diff --git a/Libraries/LibWeb/CMakeLists.txt b/Libraries/LibWeb/CMakeLists.txt index c17bf0f1371..78147441af0 100644 --- a/Libraries/LibWeb/CMakeLists.txt +++ b/Libraries/LibWeb/CMakeLists.txt @@ -70,6 +70,7 @@ set(SOURCES CSS/CSSStyleValue.cpp CSS/CSSSupportsRule.cpp CSS/CSSTransition.cpp + CSS/CascadedProperties.cpp CSS/Display.cpp CSS/EdgeRect.cpp CSS/FontFace.cpp diff --git a/Libraries/LibWeb/CSS/CascadeOrigin.h b/Libraries/LibWeb/CSS/CascadeOrigin.h new file mode 100644 index 00000000000..cea59428b7e --- /dev/null +++ b/Libraries/LibWeb/CSS/CascadeOrigin.h @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2024, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +namespace Web::CSS { + +// https://www.w3.org/TR/css-cascade/#origin +enum class CascadeOrigin : u8 { + Author, + User, + UserAgent, + Animation, + Transition, +}; + +} diff --git a/Libraries/LibWeb/CSS/CascadedProperties.cpp b/Libraries/LibWeb/CSS/CascadedProperties.cpp new file mode 100644 index 00000000000..ccf11f243aa --- /dev/null +++ b/Libraries/LibWeb/CSS/CascadedProperties.cpp @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2024, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include +#include + +namespace Web::CSS { +GC_DEFINE_ALLOCATOR(CascadedProperties); + +CascadedProperties::CascadedProperties() = default; + +CascadedProperties::~CascadedProperties() = default; + +void CascadedProperties::visit_edges(Visitor& visitor) +{ + Base::visit_edges(visitor); + for (auto const& [property_id, entries] : m_properties) { + for (auto const& entry : entries) { + visitor.visit(entry.source); + } + } +} + +void CascadedProperties::revert_property(PropertyID property_id, Important important, CascadeOrigin cascade_origin) +{ + auto it = m_properties.find(property_id); + if (it == m_properties.end()) + return; + auto& entries = it->value; + entries.remove_all_matching([&](auto& entry) { + return entry.property.property_id == property_id + && entry.property.important == important + && cascade_origin == entry.origin; + }); + if (entries.is_empty()) + m_properties.remove(it); +} + +void CascadedProperties::revert_layer_property(PropertyID property_id, Important important, Optional layer_name) +{ + auto it = m_properties.find(property_id); + if (it == m_properties.end()) + return; + auto& entries = it->value; + entries.remove_all_matching([&](auto& entry) { + return entry.property.property_id == property_id + && entry.property.important == important + && layer_name == entry.layer_name; + }); + if (entries.is_empty()) + m_properties.remove(it); +} + +void CascadedProperties::resolve_unresolved_properties(GC::Ref element, Optional pseudo_element) +{ + for (auto& [property_id, entries] : m_properties) { + for (auto& entry : entries) { + if (!entry.property.value->is_unresolved()) + continue; + entry.property.value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { element->document() }, element, pseudo_element, property_id, entry.property.value->as_unresolved()); + } + } +} + +void CascadedProperties::set_property(PropertyID property_id, NonnullRefPtr value, Important important, CascadeOrigin origin, Optional layer_name, GC::Ptr source) +{ + auto& entries = m_properties.ensure(property_id); + + for (auto& entry : entries.in_reverse()) { + if (entry.origin == origin && entry.layer_name == layer_name) { + if (entry.property.important == Important::Yes && important == Important::No) + return; + entry.property = StyleProperty { + .important = important, + .property_id = property_id, + .value = value, + }; + return; + } + } + + entries.append(Entry { + .property = StyleProperty { + .important = important, + .property_id = property_id, + .value = value, + }, + .origin = origin, + .layer_name = move(layer_name), + .source = source, + }); +} + +void CascadedProperties::set_property_from_presentational_hint(PropertyID property_id, NonnullRefPtr value) +{ + auto& entries = m_properties.ensure(property_id); + + entries.append(Entry { + .property = StyleProperty { + .important = Important::No, + .property_id = property_id, + .value = value, + }, + .origin = CascadeOrigin::Author, + .layer_name = {}, + .source = nullptr, + }); +} + +RefPtr CascadedProperties::property(PropertyID property_id) const +{ + auto it = m_properties.find(property_id); + if (it == m_properties.end()) + return nullptr; + + return it->value.last().property.value; +} + +GC::Ptr CascadedProperties::property_source(PropertyID property_id) const +{ + auto it = m_properties.find(property_id); + if (it == m_properties.end()) + return nullptr; + + return it->value.last().source; +} + +bool CascadedProperties::is_property_important(PropertyID property_id) const +{ + auto it = m_properties.find(property_id); + if (it == m_properties.end()) + return false; + + return it->value.last().property.important == Important::Yes; +} + +} diff --git a/Libraries/LibWeb/CSS/CascadedProperties.h b/Libraries/LibWeb/CSS/CascadedProperties.h new file mode 100644 index 00000000000..2876589491d --- /dev/null +++ b/Libraries/LibWeb/CSS/CascadedProperties.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2024, Andreas Kling + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace Web::CSS { + +class CascadedProperties final : public JS::Cell { + GC_CELL(CascadedProperties, JS::Cell); + GC_DECLARE_ALLOCATOR(CascadedProperties); + +public: + virtual ~CascadedProperties() override; + + [[nodiscard]] RefPtr property(PropertyID) const; + [[nodiscard]] GC::Ptr property_source(PropertyID) const; + [[nodiscard]] bool is_property_important(PropertyID) const; + + void set_property(PropertyID, NonnullRefPtr, Important, CascadeOrigin, Optional layer_name, GC::Ptr source); + void set_property_from_presentational_hint(PropertyID, NonnullRefPtr); + + void revert_property(PropertyID, Important, CascadeOrigin); + void revert_layer_property(PropertyID, Important, Optional layer_name); + + void resolve_unresolved_properties(GC::Ref, Optional); + +private: + CascadedProperties(); + + virtual void visit_edges(Visitor&) override; + + struct Entry { + StyleProperty property; + CascadeOrigin origin; + Optional layer_name; + GC::Ptr source; + }; + HashMap> m_properties; +}; + +} diff --git a/Libraries/LibWeb/CSS/StyleComputer.cpp b/Libraries/LibWeb/CSS/StyleComputer.cpp index 9b01ab7fb88..0d12418abc8 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.cpp +++ b/Libraries/LibWeb/CSS/StyleComputer.cpp @@ -887,64 +887,47 @@ void StyleComputer::for_each_property_expanding_shorthands(PropertyID property_i set_longhand_property(property_id, value); } -void StyleComputer::set_property_expanding_shorthands(StyleProperties& style, PropertyID property_id, CSSStyleValue const& value, CSSStyleDeclaration const* declaration, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important important) +void StyleComputer::set_property_expanding_shorthands( + CascadedProperties& cascaded_properties, + PropertyID property_id, + CSSStyleValue const& value, + GC::Ptr declaration, + CascadeOrigin cascade_origin, + Important important, + Optional layer_name) { - auto revert_shorthand = [&](PropertyID shorthand_id, StyleProperties const& style_for_revert) { - auto previous_value = style_for_revert.m_data->m_property_values[to_underlying(shorthand_id)]; - if (!previous_value) - previous_value = CSSKeywordValue::create(Keyword::Initial); - - style.set_property(shorthand_id, *previous_value, StyleProperties::Inherited::No, important); - if (shorthand_id == CSS::PropertyID::AnimationName) - style.set_animation_name_source(style_for_revert.animation_name_source()); - if (shorthand_id == CSS::PropertyID::TransitionProperty) - style.set_transition_property_source(style_for_revert.transition_property_source()); - }; - - for_each_property_expanding_shorthands(property_id, value, AllowUnresolved::No, [&](PropertyID shorthand_id, CSSStyleValue const& shorthand_value) { - if (shorthand_value.is_revert()) { - revert_shorthand(shorthand_id, style_for_revert); - } else if (shorthand_value.is_revert_layer()) { - revert_shorthand(shorthand_id, style_for_revert_layer); + for_each_property_expanding_shorthands(property_id, value, AllowUnresolved::No, [&](PropertyID longhand_id, CSSStyleValue const& longhand_value) { + if (longhand_value.is_revert()) { + cascaded_properties.revert_property(longhand_id, important, cascade_origin); + } else if (longhand_value.is_revert_layer()) { + cascaded_properties.revert_layer_property(longhand_id, important, layer_name); } else { - style.set_property(shorthand_id, shorthand_value, StyleProperties::Inherited::No, important); - if (shorthand_id == CSS::PropertyID::AnimationName) - style.set_animation_name_source(declaration); - if (shorthand_id == CSS::PropertyID::TransitionProperty) - style.set_transition_property_source(declaration); + cascaded_properties.set_property(longhand_id, longhand_value, important, cascade_origin, layer_name, declaration); } }); } -void StyleComputer::set_all_properties(DOM::Element& element, Optional pseudo_element, StyleProperties& style, CSSStyleValue const& value, DOM::Document& document, CSS::CSSStyleDeclaration const* declaration, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important important) const +void StyleComputer::set_all_properties( + CascadedProperties& cascaded_properties, + DOM::Element& element, + Optional pseudo_element, + CSSStyleValue const& value, + DOM::Document& document, + GC::Ptr declaration, + CascadeOrigin cascade_origin, + Important important, + Optional layer_name) const { for (auto i = to_underlying(CSS::first_longhand_property_id); i <= to_underlying(CSS::last_longhand_property_id); ++i) { auto property_id = (CSS::PropertyID)i; if (value.is_revert()) { - style.revert_property(property_id, style_for_revert); + cascaded_properties.revert_property(property_id, important, cascade_origin); continue; } if (value.is_revert_layer()) { - style.revert_property(property_id, style_for_revert_layer); - continue; - } - - if (value.is_unset()) { - if (is_inherited_property(property_id)) { - style.set_property( - property_id, - get_inherit_value(property_id, &element, pseudo_element), - StyleProperties::Inherited::Yes, - important); - } else { - style.set_property( - property_id, - property_initial_value(property_id), - StyleProperties::Inherited::No, - important); - } + cascaded_properties.revert_layer_property(property_id, important, layer_name); continue; } @@ -952,15 +935,20 @@ void StyleComputer::set_all_properties(DOM::Element& element, Optionalis_unresolved()) property_value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document }, element, pseudo_element, property_id, property_value->as_unresolved()); if (!property_value->is_unresolved()) - set_property_expanding_shorthands(style, property_id, property_value, declaration, style_for_revert, style_for_revert_layer); + set_property_expanding_shorthands(cascaded_properties, property_id, property_value, declaration, cascade_origin, important, layer_name); - style.set_property_important(property_id, important); - - set_property_expanding_shorthands(style, property_id, value, declaration, style_for_revert, style_for_revert_layer, important); + set_property_expanding_shorthands(cascaded_properties, property_id, value, declaration, cascade_origin, important, layer_name); } } -void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& element, Optional pseudo_element, Vector const& matching_rules, CascadeOrigin cascade_origin, Important important, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer) const +void StyleComputer::cascade_declarations( + CascadedProperties& cascaded_properties, + DOM::Element& element, + Optional pseudo_element, + Vector const& matching_rules, + CascadeOrigin cascade_origin, + Important important, + Optional layer_name) const { for (auto const& match : matching_rules) { for (auto const& property : match.declaration().properties()) { @@ -968,7 +956,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e continue; if (property.property_id == CSS::PropertyID::All) { - set_all_properties(element, pseudo_element, style, property.value, m_document, &match.declaration(), style_for_revert, style_for_revert_layer, important); + set_all_properties(cascaded_properties, element, pseudo_element, property.value, m_document, &match.declaration(), cascade_origin, important, layer_name); continue; } @@ -976,7 +964,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e if (property.value->is_unresolved()) property_value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document() }, element, pseudo_element, property.property_id, property.value->as_unresolved()); if (!property_value->is_unresolved()) - set_property_expanding_shorthands(style, property.property_id, property_value, &match.declaration(), style_for_revert, style_for_revert_layer, important); + set_property_expanding_shorthands(cascaded_properties, property.property_id, property_value, &match.declaration(), cascade_origin, important, layer_name); } } @@ -987,7 +975,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e continue; if (property.property_id == CSS::PropertyID::All) { - set_all_properties(element, pseudo_element, style, property.value, m_document, inline_style, style_for_revert, style_for_revert_layer, important); + set_all_properties(cascaded_properties, element, pseudo_element, property.value, m_document, inline_style, cascade_origin, important, layer_name); continue; } @@ -995,7 +983,7 @@ void StyleComputer::cascade_declarations(StyleProperties& style, DOM::Element& e if (property.value->is_unresolved()) property_value = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document() }, element, pseudo_element, property.property_id, property.value->as_unresolved()); if (!property_value->is_unresolved()) - set_property_expanding_shorthands(style, property.property_id, property_value, inline_style, style_for_revert, style_for_revert_layer, important); + set_property_expanding_shorthands(cascaded_properties, property.property_id, property_value, inline_style, cascade_origin, important, layer_name); } } } @@ -1087,9 +1075,11 @@ void StyleComputer::collect_animation_into(DOM::Element& element, Optional RefPtr { if (refresh == AnimationRefresh::Yes) return {}; - return style_properties.maybe_null_property(it.key); + return style_properties.property(it.key); }, [&](RefPtr value) -> RefPtr { + if (value->is_revert() || value->is_revert_layer()) + return style_properties.property(it.key); if (value->is_unresolved()) return Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { element.document() }, element, pseudo_element, it.key, value->as_unresolved()); return value; @@ -1133,12 +1123,12 @@ void StyleComputer::collect_animation_into(DOM::Element& element, Optional(*animation.effect()); Optional duration; - if (auto duration_value = style.maybe_null_property(PropertyID::AnimationDuration); duration_value) { + if (auto duration_value = cascaded_properties.property(PropertyID::AnimationDuration); duration_value) { if (duration_value->is_time()) { duration = duration_value->as_time().time(); } else if (duration_value->is_keyword() && duration_value->as_keyword().keyword() == Keyword::Auto) { @@ -1148,11 +1138,11 @@ static void apply_animation_properties(DOM::Document& document, StyleProperties& } CSS::Time delay { 0, CSS::Time::Type::S }; - if (auto delay_value = style.maybe_null_property(PropertyID::AnimationDelay); delay_value && delay_value->is_time()) + if (auto delay_value = cascaded_properties.property(PropertyID::AnimationDelay); delay_value && delay_value->is_time()) delay = delay_value->as_time().time(); double iteration_count = 1.0; - if (auto iteration_count_value = style.maybe_null_property(PropertyID::AnimationIterationCount); iteration_count_value) { + if (auto iteration_count_value = cascaded_properties.property(PropertyID::AnimationIterationCount); iteration_count_value) { if (iteration_count_value->is_keyword() && iteration_count_value->to_keyword() == Keyword::Infinite) iteration_count = HUGE_VAL; else if (iteration_count_value->is_number()) @@ -1160,25 +1150,25 @@ static void apply_animation_properties(DOM::Document& document, StyleProperties& } CSS::AnimationFillMode fill_mode { CSS::AnimationFillMode::None }; - if (auto fill_mode_property = style.maybe_null_property(PropertyID::AnimationFillMode); fill_mode_property && fill_mode_property->is_keyword()) { + if (auto fill_mode_property = cascaded_properties.property(PropertyID::AnimationFillMode); fill_mode_property && fill_mode_property->is_keyword()) { if (auto fill_mode_value = keyword_to_animation_fill_mode(fill_mode_property->to_keyword()); fill_mode_value.has_value()) fill_mode = *fill_mode_value; } CSS::AnimationDirection direction { CSS::AnimationDirection::Normal }; - if (auto direction_property = style.maybe_null_property(PropertyID::AnimationDirection); direction_property && direction_property->is_keyword()) { + if (auto direction_property = cascaded_properties.property(PropertyID::AnimationDirection); direction_property && direction_property->is_keyword()) { if (auto direction_value = keyword_to_animation_direction(direction_property->to_keyword()); direction_value.has_value()) direction = *direction_value; } CSS::AnimationPlayState play_state { CSS::AnimationPlayState::Running }; - if (auto play_state_property = style.maybe_null_property(PropertyID::AnimationPlayState); play_state_property && play_state_property->is_keyword()) { + if (auto play_state_property = cascaded_properties.property(PropertyID::AnimationPlayState); play_state_property && play_state_property->is_keyword()) { if (auto play_state_value = keyword_to_animation_play_state(play_state_property->to_keyword()); play_state_value.has_value()) play_state = *play_state_value; } CSS::EasingStyleValue::Function timing_function { CSS::EasingStyleValue::CubicBezier::ease() }; - if (auto timing_property = style.maybe_null_property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing()) + if (auto timing_property = cascaded_properties.property(PropertyID::AnimationTimingFunction); timing_property && timing_property->is_easing()) timing_function = timing_property->as_easing().function(); auto iteration_duration = duration.has_value() @@ -1204,7 +1194,7 @@ static void apply_animation_properties(DOM::Document& document, StyleProperties& } } -static void apply_dimension_attribute(StyleProperties& style, DOM::Element const& element, FlyString const& attribute_name, CSS::PropertyID property_id) +static void apply_dimension_attribute(CascadedProperties& cascaded_properties, DOM::Element const& element, FlyString const& attribute_name, CSS::PropertyID property_id) { auto attribute = element.attribute(attribute_name); if (!attribute.has_value()) @@ -1214,7 +1204,7 @@ static void apply_dimension_attribute(StyleProperties& style, DOM::Element const if (!parsed_value) return; - style.set_property(property_id, parsed_value.release_nonnull()); + cascaded_properties.set_property_from_presentational_hint(property_id, parsed_value.release_nonnull()); } static void compute_transitioned_properties(StyleProperties const& style, DOM::Element& element, Optional pseudo_element) @@ -1495,8 +1485,10 @@ void StyleComputer::start_needed_transitions(StyleProperties const& previous_sty // https://www.w3.org/TR/css-cascade/#cascading // https://drafts.csswg.org/css-cascade-5/#layering -void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element& element, Optional pseudo_element, bool& did_match_any_pseudo_element_rules, ComputeStyleMode mode) const +GC::Ref StyleComputer::compute_cascaded_values(DOM::Element& element, Optional pseudo_element, bool& did_match_any_pseudo_element_rules, ComputeStyleMode mode) const { + auto cascaded_properties = m_document->heap().allocate(); + // First, we collect all the CSS rules whose selectors match `element`: MatchingRuleSet matching_rule_set; matching_rule_set.user_agent_rules = collect_matching_rules(element, CascadeOrigin::UserAgent, pseudo_element); @@ -1518,7 +1510,7 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element VERIFY(pseudo_element.has_value()); if (matching_rule_set.author_rules.is_empty() && matching_rule_set.user_rules.is_empty() && matching_rule_set.user_agent_rules.is_empty()) { did_match_any_pseudo_element_rules = false; - return; + return cascaded_properties; } did_match_any_pseudo_element_rules = true; } @@ -1535,14 +1527,10 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element // Then we apply the declarations from the matched rules in cascade order: // Normal user agent declarations - auto previous_origin_style = style; - auto previous_layer_style = style; - cascade_declarations(style, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::No, previous_origin_style, previous_layer_style); + cascade_declarations(*cascaded_properties, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::No, {}); // Normal user declarations - previous_origin_style = style; - previous_layer_style = style; - cascade_declarations(style, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::No, previous_origin_style, previous_layer_style); + cascade_declarations(*cascaded_properties, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::No, {}); // Author presentational hints // The spec calls this a special "Author presentational hint origin": @@ -1550,119 +1538,40 @@ void StyleComputer::compute_cascaded_values(StyleProperties& style, DOM::Element // however for the purpose of the revert keyword (but not for the revert-layer keyword) it is considered // part of the author origin." // https://drafts.csswg.org/css-cascade-5/#author-presentational-hint-origin - previous_origin_style = style; if (!pseudo_element.has_value()) { - element.apply_presentational_hints(style); - + element.apply_presentational_hints(cascaded_properties); if (element.supports_dimension_attributes()) { - apply_dimension_attribute(style, element, HTML::AttributeNames::width, CSS::PropertyID::Width); - apply_dimension_attribute(style, element, HTML::AttributeNames::height, CSS::PropertyID::Height); + apply_dimension_attribute(cascaded_properties, element, HTML::AttributeNames::width, CSS::PropertyID::Width); + apply_dimension_attribute(cascaded_properties, element, HTML::AttributeNames::height, CSS::PropertyID::Height); } // SVG presentation attributes are parsed as CSS values, so we need to handle potential custom properties here. if (element.is_svg_element()) { - // FIXME: This is not very efficient, we should only resolve the custom properties that are actually used. - for (auto i = to_underlying(CSS::first_property_id); i <= to_underlying(CSS::last_property_id); ++i) { - auto property_id = (CSS::PropertyID)i; - auto& property = style.m_data->m_property_values[i]; - if (property && property->is_unresolved()) - property = Parser::Parser::resolve_unresolved_style_value(Parser::ParsingContext { document() }, element, pseudo_element, property_id, property->as_unresolved()); - } + cascaded_properties->resolve_unresolved_properties(element, pseudo_element); } } // Normal author declarations, ordered by @layer, with un-@layer-ed rules last for (auto const& layer : matching_rule_set.author_rules) { - previous_layer_style = style; - cascade_declarations(style, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::No, previous_origin_style, previous_layer_style); - } - - // Animation declarations [css-animations-2] - auto animation_name = [&]() -> Optional { - auto const* animation_name = style.maybe_null_property(PropertyID::AnimationName); - if (!animation_name) - return OptionalNone {}; - if (animation_name->is_string()) - return animation_name->as_string().string_value().to_string(); - return animation_name->to_string(CSSStyleValue::SerializationMode::Normal); - }(); - - if (animation_name.has_value()) { - if (auto source_declaration = style.animation_name_source()) { - auto& realm = element.realm(); - - if (source_declaration != element.cached_animation_name_source(pseudo_element)) { - // This animation name is new, so we need to create a new animation for it. - if (auto existing_animation = element.cached_animation_name_animation(pseudo_element)) - existing_animation->cancel(Animations::Animation::ShouldInvalidate::No); - element.set_cached_animation_name_source(source_declaration, pseudo_element); - - auto effect = Animations::KeyframeEffect::create(realm); - auto animation = CSSAnimation::create(realm); - animation->set_id(animation_name.release_value()); - animation->set_timeline(m_document->timeline()); - animation->set_owning_element(element); - animation->set_effect(effect); - apply_animation_properties(m_document, style, animation); - if (pseudo_element.has_value()) - effect->set_pseudo_element(Selector::PseudoElement { pseudo_element.value() }); - - auto const& rule_cache = rule_cache_for_cascade_origin(CascadeOrigin::Author); - if (auto keyframe_set = rule_cache.rules_by_animation_keyframes.get(animation->id()); keyframe_set.has_value()) - effect->set_key_frame_set(keyframe_set.value()); - - effect->set_target(&element); - element.set_cached_animation_name_animation(animation, pseudo_element); - - HTML::TemporaryExecutionContext context(realm); - animation->play().release_value_but_fixme_should_propagate_errors(); - } else { - // The animation hasn't changed, but some properties of the animation may have - apply_animation_properties(m_document, style, *element.cached_animation_name_animation(pseudo_element)); - } - } - } else { - // If the element had an existing animation, cancel it - if (auto existing_animation = element.cached_animation_name_animation(pseudo_element)) { - existing_animation->cancel(Animations::Animation::ShouldInvalidate::No); - element.set_cached_animation_name_animation({}, pseudo_element); - element.set_cached_animation_name_source({}, pseudo_element); - } - } - - auto animations = element.get_animations_internal(Animations::GetAnimationsOptions { .subtree = false }); - if (animations.is_exception()) { - dbgln("Error getting animations for element {}", element.debug_description()); - } else { - for (auto& animation : animations.value()) { - if (auto effect = animation->effect(); effect && effect->is_keyframe_effect()) { - auto& keyframe_effect = *static_cast(effect.ptr()); - if (keyframe_effect.pseudo_element_type() == pseudo_element) - collect_animation_into(element, pseudo_element, keyframe_effect, style); - } - } + cascade_declarations(cascaded_properties, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::No, layer.qualified_layer_name); } // Important author declarations, with un-@layer-ed rules first, followed by each @layer in reverse order. - previous_origin_style = style; for (auto const& layer : matching_rule_set.author_rules.in_reverse()) { - previous_layer_style = style; - cascade_declarations(style, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::Yes, previous_origin_style, previous_layer_style); + cascade_declarations(cascaded_properties, element, pseudo_element, layer.rules, CascadeOrigin::Author, Important::Yes, {}); } // Important user declarations - previous_origin_style = style; - previous_layer_style = style; - cascade_declarations(style, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::Yes, previous_origin_style, previous_layer_style); + cascade_declarations(cascaded_properties, element, pseudo_element, matching_rule_set.user_rules, CascadeOrigin::User, Important::Yes, {}); // Important user agent declarations - previous_origin_style = style; - previous_layer_style = style; - cascade_declarations(style, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::Yes, previous_origin_style, previous_layer_style); + cascade_declarations(cascaded_properties, element, pseudo_element, matching_rule_set.user_agent_rules, CascadeOrigin::UserAgent, Important::Yes, {}); // Transition declarations [css-transitions-1] // Note that we have to do these after finishing computing the style, // so they're not done here, but as the final step in compute_style_impl() + + return cascaded_properties; } DOM::Element const* element_to_inherit_style_from(DOM::Element const* element, Optional pseudo_element) @@ -2377,10 +2286,11 @@ Optional StyleComputer::compute_style_impl(DOM::Element& elemen ScopeGuard guard { [&element]() { element.set_needs_style_update(false); } }; - StyleProperties style = {}; // 1. Perform the cascade. This produces the "specified style" bool did_match_any_pseudo_element_rules = false; - compute_cascaded_values(style, element, pseudo_element, did_match_any_pseudo_element_rules, mode); + auto cascaded_properties = compute_cascaded_values(element, pseudo_element, did_match_any_pseudo_element_rules, mode); + + element.set_cascaded_properties(pseudo_element, cascaded_properties); if (mode == ComputeStyleMode::CreatePseudoElementStyleIfNeeded) { // NOTE: If we're computing style for a pseudo-element, we look for a number of reasons to bail early. @@ -2393,7 +2303,7 @@ Optional StyleComputer::compute_style_impl(DOM::Element& elemen // - content: none // - content: normal (for ::before and ::after) bool content_is_normal = false; - if (auto content_value = style.maybe_null_property(CSS::PropertyID::Content)) { + if (auto content_value = cascaded_properties->property(CSS::PropertyID::Content)) { if (content_value->is_keyword()) { auto content = content_value->as_keyword().keyword(); if (content == CSS::Keyword::None) @@ -2411,35 +2321,140 @@ Optional StyleComputer::compute_style_impl(DOM::Element& elemen } } + return compute_properties(element, pseudo_element, cascaded_properties); +} + +StyleProperties StyleComputer::compute_properties(DOM::Element& element, Optional pseudo_element, CascadedProperties& cascaded_properties) const +{ + StyleProperties computed_style; + + for (auto i = to_underlying(first_longhand_property_id); i <= to_underlying(last_longhand_property_id); ++i) { + auto property_id = static_cast(i); + auto value = cascaded_properties.property(property_id); + 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); + } else { + value = property_initial_value(property_id); + } + } + + if (!value || value->is_initial()) + value = property_initial_value(property_id); + + if (value->is_unset()) { + if (is_inherited_property(property_id)) + value = CSSKeywordValue::create(Keyword::Inherit); + else + value = CSSKeywordValue::create(Keyword::Initial); + } + + 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)); + } + if (property_id == PropertyID::TransitionProperty) { + computed_style.set_transition_property_source(cascaded_properties.property_source(property_id)); + } + } + + // Animation declarations [css-animations-2] + auto animation_name = [&]() -> Optional { + auto const animation_name = computed_style.maybe_null_property(PropertyID::AnimationName); + if (!animation_name) + return OptionalNone {}; + if (animation_name->is_string()) + return animation_name->as_string().string_value().to_string(); + return animation_name->to_string(CSSStyleValue::SerializationMode::Normal); + }(); + + if (animation_name.has_value()) { + if (auto source_declaration = computed_style.animation_name_source()) { + auto& realm = element.realm(); + + if (source_declaration != element.cached_animation_name_source(pseudo_element)) { + // This animation name is new, so we need to create a new animation for it. + if (auto existing_animation = element.cached_animation_name_animation(pseudo_element)) + existing_animation->cancel(Animations::Animation::ShouldInvalidate::No); + element.set_cached_animation_name_source(source_declaration, pseudo_element); + + auto effect = Animations::KeyframeEffect::create(realm); + auto animation = CSSAnimation::create(realm); + animation->set_id(animation_name.release_value()); + animation->set_timeline(m_document->timeline()); + animation->set_owning_element(element); + animation->set_effect(effect); + apply_animation_properties(m_document, cascaded_properties, animation); + if (pseudo_element.has_value()) + effect->set_pseudo_element(Selector::PseudoElement { pseudo_element.value() }); + + auto const& rule_cache = rule_cache_for_cascade_origin(CascadeOrigin::Author); + if (auto keyframe_set = rule_cache.rules_by_animation_keyframes.get(animation->id()); keyframe_set.has_value()) + effect->set_key_frame_set(keyframe_set.value()); + + effect->set_target(&element); + element.set_cached_animation_name_animation(animation, pseudo_element); + + HTML::TemporaryExecutionContext context(realm); + animation->play().release_value_but_fixme_should_propagate_errors(); + } else { + // The animation hasn't changed, but some properties of the animation may have + apply_animation_properties(m_document, cascaded_properties, *element.cached_animation_name_animation(pseudo_element)); + } + } + } else { + // If the element had an existing animation, cancel it + if (auto existing_animation = element.cached_animation_name_animation(pseudo_element)) { + existing_animation->cancel(Animations::Animation::ShouldInvalidate::No); + element.set_cached_animation_name_animation({}, pseudo_element); + element.set_cached_animation_name_source({}, pseudo_element); + } + } + + auto animations = element.get_animations_internal(Animations::GetAnimationsOptions { .subtree = false }); + if (animations.is_exception()) { + dbgln("Error getting animations for element {}", element.debug_description()); + } else { + for (auto& animation : animations.value()) { + if (auto effect = animation->effect(); effect && effect->is_keyframe_effect()) { + auto& keyframe_effect = *static_cast(effect.ptr()); + if (keyframe_effect.pseudo_element_type() == pseudo_element) + collect_animation_into(element, pseudo_element, keyframe_effect, computed_style); + } + } + } + // 2. Compute the math-depth property, since that might affect the font-size - compute_math_depth(style, &element, pseudo_element); + compute_math_depth(computed_style, &element, pseudo_element); // 3. Compute the font, since that may be needed for font-relative CSS units - compute_font(style, &element, pseudo_element); + compute_font(computed_style, &element, pseudo_element); // 4. Absolutize values, turning font/viewport relative lengths into absolute lengths - absolutize_values(style); + absolutize_values(computed_style); // 5. Default the values, applying inheritance and 'initial' as needed - compute_defaulted_values(style, &element, pseudo_element); + compute_defaulted_values(computed_style, &element, pseudo_element); // 6. Run automatic box type transformations - transform_box_type_if_needed(style, element, pseudo_element); + transform_box_type_if_needed(computed_style, element, pseudo_element); // 7. Resolve effective overflow values - resolve_effective_overflow_values(style); + resolve_effective_overflow_values(computed_style); // 8. Let the element adjust computed style - element.adjust_computed_style(style); + element.adjust_computed_style(computed_style); // 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(style, element, pseudo_element); + compute_transitioned_properties(computed_style, element, pseudo_element); if (auto previous_style = element.computed_css_values(); previous_style.has_value()) { - start_needed_transitions(*previous_style, style, element, pseudo_element); + start_needed_transitions(*previous_style, computed_style, element, pseudo_element); } - return style; + return computed_style; } void StyleComputer::build_rule_cache_if_needed() const diff --git a/Libraries/LibWeb/CSS/StyleComputer.h b/Libraries/LibWeb/CSS/StyleComputer.h index 079d231cf47..f0732320671 100644 --- a/Libraries/LibWeb/CSS/StyleComputer.h +++ b/Libraries/LibWeb/CSS/StyleComputer.h @@ -15,6 +15,8 @@ #include #include #include +#include +#include #include #include #include @@ -71,15 +73,6 @@ private: CounterType m_buckets[bucket_count]; }; -// https://www.w3.org/TR/css-cascade/#origin -enum class CascadeOrigin : u8 { - Author, - User, - UserAgent, - Animation, - Transition, -}; - struct MatchingRule { GC::Ptr shadow_root; GC::Ptr rule; // Either CSSStyleRule or CSSNestedDeclarations @@ -126,7 +119,14 @@ public: No, }; static void for_each_property_expanding_shorthands(PropertyID, CSSStyleValue const&, AllowUnresolved, Function const& set_longhand_property); - static void set_property_expanding_shorthands(StyleProperties&, PropertyID, CSSStyleValue const&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important = Important::No); + static void set_property_expanding_shorthands( + CascadedProperties&, + PropertyID, + CSSStyleValue const&, + GC::Ptr, + CascadeOrigin, + Important, + Optional layer_name); static NonnullRefPtr get_inherit_value(CSS::PropertyID, DOM::Element const*, Optional = {}); static Optional user_agent_style_sheet_source(StringView name); @@ -167,12 +167,14 @@ public: No, Yes, }; - void collect_animation_into(DOM::Element&, Optional, GC::Ref animation, StyleProperties& style_properties, AnimationRefresh = AnimationRefresh::No) const; + void collect_animation_into(DOM::Element&, Optional, GC::Ref animation, StyleProperties&, AnimationRefresh = AnimationRefresh::No) const; [[nodiscard]] bool has_has_selectors() const { return m_has_has_selectors; } size_t number_of_css_font_faces_with_loading_in_progress() const; + [[nodiscard]] StyleProperties compute_properties(DOM::Element&, Optional, CascadedProperties&) const; + private: enum class ComputeStyleMode { Normal, @@ -184,7 +186,7 @@ private: [[nodiscard]] bool should_reject_with_ancestor_filter(Selector const&) const; Optional compute_style_impl(DOM::Element&, Optional, ComputeStyleMode) const; - void compute_cascaded_values(StyleProperties&, DOM::Element&, Optional, bool& did_match_any_pseudo_element_rules, ComputeStyleMode) const; + [[nodiscard]] GC::Ref compute_cascaded_values(DOM::Element&, Optional, bool& did_match_any_pseudo_element_rules, ComputeStyleMode) const; static RefPtr find_matching_font_weight_ascending(Vector const& candidates, int target_weight, float font_size_in_pt, bool inclusive); static RefPtr find_matching_font_weight_descending(Vector const& candidates, int target_weight, float font_size_in_pt, bool inclusive); RefPtr font_matching_algorithm(FlyString const& family_name, int weight, int slope, float font_size_in_pt) const; @@ -198,7 +200,16 @@ private: void compute_defaulted_property_value(StyleProperties&, DOM::Element const*, CSS::PropertyID, Optional) const; - void set_all_properties(DOM::Element&, Optional, StyleProperties&, CSSStyleValue const&, DOM::Document&, CSS::CSSStyleDeclaration const*, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer, Important = Important::No) const; + void set_all_properties( + CascadedProperties&, + DOM::Element&, + Optional, + CSSStyleValue const&, + DOM::Document&, + GC::Ptr, + CascadeOrigin, + Important, + Optional layer_name) const; template void for_each_stylesheet(CascadeOrigin, Callback) const; @@ -221,7 +232,14 @@ private: Vector author_rules; }; - void cascade_declarations(StyleProperties&, DOM::Element&, Optional, Vector const&, CascadeOrigin, Important, StyleProperties const& style_for_revert, StyleProperties const& style_for_revert_layer) const; + void cascade_declarations( + CascadedProperties&, + DOM::Element&, + Optional, + Vector const&, + CascadeOrigin, + Important, + Optional layer_name) const; void build_rule_cache(); void build_rule_cache_if_needed() const; diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 4c79472bba3..3ac11c113e7 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -101,8 +101,10 @@ void Element::visit_edges(Cell::Visitor& visitor) visitor.visit(m_class_list); visitor.visit(m_shadow_root); visitor.visit(m_custom_element_definition); + visitor.visit(m_cascaded_properties); if (m_pseudo_element_data) { for (auto& pseudo_element : *m_pseudo_element_data) { + visitor.visit(pseudo_element.cascaded_properties); visitor.visit(pseudo_element.layout_node); } } @@ -2273,6 +2275,28 @@ size_t Element::attribute_list_size() const return m_attributes->length(); } +GC::Ptr Element::cascaded_properties(Optional pseudo_element) const +{ + if (pseudo_element.has_value()) { + auto pseudo_element_data = get_pseudo_element(pseudo_element.value()); + if (pseudo_element_data.has_value()) + return pseudo_element_data->cascaded_properties; + return nullptr; + } + return m_cascaded_properties; +} + +void Element::set_cascaded_properties(Optional pseudo_element, GC::Ptr cascaded_properties) +{ + if (pseudo_element.has_value()) { + if (pseudo_element.value() >= CSS::Selector::PseudoElement::Type::KnownPseudoElementCount) + return; + ensure_pseudo_element(pseudo_element.value()).cascaded_properties = cascaded_properties; + } else { + m_cascaded_properties = cascaded_properties; + } +} + void Element::set_computed_css_values(Optional style) { m_computed_css_values = move(style); diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index 9faa23e7e63..eec424962f0 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -172,7 +173,7 @@ public: // https://html.spec.whatwg.org/multipage/embedded-content-other.html#dimension-attributes virtual bool supports_dimension_attributes() const { return false; } - virtual void apply_presentational_hints(CSS::StyleProperties&) const { } + virtual void apply_presentational_hints(GC::Ref) const { } void run_attribute_change_steps(FlyString const& local_name, Optional const& old_value, Optional const& value, Optional const& namespace_); @@ -189,6 +190,9 @@ public: void set_computed_css_values(Optional); CSS::StyleProperties resolved_css_values(Optional = {}); + [[nodiscard]] GC::Ptr cascaded_properties(Optional) const; + void set_cascaded_properties(Optional, GC::Ptr); + void set_pseudo_element_computed_css_values(CSS::Selector::PseudoElement::Type, Optional); Optional pseudo_element_computed_css_values(CSS::Selector::PseudoElement::Type); @@ -410,11 +414,14 @@ private: GC::Ptr m_class_list; GC::Ptr m_shadow_root; + GC::Ptr m_cascaded_properties; + Optional m_computed_css_values; HashMap m_custom_properties; struct PseudoElement { GC::Ptr layout_node; + GC::Ptr cascaded_properties; Optional computed_css_values; HashMap custom_properties; }; diff --git a/Libraries/LibWeb/Dump.cpp b/Libraries/LibWeb/Dump.cpp index 36f3dd4b4ba..a333691dddd 100644 --- a/Libraries/LibWeb/Dump.cpp +++ b/Libraries/LibWeb/Dump.cpp @@ -137,14 +137,14 @@ void dump_tree(StringBuilder& builder, DOM::Node const& node) --indent; } -void dump_tree(Layout::Node const& layout_node, bool show_box_model, bool show_specified_style) +void dump_tree(Layout::Node const& layout_node, bool show_box_model, bool show_cascaded_properties) { StringBuilder builder; - dump_tree(builder, layout_node, show_box_model, show_specified_style, true); + dump_tree(builder, layout_node, show_box_model, show_cascaded_properties, true); dbgln("{}", builder.string_view()); } -void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool show_box_model, bool show_specified_style, bool interactive) +void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool show_box_model, bool show_cascaded_properties, bool interactive) { static size_t indent = 0; for (size_t i = 0; i < indent; ++i) @@ -329,7 +329,7 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho builder.appendff(" (url: {})", document->url()); if (auto const* nested_layout_root = document->layout_node()) { ++indent; - dump_tree(builder, *nested_layout_root, show_box_model, show_specified_style, interactive); + dump_tree(builder, *nested_layout_root, show_box_model, show_cascaded_properties, interactive); --indent; } } @@ -348,7 +348,7 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho builder.append(" "sv); builder.append("(SVG-as-image isolated context)\n"sv); - dump_tree(builder, *svg_data.svg_document().layout_node(), show_box_model, show_specified_style, interactive); + dump_tree(builder, *svg_data.svg_document().layout_node(), show_box_model, show_cascaded_properties, interactive); --indent; } } @@ -397,7 +397,7 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho } } - if (show_specified_style && layout_node.dom_node() && layout_node.dom_node()->is_element() && verify_cast(layout_node.dom_node())->computed_css_values().has_value()) { + if (show_cascaded_properties && layout_node.dom_node() && layout_node.dom_node()->is_element() && verify_cast(layout_node.dom_node())->computed_css_values().has_value()) { struct NameAndValue { FlyString name; String value; @@ -417,7 +417,7 @@ void dump_tree(StringBuilder& builder, Layout::Node const& layout_node, bool sho ++indent; layout_node.for_each_child([&](auto& child) { - dump_tree(builder, child, show_box_model, show_specified_style, interactive); + dump_tree(builder, child, show_box_model, show_cascaded_properties, interactive); return IterationDecision::Continue; }); --indent; diff --git a/Libraries/LibWeb/Dump.h b/Libraries/LibWeb/Dump.h index 99c6c8ad022..acb6d3ebae2 100644 --- a/Libraries/LibWeb/Dump.h +++ b/Libraries/LibWeb/Dump.h @@ -16,8 +16,8 @@ namespace Web { void dump_tree(HTML::TraversableNavigable&); void dump_tree(StringBuilder&, DOM::Node const&); void dump_tree(DOM::Node const&); -void dump_tree(StringBuilder&, Layout::Node const&, bool show_box_model = false, bool show_specified_style = false, bool colorize = false); -void dump_tree(Layout::Node const&, bool show_box_model = true, bool show_specified_style = false); +void dump_tree(StringBuilder&, Layout::Node const&, bool show_box_model = false, bool show_cascaded_properties = false, bool colorize = false); +void dump_tree(Layout::Node const&, bool show_box_model = true, bool show_cascaded_properties = false); void dump_tree(StringBuilder&, Painting::Paintable const&, bool colorize = false, int indent = 0); void dump_tree(Painting::Paintable const&); void dump_sheet(StringBuilder&, CSS::StyleSheet const&); diff --git a/Libraries/LibWeb/HTML/HTMLBodyElement.cpp b/Libraries/LibWeb/HTML/HTMLBodyElement.cpp index d4d75cff7d0..8c5d936bfb0 100644 --- a/Libraries/LibWeb/HTML/HTMLBodyElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLBodyElement.cpp @@ -41,22 +41,22 @@ void HTMLBodyElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLBodyElement); } -void HTMLBodyElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLBodyElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name.equals_ignoring_ascii_case("bgcolor"sv)) { // https://html.spec.whatwg.org/multipage/rendering.html#the-page:rules-for-parsing-a-legacy-colour-value auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); } else if (name.equals_ignoring_ascii_case("text"sv)) { // https://html.spec.whatwg.org/multipage/rendering.html#the-page:rules-for-parsing-a-legacy-colour-value-2 auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::Color, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Color, CSS::CSSColorValue::create_from_color(color.value())); } else if (name.equals_ignoring_ascii_case("background"sv)) { VERIFY(m_background_style_value); - style.set_property(CSS::PropertyID::BackgroundImage, *m_background_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, *m_background_style_value); } }); @@ -84,7 +84,7 @@ void HTMLBodyElement::apply_presentational_hints(CSS::StyleProperties& style) co if (!value.has_value()) return; if (auto parsed_value = parse_non_negative_integer(value.value()); parsed_value.has_value()) - style.set_property(property_id, CSS::LengthStyleValue::create(CSS::Length::make_px(*parsed_value))); + cascaded_properties->set_property_from_presentational_hint(property_id, CSS::LengthStyleValue::create(CSS::Length::make_px(*parsed_value))); }; apply_margin_value(CSS::PropertyID::MarginTop, margin_top_value); diff --git a/Libraries/LibWeb/HTML/HTMLBodyElement.h b/Libraries/LibWeb/HTML/HTMLBodyElement.h index d28356cec47..3d39a6c5663 100644 --- a/Libraries/LibWeb/HTML/HTMLBodyElement.h +++ b/Libraries/LibWeb/HTML/HTMLBodyElement.h @@ -22,7 +22,7 @@ public: virtual ~HTMLBodyElement() override; virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; // https://www.w3.org/TR/html-aria/#el-body virtual Optional default_role() const override { return ARIA::Role::generic; } diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp b/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp index 0e9fc291561..e03f2a6acac 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.cpp @@ -65,7 +65,7 @@ void HTMLCanvasElement::visit_edges(Cell::Visitor& visitor) }); } -void HTMLCanvasElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLCanvasElement::apply_presentational_hints(GC::Ref cascaded_properties) const { // https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images // The width and height attributes map to the aspect-ratio property on canvas elements. @@ -79,7 +79,7 @@ void HTMLCanvasElement::apply_presentational_hints(CSS::StyleProperties& style) if (w.has_value() && h.has_value()) // then the user agent is expected to use the parsed integers as a presentational hint for the 'aspect-ratio' property of the form auto w / h. - style.set_property(CSS::PropertyID::AspectRatio, + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::AspectRatio, CSS::StyleValueList::create(CSS::StyleValueVector { CSS::CSSKeywordValue::create(CSS::Keyword::Auto), CSS::RatioStyleValue::create(CSS::Ratio { static_cast(w.value()), static_cast(h.value()) }) }, diff --git a/Libraries/LibWeb/HTML/HTMLCanvasElement.h b/Libraries/LibWeb/HTML/HTMLCanvasElement.h index 2da8e73f71a..5a0bd6d7b30 100644 --- a/Libraries/LibWeb/HTML/HTMLCanvasElement.h +++ b/Libraries/LibWeb/HTML/HTMLCanvasElement.h @@ -52,7 +52,7 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual GC::Ptr create_layout_node(CSS::StyleProperties) override; virtual void adjust_computed_style(CSS::StyleProperties&) override; diff --git a/Libraries/LibWeb/HTML/HTMLDivElement.cpp b/Libraries/LibWeb/HTML/HTMLDivElement.cpp index 5f0547aa812..71035e89c8b 100644 --- a/Libraries/LibWeb/HTML/HTMLDivElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLDivElement.cpp @@ -22,18 +22,18 @@ HTMLDivElement::HTMLDivElement(DOM::Document& document, DOM::QualifiedName quali HTMLDivElement::~HTMLDivElement() = default; // https://html.spec.whatwg.org/multipage/rendering.html#flow-content-3 -void HTMLDivElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLDivElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name.equals_ignoring_ascii_case("align"sv)) { if (value.equals_ignoring_ascii_case("left"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebLeft)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebLeft)); else if (value.equals_ignoring_ascii_case("right"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebRight)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebRight)); else if (value.equals_ignoring_ascii_case("center"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebCenter)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebCenter)); else if (value.equals_ignoring_ascii_case("justify"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Justify)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Justify)); } }); } diff --git a/Libraries/LibWeb/HTML/HTMLDivElement.h b/Libraries/LibWeb/HTML/HTMLDivElement.h index 98199f606a8..4e6b6f269e3 100644 --- a/Libraries/LibWeb/HTML/HTMLDivElement.h +++ b/Libraries/LibWeb/HTML/HTMLDivElement.h @@ -26,7 +26,7 @@ protected: private: virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; }; } diff --git a/Libraries/LibWeb/HTML/HTMLEmbedElement.cpp b/Libraries/LibWeb/HTML/HTMLEmbedElement.cpp index 2436548e392..b3f9a349bb3 100644 --- a/Libraries/LibWeb/HTML/HTMLEmbedElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLEmbedElement.cpp @@ -29,32 +29,32 @@ void HTMLEmbedElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLEmbedElement); } -void HTMLEmbedElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLEmbedElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::align) { if (value.equals_ignoring_ascii_case("center"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); else if (value.equals_ignoring_ascii_case("middle"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Middle)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Middle)); } else if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_dimension_value(value)) - style.set_property(CSS::PropertyID::Height, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, *parsed_value); } // https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images:maps-to-the-dimension-property else if (name == HTML::AttributeNames::hspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginLeft, *parsed_value); - style.set_property(CSS::PropertyID::MarginRight, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginLeft, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginRight, *parsed_value); } } else if (name == HTML::AttributeNames::vspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginTop, *parsed_value); - style.set_property(CSS::PropertyID::MarginBottom, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginTop, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginBottom, *parsed_value); } } else if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Width, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, *parsed_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLEmbedElement.h b/Libraries/LibWeb/HTML/HTMLEmbedElement.h index d3cea6ca73a..f9305640803 100644 --- a/Libraries/LibWeb/HTML/HTMLEmbedElement.h +++ b/Libraries/LibWeb/HTML/HTMLEmbedElement.h @@ -22,7 +22,7 @@ private: virtual bool is_html_embed_element() const override { return true; } virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual void adjust_computed_style(CSS::StyleProperties&) override; }; diff --git a/Libraries/LibWeb/HTML/HTMLFontElement.cpp b/Libraries/LibWeb/HTML/HTMLFontElement.cpp index a8493dc8994..cd8078f3a53 100644 --- a/Libraries/LibWeb/HTML/HTMLFontElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLFontElement.cpp @@ -112,21 +112,21 @@ void HTMLFontElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLFontElement); } -void HTMLFontElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLFontElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name.equals_ignoring_ascii_case("color"sv)) { // https://html.spec.whatwg.org/multipage/rendering.html#phrasing-content-3:rules-for-parsing-a-legacy-colour-value auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::Color, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Color, CSS::CSSColorValue::create_from_color(color.value())); } else if (name.equals_ignoring_ascii_case("size"sv)) { // When a font element has a size attribute, the user agent is expected to use the following steps, known as the rules for parsing a legacy font size, to treat the attribute as a presentational hint setting the element's 'font-size' property: auto font_size_or_empty = parse_legacy_font_size(value); if (font_size_or_empty.has_value()) { auto font_size = string_from_keyword(font_size_or_empty.release_value()); if (auto parsed_value = parse_css_value(CSS::Parser::ParsingContext { document() }, font_size, CSS::PropertyID::FontSize)) - style.set_property(CSS::PropertyID::FontSize, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::FontSize, parsed_value.release_nonnull()); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLFontElement.h b/Libraries/LibWeb/HTML/HTMLFontElement.h index 28d948a0720..6dabdac0374 100644 --- a/Libraries/LibWeb/HTML/HTMLFontElement.h +++ b/Libraries/LibWeb/HTML/HTMLFontElement.h @@ -17,7 +17,7 @@ class HTMLFontElement final : public HTMLElement { public: virtual ~HTMLFontElement() override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; private: HTMLFontElement(DOM::Document&, DOM::QualifiedName); diff --git a/Libraries/LibWeb/HTML/HTMLHRElement.cpp b/Libraries/LibWeb/HTML/HTMLHRElement.cpp index 403a01d3b27..13c94c3aa92 100644 --- a/Libraries/LibWeb/HTML/HTMLHRElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLHRElement.cpp @@ -28,13 +28,13 @@ void HTMLHRElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLHRElement); } -void HTMLHRElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLHRElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { // https://html.spec.whatwg.org/multipage/rendering.html#the-hr-element-2:maps-to-the-dimension-property if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Width, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, *parsed_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLHRElement.h b/Libraries/LibWeb/HTML/HTMLHRElement.h index 8ed8fafbb67..3a6805d4ffc 100644 --- a/Libraries/LibWeb/HTML/HTMLHRElement.h +++ b/Libraries/LibWeb/HTML/HTMLHRElement.h @@ -26,7 +26,7 @@ private: virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; }; } diff --git a/Libraries/LibWeb/HTML/HTMLHeadingElement.cpp b/Libraries/LibWeb/HTML/HTMLHeadingElement.cpp index 5c254546ee2..ccced4427ce 100644 --- a/Libraries/LibWeb/HTML/HTMLHeadingElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLHeadingElement.cpp @@ -28,19 +28,19 @@ void HTMLHeadingElement::initialize(JS::Realm& realm) } // https://html.spec.whatwg.org/multipage/rendering.html#tables-2 -void HTMLHeadingElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLHeadingElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - HTMLElement::apply_presentational_hints(style); + HTMLElement::apply_presentational_hints(cascaded_properties); for_each_attribute([&](auto& name, auto& value) { if (name.equals_ignoring_ascii_case("align"sv)) { if (value == "left"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Left)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Left)); else if (value == "right"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Right)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Right)); else if (value == "center"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); else if (value == "justify"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Justify)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Justify)); } }); } diff --git a/Libraries/LibWeb/HTML/HTMLHeadingElement.h b/Libraries/LibWeb/HTML/HTMLHeadingElement.h index 81e81e45ad5..285288e121c 100644 --- a/Libraries/LibWeb/HTML/HTMLHeadingElement.h +++ b/Libraries/LibWeb/HTML/HTMLHeadingElement.h @@ -18,7 +18,7 @@ class HTMLHeadingElement final : public HTMLElement { public: virtual ~HTMLHeadingElement() override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; // https://www.w3.org/TR/html-aria/#el-h1-h6 virtual Optional default_role() const override { return ARIA::Role::heading; } diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.cpp b/Libraries/LibWeb/HTML/HTMLImageElement.cpp index fbc453ac199..efef4eec7d8 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLImageElement.cpp @@ -82,32 +82,32 @@ void HTMLImageElement::visit_edges(Cell::Visitor& visitor) visit_lazy_loading_element(visitor); } -void HTMLImageElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLImageElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::hspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginLeft, *parsed_value); - style.set_property(CSS::PropertyID::MarginRight, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginLeft, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginRight, *parsed_value); } } else if (name == HTML::AttributeNames::vspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginTop, *parsed_value); - style.set_property(CSS::PropertyID::MarginBottom, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginTop, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginBottom, *parsed_value); } } else if (name == HTML::AttributeNames::border) { if (auto parsed_value = parse_non_negative_integer(value); parsed_value.has_value()) { auto width_value = CSS::LengthStyleValue::create(CSS::Length::make_px(*parsed_value)); - style.set_property(CSS::PropertyID::BorderTopWidth, width_value); - style.set_property(CSS::PropertyID::BorderRightWidth, width_value); - style.set_property(CSS::PropertyID::BorderBottomWidth, width_value); - style.set_property(CSS::PropertyID::BorderLeftWidth, width_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderTopWidth, width_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderRightWidth, width_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderBottomWidth, width_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderLeftWidth, width_value); auto solid_value = CSS::CSSKeywordValue::create(CSS::Keyword::Solid); - style.set_property(CSS::PropertyID::BorderTopStyle, solid_value); - style.set_property(CSS::PropertyID::BorderRightStyle, solid_value); - style.set_property(CSS::PropertyID::BorderBottomStyle, solid_value); - style.set_property(CSS::PropertyID::BorderLeftStyle, solid_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderTopStyle, solid_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderRightStyle, solid_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderBottomStyle, solid_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderLeftStyle, solid_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLImageElement.h b/Libraries/LibWeb/HTML/HTMLImageElement.h index ddc8854e8bc..e9e584ce03d 100644 --- a/Libraries/LibWeb/HTML/HTMLImageElement.h +++ b/Libraries/LibWeb/HTML/HTMLImageElement.h @@ -121,7 +121,7 @@ private: virtual void adopted_from(DOM::Document&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; // https://html.spec.whatwg.org/multipage/embedded-content.html#the-img-element:dimension-attributes virtual bool supports_dimension_attributes() const override { return true; } diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 607ce240fb5..f6db5ffa821 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1593,7 +1593,7 @@ void HTMLInputElement::form_associated_element_was_removed(DOM::Node*) set_shadow_root(nullptr); } -void HTMLInputElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLInputElement::apply_presentational_hints(GC::Ref cascaded_properties) const { if (type_state() != TypeAttributeState::ImageButton) return; @@ -1601,42 +1601,42 @@ void HTMLInputElement::apply_presentational_hints(CSS::StyleProperties& style) c for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::align) { if (value.equals_ignoring_ascii_case("center"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); else if (value.equals_ignoring_ascii_case("middle"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Middle)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Middle)); } else if (name == HTML::AttributeNames::border) { if (auto parsed_value = parse_non_negative_integer(value); parsed_value.has_value()) { auto width_style_value = CSS::LengthStyleValue::create(CSS::Length::make_px(*parsed_value)); - style.set_property(CSS::PropertyID::BorderTopWidth, width_style_value); - style.set_property(CSS::PropertyID::BorderRightWidth, width_style_value); - style.set_property(CSS::PropertyID::BorderBottomWidth, width_style_value); - style.set_property(CSS::PropertyID::BorderLeftWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderTopWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderRightWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderBottomWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderLeftWidth, width_style_value); auto border_style_value = CSS::CSSKeywordValue::create(CSS::Keyword::Solid); - style.set_property(CSS::PropertyID::BorderTopStyle, border_style_value); - style.set_property(CSS::PropertyID::BorderRightStyle, border_style_value); - style.set_property(CSS::PropertyID::BorderBottomStyle, border_style_value); - style.set_property(CSS::PropertyID::BorderLeftStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderTopStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderRightStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderBottomStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderLeftStyle, border_style_value); } } else if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Height, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, *parsed_value); } } // https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images:maps-to-the-dimension-property else if (name == HTML::AttributeNames::hspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginLeft, *parsed_value); - style.set_property(CSS::PropertyID::MarginRight, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginLeft, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginRight, *parsed_value); } } else if (name == HTML::AttributeNames::vspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginTop, *parsed_value); - style.set_property(CSS::PropertyID::MarginBottom, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginTop, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginBottom, *parsed_value); } } else if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Width, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, *parsed_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.h b/Libraries/LibWeb/HTML/HTMLInputElement.h index 0990ab3153a..92941b8833c 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.h +++ b/Libraries/LibWeb/HTML/HTMLInputElement.h @@ -227,7 +227,7 @@ private: void type_attribute_changed(TypeAttributeState old_state, TypeAttributeState new_state); - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; // ^DOM::Node virtual bool is_html_input_element() const final { return true; } diff --git a/Libraries/LibWeb/HTML/HTMLMarqueeElement.cpp b/Libraries/LibWeb/HTML/HTMLMarqueeElement.cpp index e3380e45c36..acffaefa986 100644 --- a/Libraries/LibWeb/HTML/HTMLMarqueeElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLMarqueeElement.cpp @@ -30,33 +30,33 @@ void HTMLMarqueeElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLMarqueeElement); } -void HTMLMarqueeElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLMarqueeElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - HTMLElement::apply_presentational_hints(style); + HTMLElement::apply_presentational_hints(cascaded_properties); for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::bgcolor) { // https://html.spec.whatwg.org/multipage/rendering.html#the-marquee-element-2:rules-for-parsing-a-legacy-colour-value auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); } else if (name == HTML::AttributeNames::height) { // https://html.spec.whatwg.org/multipage/rendering.html#the-marquee-element-2:maps-to-the-dimension-property if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Height, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, *parsed_value); } } else if (name == HTML::AttributeNames::hspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginLeft, *parsed_value); - style.set_property(CSS::PropertyID::MarginRight, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginLeft, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginRight, *parsed_value); } } else if (name == HTML::AttributeNames::vspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginTop, *parsed_value); - style.set_property(CSS::PropertyID::MarginBottom, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginTop, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginBottom, *parsed_value); } } else if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Width, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, *parsed_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLMarqueeElement.h b/Libraries/LibWeb/HTML/HTMLMarqueeElement.h index dd9c9399b64..9ad94012deb 100644 --- a/Libraries/LibWeb/HTML/HTMLMarqueeElement.h +++ b/Libraries/LibWeb/HTML/HTMLMarqueeElement.h @@ -30,7 +30,7 @@ private: HTMLMarqueeElement(DOM::Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; }; } diff --git a/Libraries/LibWeb/HTML/HTMLObjectElement.cpp b/Libraries/LibWeb/HTML/HTMLObjectElement.cpp index cbc48c862de..324eb0a84a1 100644 --- a/Libraries/LibWeb/HTML/HTMLObjectElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLObjectElement.cpp @@ -100,49 +100,49 @@ void HTMLObjectElement::form_associated_element_was_removed(DOM::Node*) destroy_the_child_navigable(); } -void HTMLObjectElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLObjectElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::align) { if (value.equals_ignoring_ascii_case("center"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); else if (value.equals_ignoring_ascii_case("middle"sv)) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Middle)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Middle)); } else if (name == HTML::AttributeNames::border) { if (auto parsed_value = parse_non_negative_integer(value); parsed_value.has_value()) { auto width_style_value = CSS::LengthStyleValue::create(CSS::Length::make_px(*parsed_value)); - style.set_property(CSS::PropertyID::BorderTopWidth, width_style_value); - style.set_property(CSS::PropertyID::BorderRightWidth, width_style_value); - style.set_property(CSS::PropertyID::BorderBottomWidth, width_style_value); - style.set_property(CSS::PropertyID::BorderLeftWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderTopWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderRightWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderBottomWidth, width_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderLeftWidth, width_style_value); auto border_style_value = CSS::CSSKeywordValue::create(CSS::Keyword::Solid); - style.set_property(CSS::PropertyID::BorderTopStyle, border_style_value); - style.set_property(CSS::PropertyID::BorderRightStyle, border_style_value); - style.set_property(CSS::PropertyID::BorderBottomStyle, border_style_value); - style.set_property(CSS::PropertyID::BorderLeftStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderTopStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderRightStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderBottomStyle, border_style_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderLeftStyle, border_style_value); } } // https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images:maps-to-the-dimension-property-3 else if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Height, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, *parsed_value); } } // https://html.spec.whatwg.org/multipage/rendering.html#attributes-for-embedded-content-and-images:maps-to-the-dimension-property else if (name == HTML::AttributeNames::hspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginLeft, *parsed_value); - style.set_property(CSS::PropertyID::MarginRight, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginLeft, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginRight, *parsed_value); } } else if (name == HTML::AttributeNames::vspace) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::MarginTop, *parsed_value); - style.set_property(CSS::PropertyID::MarginBottom, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginTop, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginBottom, *parsed_value); } } else if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Width, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, *parsed_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLObjectElement.h b/Libraries/LibWeb/HTML/HTMLObjectElement.h index 94a1c70ab99..ee6179884b6 100644 --- a/Libraries/LibWeb/HTML/HTMLObjectElement.h +++ b/Libraries/LibWeb/HTML/HTMLObjectElement.h @@ -54,7 +54,7 @@ private: virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual GC::Ptr create_layout_node(CSS::StyleProperties) override; virtual void adjust_computed_style(CSS::StyleProperties&) override; diff --git a/Libraries/LibWeb/HTML/HTMLParagraphElement.cpp b/Libraries/LibWeb/HTML/HTMLParagraphElement.cpp index 13a77c34484..b78c1b76971 100644 --- a/Libraries/LibWeb/HTML/HTMLParagraphElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLParagraphElement.cpp @@ -28,19 +28,19 @@ void HTMLParagraphElement::initialize(JS::Realm& realm) } // https://html.spec.whatwg.org/multipage/rendering.html#tables-2 -void HTMLParagraphElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLParagraphElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - HTMLElement::apply_presentational_hints(style); + HTMLElement::apply_presentational_hints(cascaded_properties); for_each_attribute([&](auto& name, auto& value) { if (name.equals_ignoring_ascii_case("align"sv)) { if (value == "left"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Left)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Left)); else if (value == "right"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Right)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Right)); else if (value == "center"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Center)); else if (value == "justify"sv) - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Justify)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::Justify)); } }); } diff --git a/Libraries/LibWeb/HTML/HTMLParagraphElement.h b/Libraries/LibWeb/HTML/HTMLParagraphElement.h index d3b2d060c7b..b431d354ee2 100644 --- a/Libraries/LibWeb/HTML/HTMLParagraphElement.h +++ b/Libraries/LibWeb/HTML/HTMLParagraphElement.h @@ -18,7 +18,7 @@ class HTMLParagraphElement final : public HTMLElement { public: virtual ~HTMLParagraphElement() override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; // https://www.w3.org/TR/html-aria/#el-p virtual Optional default_role() const override { return ARIA::Role::paragraph; } diff --git a/Libraries/LibWeb/HTML/HTMLPreElement.cpp b/Libraries/LibWeb/HTML/HTMLPreElement.cpp index 310dff90cf6..4e6a5cdf062 100644 --- a/Libraries/LibWeb/HTML/HTMLPreElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLPreElement.cpp @@ -28,13 +28,13 @@ void HTMLPreElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLPreElement); } -void HTMLPreElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLPreElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - HTMLElement::apply_presentational_hints(style); + HTMLElement::apply_presentational_hints(cascaded_properties); for_each_attribute([&](auto const& name, auto const&) { if (name.equals_ignoring_ascii_case(HTML::AttributeNames::wrap)) - style.set_property(CSS::PropertyID::WhiteSpace, CSS::CSSKeywordValue::create(CSS::Keyword::PreWrap)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::WhiteSpace, CSS::CSSKeywordValue::create(CSS::Keyword::PreWrap)); }); } diff --git a/Libraries/LibWeb/HTML/HTMLPreElement.h b/Libraries/LibWeb/HTML/HTMLPreElement.h index 7f17ca84809..6de15dd44a0 100644 --- a/Libraries/LibWeb/HTML/HTMLPreElement.h +++ b/Libraries/LibWeb/HTML/HTMLPreElement.h @@ -26,7 +26,7 @@ private: HTMLPreElement(DOM::Document&, DOM::QualifiedName); virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; }; } diff --git a/Libraries/LibWeb/HTML/HTMLTableCaptionElement.cpp b/Libraries/LibWeb/HTML/HTMLTableCaptionElement.cpp index b004f0774d6..456ff1fb9ce 100644 --- a/Libraries/LibWeb/HTML/HTMLTableCaptionElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableCaptionElement.cpp @@ -28,13 +28,13 @@ void HTMLTableCaptionElement::initialize(JS::Realm& realm) } // https://html.spec.whatwg.org/multipage/rendering.html#tables-2 -void HTMLTableCaptionElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLTableCaptionElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - HTMLElement::apply_presentational_hints(style); + HTMLElement::apply_presentational_hints(cascaded_properties); for_each_attribute([&](auto& name, auto& value) { if (name.equals_ignoring_ascii_case("align"sv)) { if (value == "bottom"sv) - style.set_property(CSS::PropertyID::CaptionSide, CSS::CSSKeywordValue::create(CSS::Keyword::Bottom)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::CaptionSide, CSS::CSSKeywordValue::create(CSS::Keyword::Bottom)); } }); } diff --git a/Libraries/LibWeb/HTML/HTMLTableCaptionElement.h b/Libraries/LibWeb/HTML/HTMLTableCaptionElement.h index 8bc898a2af0..91eafaa86a8 100644 --- a/Libraries/LibWeb/HTML/HTMLTableCaptionElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableCaptionElement.h @@ -18,7 +18,7 @@ class HTMLTableCaptionElement final : public HTMLElement { public: virtual ~HTMLTableCaptionElement() override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; // https://www.w3.org/TR/html-aria/#el-caption virtual Optional default_role() const override { return ARIA::Role::caption; } diff --git a/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp b/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp index a745ce363ed..53ffe6d79d3 100644 --- a/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableCellElement.cpp @@ -37,46 +37,46 @@ void HTMLTableCellElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLTableCellElement); } -void HTMLTableCellElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLTableCellElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::bgcolor) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); return; } if (name == HTML::AttributeNames::valign) { if (auto parsed_value = parse_css_value(CSS::Parser::ParsingContext { document() }, value, CSS::PropertyID::VerticalAlign)) - style.set_property(CSS::PropertyID::VerticalAlign, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::VerticalAlign, parsed_value.release_nonnull()); return; } if (name == HTML::AttributeNames::align) { if (value.equals_ignoring_ascii_case("center"sv) || value.equals_ignoring_ascii_case("middle"sv)) { - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebCenter)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebCenter)); } else if (value.equals_ignoring_ascii_case("left"sv)) { - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebLeft)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebLeft)); } else if (value.equals_ignoring_ascii_case("right"sv)) { - style.set_property(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebRight)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, CSS::CSSKeywordValue::create(CSS::Keyword::LibwebRight)); } else { if (auto parsed_value = parse_css_value(CSS::Parser::ParsingContext { document() }, value, CSS::PropertyID::TextAlign)) - style.set_property(CSS::PropertyID::TextAlign, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::TextAlign, parsed_value.release_nonnull()); } return; } if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_nonzero_dimension_value(value)) - style.set_property(CSS::PropertyID::Width, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, parsed_value.release_nonnull()); return; } else if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_nonzero_dimension_value(value)) - style.set_property(CSS::PropertyID::Height, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, parsed_value.release_nonnull()); return; } else if (name == HTML::AttributeNames::background) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) - style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); return; } }); @@ -86,10 +86,10 @@ void HTMLTableCellElement::apply_presentational_hints(CSS::StyleProperties& styl return; if (auto padding = table_element->padding()) { - style.set_property(CSS::PropertyID::PaddingTop, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); - style.set_property(CSS::PropertyID::PaddingBottom, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); - style.set_property(CSS::PropertyID::PaddingLeft, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); - style.set_property(CSS::PropertyID::PaddingRight, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::PaddingTop, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::PaddingBottom, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::PaddingLeft, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::PaddingRight, CSS::LengthStyleValue::create(CSS::Length::make_px(padding))); } auto border = table_element->border(); @@ -97,9 +97,9 @@ void HTMLTableCellElement::apply_presentational_hints(CSS::StyleProperties& styl if (!border) return; auto apply_border_style = [&](CSS::PropertyID style_property, CSS::PropertyID width_property, CSS::PropertyID color_property) { - style.set_property(style_property, CSS::CSSKeywordValue::create(CSS::Keyword::Inset)); - style.set_property(width_property, CSS::LengthStyleValue::create(CSS::Length::make_px(1))); - style.set_property(color_property, table_element->computed_css_values()->property(color_property)); + cascaded_properties->set_property_from_presentational_hint(style_property, CSS::CSSKeywordValue::create(CSS::Keyword::Inset)); + cascaded_properties->set_property_from_presentational_hint(width_property, CSS::LengthStyleValue::create(CSS::Length::make_px(1))); + cascaded_properties->set_property_from_presentational_hint(color_property, table_element->computed_css_values()->property(color_property)); }; apply_border_style(CSS::PropertyID::BorderLeftStyle, CSS::PropertyID::BorderLeftWidth, CSS::PropertyID::BorderLeftColor); apply_border_style(CSS::PropertyID::BorderTopStyle, CSS::PropertyID::BorderTopWidth, CSS::PropertyID::BorderTopColor); diff --git a/Libraries/LibWeb/HTML/HTMLTableCellElement.h b/Libraries/LibWeb/HTML/HTMLTableCellElement.h index 1067e79b732..9d8beff1f49 100644 --- a/Libraries/LibWeb/HTML/HTMLTableCellElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableCellElement.h @@ -34,7 +34,7 @@ private: virtual bool is_html_table_cell_element() const override { return true; } virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; }; } diff --git a/Libraries/LibWeb/HTML/HTMLTableColElement.cpp b/Libraries/LibWeb/HTML/HTMLTableColElement.cpp index 48351f6b6ee..0a64ba2132b 100644 --- a/Libraries/LibWeb/HTML/HTMLTableColElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableColElement.cpp @@ -51,13 +51,13 @@ WebIDL::ExceptionOr HTMLTableColElement::set_span(unsigned int value) return set_attribute(HTML::AttributeNames::span, String::number(value)); } -void HTMLTableColElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLTableColElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:maps-to-the-dimension-property-2 if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_dimension_value(value)) { - style.set_property(CSS::PropertyID::Width, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, *parsed_value); } } }); diff --git a/Libraries/LibWeb/HTML/HTMLTableColElement.h b/Libraries/LibWeb/HTML/HTMLTableColElement.h index a5d499199f9..64411bed3b3 100644 --- a/Libraries/LibWeb/HTML/HTMLTableColElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableColElement.h @@ -26,7 +26,7 @@ private: virtual void initialize(JS::Realm&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; }; } diff --git a/Libraries/LibWeb/HTML/HTMLTableElement.cpp b/Libraries/LibWeb/HTML/HTMLTableElement.cpp index cd391d7a7c0..dbc93d4067e 100644 --- a/Libraries/LibWeb/HTML/HTMLTableElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableElement.cpp @@ -51,44 +51,44 @@ static unsigned parse_border(StringView value) return value.to_number().value_or(0); } -void HTMLTableElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLTableElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::width) { if (auto parsed_value = parse_nonzero_dimension_value(value)) - style.set_property(CSS::PropertyID::Width, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, parsed_value.release_nonnull()); return; } if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_dimension_value(value)) - style.set_property(CSS::PropertyID::Height, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, parsed_value.release_nonnull()); return; } if (name == HTML::AttributeNames::align) { if (value.equals_ignoring_ascii_case("center"sv)) { - style.set_property(CSS::PropertyID::MarginLeft, CSS::CSSKeywordValue::create(CSS::Keyword::Auto)); - style.set_property(CSS::PropertyID::MarginRight, CSS::CSSKeywordValue::create(CSS::Keyword::Auto)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginLeft, CSS::CSSKeywordValue::create(CSS::Keyword::Auto)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::MarginRight, CSS::CSSKeywordValue::create(CSS::Keyword::Auto)); } else if (auto parsed_value = parse_css_value(CSS::Parser::ParsingContext { document() }, value, CSS::PropertyID::Float)) { - style.set_property(CSS::PropertyID::Float, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Float, parsed_value.release_nonnull()); } return; } if (name == HTML::AttributeNames::background) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) - style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); return; } if (name == HTML::AttributeNames::bgcolor) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); return; } if (name == HTML::AttributeNames::cellspacing) { if (auto parsed_value = parse_dimension_value(value)) - style.set_property(CSS::PropertyID::BorderSpacing, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BorderSpacing, parsed_value.release_nonnull()); return; } if (name == HTML::AttributeNames::border) { @@ -97,9 +97,9 @@ void HTMLTableElement::apply_presentational_hints(CSS::StyleProperties& style) c return; auto apply_border_style = [&](CSS::PropertyID style_property, CSS::PropertyID width_property, CSS::PropertyID color_property) { auto legacy_line_style = CSS::CSSKeywordValue::create(CSS::Keyword::Outset); - style.set_property(style_property, legacy_line_style); - style.set_property(width_property, CSS::LengthStyleValue::create(CSS::Length::make_px(border))); - style.set_property(color_property, CSS::CSSColorValue::create_from_color(Color(128, 128, 128))); + cascaded_properties->set_property_from_presentational_hint(style_property, legacy_line_style); + cascaded_properties->set_property_from_presentational_hint(width_property, CSS::LengthStyleValue::create(CSS::Length::make_px(border))); + cascaded_properties->set_property_from_presentational_hint(color_property, CSS::CSSColorValue::create_from_color(Color(128, 128, 128))); }; apply_border_style(CSS::PropertyID::BorderLeftStyle, CSS::PropertyID::BorderLeftWidth, CSS::PropertyID::BorderLeftColor); apply_border_style(CSS::PropertyID::BorderTopStyle, CSS::PropertyID::BorderTopWidth, CSS::PropertyID::BorderTopColor); diff --git a/Libraries/LibWeb/HTML/HTMLTableElement.h b/Libraries/LibWeb/HTML/HTMLTableElement.h index eee1c0da7b1..73eb5d73bd6 100644 --- a/Libraries/LibWeb/HTML/HTMLTableElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableElement.h @@ -58,7 +58,7 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; GC::Ptr mutable m_rows; diff --git a/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp b/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp index ebdf3103ba7..3193874da17 100644 --- a/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableRowElement.cpp @@ -39,25 +39,25 @@ void HTMLTableRowElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLTableRowElement); } -void HTMLTableRowElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLTableRowElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - Base::apply_presentational_hints(style); + Base::apply_presentational_hints(cascaded_properties); for_each_attribute([&](auto& name, auto& value) { if (name == HTML::AttributeNames::bgcolor) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value auto color = parse_legacy_color_value(value); if (color.has_value()) - style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); } else if (name == HTML::AttributeNames::background) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) - style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); } else if (name == HTML::AttributeNames::height) { if (auto parsed_value = parse_dimension_value(value)) - style.set_property(CSS::PropertyID::Height, *parsed_value); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, *parsed_value); } else if (name == HTML::AttributeNames::valign) { if (auto parsed_value = parse_css_value(CSS::Parser::ParsingContext { document() }, value, CSS::PropertyID::VerticalAlign)) - style.set_property(CSS::PropertyID::VerticalAlign, parsed_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::VerticalAlign, parsed_value.release_nonnull()); } }); } diff --git a/Libraries/LibWeb/HTML/HTMLTableRowElement.h b/Libraries/LibWeb/HTML/HTMLTableRowElement.h index 757e82f88a3..47aeba89285 100644 --- a/Libraries/LibWeb/HTML/HTMLTableRowElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableRowElement.h @@ -35,7 +35,7 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; GC::Ptr mutable m_cells; }; diff --git a/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp b/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp index f00c8b69d2f..842130800ca 100644 --- a/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLTableSectionElement.cpp @@ -100,18 +100,18 @@ WebIDL::ExceptionOr HTMLTableSectionElement::delete_row(WebIDL::Long index return {}; } -void HTMLTableSectionElement::apply_presentational_hints(CSS::StyleProperties& style) const +void HTMLTableSectionElement::apply_presentational_hints(GC::Ref cascaded_properties) const { for_each_attribute([&](auto& name, auto& value) { // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:encoding-parsing-and-serializing-a-url if (name == HTML::AttributeNames::background) { if (auto parsed_value = document().encoding_parse_url(value); parsed_value.is_valid()) - style.set_property(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundImage, CSS::ImageStyleValue::create(parsed_value)); } // https://html.spec.whatwg.org/multipage/rendering.html#tables-2:rules-for-parsing-a-legacy-colour-value else if (name == HTML::AttributeNames::bgcolor) { if (auto color = parse_legacy_color_value(value); color.has_value()) - style.set_property(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::BackgroundColor, CSS::CSSColorValue::create_from_color(color.value())); } }); } diff --git a/Libraries/LibWeb/HTML/HTMLTableSectionElement.h b/Libraries/LibWeb/HTML/HTMLTableSectionElement.h index f40780b4999..83b1554bb9f 100644 --- a/Libraries/LibWeb/HTML/HTMLTableSectionElement.h +++ b/Libraries/LibWeb/HTML/HTMLTableSectionElement.h @@ -37,7 +37,7 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; GC::Ptr mutable m_rows; }; diff --git a/Libraries/LibWeb/SVG/SVGCircleElement.cpp b/Libraries/LibWeb/SVG/SVGCircleElement.cpp index f0224371eb7..ce75225e98d 100644 --- a/Libraries/LibWeb/SVG/SVGCircleElement.cpp +++ b/Libraries/LibWeb/SVG/SVGCircleElement.cpp @@ -29,22 +29,22 @@ void SVGCircleElement::initialize(JS::Realm& realm) WEB_SET_PROTOTYPE_FOR_INTERFACE(SVGCircleElement); } -void SVGCircleElement::apply_presentational_hints(CSS::StyleProperties& style) const +void SVGCircleElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - Base::apply_presentational_hints(style); + Base::apply_presentational_hints(cascaded_properties); auto parsing_context = CSS::Parser::ParsingContext { document(), CSS::Parser::ParsingContext::Mode::SVGPresentationAttribute }; auto cx_attribute = attribute(SVG::AttributeNames::cx); if (auto cx_value = parse_css_value(parsing_context, cx_attribute.value_or(String {}), CSS::PropertyID::Cx)) - style.set_property(CSS::PropertyID::Cx, cx_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Cx, cx_value.release_nonnull()); auto cy_attribute = attribute(SVG::AttributeNames::cy); if (auto cy_value = parse_css_value(parsing_context, cy_attribute.value_or(String {}), CSS::PropertyID::Cy)) - style.set_property(CSS::PropertyID::Cy, cy_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Cy, cy_value.release_nonnull()); auto r_attribute = attribute(SVG::AttributeNames::r); if (auto r_value = parse_css_value(parsing_context, r_attribute.value_or(String {}), CSS::PropertyID::R)) - style.set_property(CSS::PropertyID::R, r_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::R, r_value.release_nonnull()); } Gfx::Path SVGCircleElement::get_path(CSSPixelSize viewport_size) diff --git a/Libraries/LibWeb/SVG/SVGCircleElement.h b/Libraries/LibWeb/SVG/SVGCircleElement.h index f734f15c08c..c4b841784fc 100644 --- a/Libraries/LibWeb/SVG/SVGCircleElement.h +++ b/Libraries/LibWeb/SVG/SVGCircleElement.h @@ -18,7 +18,7 @@ class SVGCircleElement final : public SVGGeometryElement { public: virtual ~SVGCircleElement() override = default; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual Gfx::Path get_path(CSSPixelSize viewport_size) override; diff --git a/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp b/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp index 8c1364bd530..16d00f95b54 100644 --- a/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp +++ b/Libraries/LibWeb/SVG/SVGForeignObjectElement.cpp @@ -52,15 +52,15 @@ GC::Ptr SVGForeignObjectElement::create_layout_node(CSS::StyleProp return heap().allocate(document(), *this, move(style)); } -void SVGForeignObjectElement::apply_presentational_hints(CSS::StyleProperties& style) const +void SVGForeignObjectElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - Base::apply_presentational_hints(style); + Base::apply_presentational_hints(cascaded_properties); auto parsing_context = CSS::Parser::ParsingContext { document() }; if (auto width_value = parse_css_value(parsing_context, get_attribute_value(Web::HTML::AttributeNames::width), CSS::PropertyID::Width)) - style.set_property(CSS::PropertyID::Width, width_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, width_value.release_nonnull()); if (auto height_value = parse_css_value(parsing_context, get_attribute_value(Web::HTML::AttributeNames::height), CSS::PropertyID::Height)) - style.set_property(CSS::PropertyID::Height, height_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, height_value.release_nonnull()); } GC::Ref SVGForeignObjectElement::x() diff --git a/Libraries/LibWeb/SVG/SVGForeignObjectElement.h b/Libraries/LibWeb/SVG/SVGForeignObjectElement.h index ddf952b9c25..3e9744e302d 100644 --- a/Libraries/LibWeb/SVG/SVGForeignObjectElement.h +++ b/Libraries/LibWeb/SVG/SVGForeignObjectElement.h @@ -31,7 +31,7 @@ private: virtual void initialize(JS::Realm&) override; virtual void visit_edges(Cell::Visitor&) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; GC::Ptr m_x; GC::Ptr m_y; diff --git a/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp b/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp index 840a548d979..f824508517d 100644 --- a/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp +++ b/Libraries/LibWeb/SVG/SVGGraphicsElement.cpp @@ -143,7 +143,7 @@ struct NamedPropertyID { StringView name; }; -void SVGGraphicsElement::apply_presentational_hints(CSS::StyleProperties& style) const +void SVGGraphicsElement::apply_presentational_hints(GC::Ref cascaded_properties) const { static Array const attribute_style_properties { // FIXME: The `fill` attribute and CSS `fill` property are not the same! But our support is limited enough that they are equivalent for now. @@ -175,7 +175,7 @@ void SVGGraphicsElement::apply_presentational_hints(CSS::StyleProperties& style) if (!name.equals_ignoring_ascii_case(property.name)) continue; if (auto style_value = parse_css_value(parsing_context, value, property.id)) - style.set_property(property.id, style_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(property.id, style_value.release_nonnull()); break; } }); diff --git a/Libraries/LibWeb/SVG/SVGGraphicsElement.h b/Libraries/LibWeb/SVG/SVGGraphicsElement.h index 2e1c090c767..3fd2bf1675a 100644 --- a/Libraries/LibWeb/SVG/SVGGraphicsElement.h +++ b/Libraries/LibWeb/SVG/SVGGraphicsElement.h @@ -29,7 +29,7 @@ class SVGGraphicsElement : public SVGElement { WEB_PLATFORM_OBJECT(SVGGraphicsElement, SVGElement); public: - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual void attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) override; diff --git a/Libraries/LibWeb/SVG/SVGSVGElement.cpp b/Libraries/LibWeb/SVG/SVGSVGElement.cpp index e91d5789e95..9d94ab04efc 100644 --- a/Libraries/LibWeb/SVG/SVGSVGElement.cpp +++ b/Libraries/LibWeb/SVG/SVGSVGElement.cpp @@ -79,26 +79,26 @@ RefPtr SVGSVGElement::height_style_value_from_attribute() co return nullptr; } -void SVGSVGElement::apply_presentational_hints(CSS::StyleProperties& style) const +void SVGSVGElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - Base::apply_presentational_hints(style); + Base::apply_presentational_hints(cascaded_properties); auto parsing_context = CSS::Parser::ParsingContext { document(), CSS::Parser::ParsingContext::Mode::SVGPresentationAttribute }; auto x_attribute = attribute(SVG::AttributeNames::x); if (auto x_value = parse_css_value(parsing_context, x_attribute.value_or(String {}), CSS::PropertyID::X)) { - style.set_property(CSS::PropertyID::X, x_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::X, x_value.release_nonnull()); } auto y_attribute = attribute(SVG::AttributeNames::y); if (auto y_value = parse_css_value(parsing_context, y_attribute.value_or(String {}), CSS::PropertyID::Y)) { - style.set_property(CSS::PropertyID::Y, y_value.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Y, y_value.release_nonnull()); } if (auto width = width_style_value_from_attribute()) - style.set_property(CSS::PropertyID::Width, width.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Width, width.release_nonnull()); if (auto height = height_style_value_from_attribute()) - style.set_property(CSS::PropertyID::Height, height.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Height, height.release_nonnull()); } void SVGSVGElement::attribute_changed(FlyString const& name, Optional const& old_value, Optional const& value, Optional const& namespace_) diff --git a/Libraries/LibWeb/SVG/SVGSVGElement.h b/Libraries/LibWeb/SVG/SVGSVGElement.h index fb33d1721eb..0aa2545a3ac 100644 --- a/Libraries/LibWeb/SVG/SVGSVGElement.h +++ b/Libraries/LibWeb/SVG/SVGSVGElement.h @@ -31,7 +31,7 @@ class SVGSVGElement final : public SVGGraphicsElement public: virtual GC::Ptr create_layout_node(CSS::StyleProperties) override; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual bool requires_svg_container() const override { return false; } virtual bool is_svg_container() const override { return true; } diff --git a/Libraries/LibWeb/SVG/SVGStopElement.cpp b/Libraries/LibWeb/SVG/SVGStopElement.cpp index b51cac542b9..d34d473bfdb 100644 --- a/Libraries/LibWeb/SVG/SVGStopElement.cpp +++ b/Libraries/LibWeb/SVG/SVGStopElement.cpp @@ -30,18 +30,18 @@ void SVGStopElement::attribute_changed(FlyString const& name, Optional c } } -void SVGStopElement::apply_presentational_hints(CSS::StyleProperties& style) const +void SVGStopElement::apply_presentational_hints(GC::Ref cascaded_properties) const { CSS::Parser::ParsingContext parsing_context { document() }; for_each_attribute([&](auto& name, auto& value) { CSS::Parser::ParsingContext parsing_context { document() }; if (name.equals_ignoring_ascii_case("stop-color"sv)) { if (auto stop_color = parse_css_value(parsing_context, value, CSS::PropertyID::StopColor)) { - style.set_property(CSS::PropertyID::StopColor, stop_color.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::StopColor, stop_color.release_nonnull()); } } else if (name.equals_ignoring_ascii_case("stop-opacity"sv)) { if (auto stop_opacity = parse_css_value(parsing_context, value, CSS::PropertyID::StopOpacity)) { - style.set_property(CSS::PropertyID::StopOpacity, stop_opacity.release_nonnull()); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::StopOpacity, stop_opacity.release_nonnull()); } } }); diff --git a/Libraries/LibWeb/SVG/SVGStopElement.h b/Libraries/LibWeb/SVG/SVGStopElement.h index 79d26682cd9..20a625a63e9 100644 --- a/Libraries/LibWeb/SVG/SVGStopElement.h +++ b/Libraries/LibWeb/SVG/SVGStopElement.h @@ -25,7 +25,7 @@ public: GC::Ref offset() const; - virtual void apply_presentational_hints(CSS::StyleProperties&) const override; + virtual void apply_presentational_hints(GC::Ref) const override; NumberPercentage stop_offset() const { return m_offset.value_or(NumberPercentage::create_number(0)); } Gfx::Color stop_color() const; diff --git a/Libraries/LibWeb/SVG/SVGSymbolElement.cpp b/Libraries/LibWeb/SVG/SVGSymbolElement.cpp index f940d3a1af4..8545b129dcf 100644 --- a/Libraries/LibWeb/SVG/SVGSymbolElement.cpp +++ b/Libraries/LibWeb/SVG/SVGSymbolElement.cpp @@ -40,13 +40,13 @@ void SVGSymbolElement::visit_edges(Cell::Visitor& visitor) } // https://svgwg.org/svg2-draft/struct.html#SymbolNotes -void SVGSymbolElement::apply_presentational_hints(CSS::StyleProperties& style) const +void SVGSymbolElement::apply_presentational_hints(GC::Ref cascaded_properties) const { - Base::apply_presentational_hints(style); + Base::apply_presentational_hints(cascaded_properties); if (is_direct_child_of_use_shadow_tree()) { // The generated instance of a ‘symbol’ that is the direct referenced element of a ‘use’ element must always have a computed value of inline for the display property. - style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Inline))); + cascaded_properties->set_property_from_presentational_hint(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Inline))); } } diff --git a/Libraries/LibWeb/SVG/SVGSymbolElement.h b/Libraries/LibWeb/SVG/SVGSymbolElement.h index 47caa47873c..1dcccb7176b 100644 --- a/Libraries/LibWeb/SVG/SVGSymbolElement.h +++ b/Libraries/LibWeb/SVG/SVGSymbolElement.h @@ -19,7 +19,7 @@ class SVGSymbolElement final : public SVGGraphicsElement public: virtual ~SVGSymbolElement() override = default; - void apply_presentational_hints(CSS::StyleProperties& style) const override; + virtual void apply_presentational_hints(GC::Ref) const override; virtual Optional view_box() const override { return m_view_box; } virtual Optional preserve_aspect_ratio() const override