Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 71 additions & 21 deletions Libraries/LibWeb/CSS/StyleComputer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -915,6 +915,7 @@ void StyleComputer::collect_animations_into(DOM::AbstractElement abstract_elemen
void StyleComputer::collect_animations_into(DOM::AbstractElement abstract_element, ReadonlySpan<GC::Ref<Animations::KeyframeEffect>> effects, ComputedProperties& computed_properties) const
{
collect_animation_effects_into(abstract_element, effects, computed_properties, nullptr);
adjust_animated_element_style_if_needed(computed_properties, abstract_element);
}

void StyleComputer::collect_animation_effects_into(DOM::AbstractElement abstract_element, ReadonlySpan<GC::Ref<Animations::KeyframeEffect>> effects, ComputedProperties& computed_properties, ComputedProperties::Builder* builder) const
Expand Down Expand Up @@ -2995,36 +2996,89 @@ static ComputedValuesFFI::FfiBoxTypeTransformationInput make_box_type_transforma
};
}

static void apply_box_type_transformation(ComputedProperties::Builder& builder, ComputedValuesFFI::FfiDisplay const& display_before, ComputedValuesFFI::FfiBoxTypeTransformation const& transformation)
{
builder.set_display_before_box_type_transformation(display_from_ffi_display(display_before));
if (transformation.set_float_none)
builder.set_property(PropertyID::Float, KeywordStyleValue::create(Keyword::None));
if (transformation.changed_display)
builder.set_property(PropertyID::Display, DisplayStyleValue::create(display_from_ffi_display(transformation.display)));
}

static ComputedValuesFFI::FfiInputLineHeightMetrics input_line_height_metrics(ComputedProperties::Builder& builder, DOM::AbstractElement abstract_element, bool should_measure)
template<typename Style>
static ComputedValuesFFI::FfiInputLineHeightMetrics input_line_height_metrics(Style& style, DOM::AbstractElement abstract_element, bool should_measure)
{
ComputedValuesFFI::FfiInputLineHeightMetrics line_height_metrics {};
if (should_measure) {
line_height_metrics.current_line_height = builder.line_height(abstract_element.element().document().font_computer()).to_double();
line_height_metrics.minimum_line_height = ComputedProperties::normal_line_height(builder.first_available_computed_font(abstract_element.element().document().font_computer())->pixel_metrics()).to_double();
line_height_metrics.current_line_height = style.line_height(abstract_element.element().document().font_computer()).to_double();
line_height_metrics.minimum_line_height = ComputedProperties::normal_line_height(style.first_available_computed_font(abstract_element.element().document().font_computer())->pixel_metrics()).to_double();
}
return line_height_metrics;
}

template<typename Style, typename SetProperty>
static void apply_element_style_adjustments(Style& style, DOM::AbstractElement abstract_element, ComputedValuesFFI::FfiElementStyleAdjustments const& adjustments, SetProperty set_property)
{
if (adjustments.box_type.set_float_none)
set_property(PropertyID::Float, KeywordStyleValue::create(Keyword::None));
if (adjustments.box_type.changed_display)
set_property(PropertyID::Display, DisplayStyleValue::create(display_from_ffi_display(adjustments.box_type.display)));

auto const& element_style = adjustments.element_style;
if (element_style.changed_display)
set_property(PropertyID::Display, DisplayStyleValue::create(display_from_ffi_display(element_style.display)));
if (element_style.set_position_static)
set_property(PropertyID::Position, KeywordStyleValue::create(Keyword::Static));
if (element_style.changed_text_align)
set_property(PropertyID::TextAlign, KeywordStyleValue::create(static_cast<Keyword>(element_style.text_align)));

auto line_height_metrics = input_line_height_metrics(style, abstract_element, element_style.check_input_line_height);
if (element_style.set_line_height_normal || (element_style.check_input_line_height && line_height_metrics.current_line_height < line_height_metrics.minimum_line_height))
set_property(PropertyID::LineHeight, KeywordStyleValue::create(Keyword::Normal));
}

// https://drafts.csswg.org/css-display/#transformations
void StyleComputer::transform_box_type_if_needed(ComputedProperties::Builder& builder, DOM::AbstractElement abstract_element) const
void StyleComputer::adjust_element_style_if_needed(ComputedProperties::Builder& builder, DOM::AbstractElement abstract_element) const
{
auto& style = builder.style();
auto input = make_box_type_transformation_input(
abstract_element,
style.display(),
style.property(PropertyID::Position).to_keyword(),
style.property(PropertyID::Float).to_keyword());
auto transformation = ComputedValuesFFI::rust_transform_box_type(&input);
apply_box_type_transformation(builder, input.display, transformation);
auto adjustments = ComputedValuesFFI::rust_adjust_element_style(
&input, to_underlying(style.property(PropertyID::TextAlign).to_keyword()));

auto set_adjusted_property = [&](PropertyID property_id, NonnullRefPtr<StyleValue const> value) {
// Animated values are stored separately from the builder's base values, so post-compute
// adjustments must replace the sampled value as well.
if (style.has_animated_property(property_id)) {
auto is_result_of_transition = style.is_animated_property_result_of_transition(property_id)
? AnimatedPropertyResultOfTransition::Yes
: AnimatedPropertyResultOfTransition::No;
auto inherited = style.is_animated_property_inherited(property_id)
? ComputedProperties::Inherited::Yes
: ComputedProperties::Inherited::No;
style.set_animated_property(Badge<StyleComputer> {}, property_id, value, is_result_of_transition, inherited);
}
builder.set_property(property_id, move(value));
};

builder.set_display_before_box_type_transformation(display_from_ffi_display(input.display));
apply_element_style_adjustments(builder, abstract_element, adjustments, set_adjusted_property);
}

void StyleComputer::adjust_animated_element_style_if_needed(ComputedProperties& style, DOM::AbstractElement abstract_element) const
{
auto input = make_box_type_transformation_input(
abstract_element,
style.display(),
style.property(PropertyID::Position).to_keyword(),
style.property(PropertyID::Float).to_keyword());
auto adjustments = ComputedValuesFFI::rust_adjust_element_style(
&input, to_underlying(style.property(PropertyID::TextAlign).to_keyword()));

auto set_adjusted_property = [&](PropertyID property_id, NonnullRefPtr<StyleValue const> value) {
auto is_result_of_transition = style.has_animated_property(property_id) && style.is_animated_property_result_of_transition(property_id)
? AnimatedPropertyResultOfTransition::Yes
: AnimatedPropertyResultOfTransition::No;
auto inherited = style.has_animated_property(property_id) && style.is_animated_property_inherited(property_id)
? ComputedProperties::Inherited::Yes
: ComputedProperties::Inherited::No;
style.set_animated_property(Badge<StyleComputer> {}, property_id, move(value), is_result_of_transition, inherited);
};
apply_element_style_adjustments(style, abstract_element, adjustments, set_adjusted_property);
}

NonnullRefPtr<ComputedValues const> StyleComputer::create_document_style() const
Expand Down Expand Up @@ -3215,7 +3269,7 @@ RefPtr<ComputedProperties> StyleComputer::compute_style_impl(DOM::AbstractElemen
VERIFY(inherited_pseudo_element_style);
auto builder = ComputedProperties::create_builder_with_base_values_from(*inherited_pseudo_element_style);

abstract_element.element().adjust_computed_style(builder);
adjust_element_style_if_needed(builder, abstract_element);
return ComputedProperties::create(move(builder));
}

Expand Down Expand Up @@ -3780,18 +3834,14 @@ NonnullRefPtr<ComputedProperties> StyleComputer::compute_properties(DOM::Abstrac

// Run automatic box type transformations again after animations have been applied.
if (animation_values_applied)
transform_box_type_if_needed(builder, abstract_element);
adjust_element_style_if_needed(builder, abstract_element);

// Apply any property-specific computed value logic
if (animation_values_applied)
resolve_effective_overflow_values(builder);
if (animation_values_applied || parent_text_align_input_is_animated)
compute_text_align(builder, abstract_element);

// Let the element adjust computed style
if (animation_values_applied && !abstract_element.pseudo_element().has_value())
abstract_element.element().adjust_computed_style(builder);

bool parent_style_in_display_none_subtree = false;
if (auto parent = abstract_element.element_to_inherit_style_from(); parent.has_value()) {
if (auto parent_style = parent->computed_values())
Expand Down
3 changes: 2 additions & 1 deletion Libraries/LibWeb/CSS/StyleComputer.h
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ class WEB_API StyleComputer final : public GC::Cell {
void compute_custom_properties(ComputedProperties&, DOM::AbstractElement) const;
void start_needed_transitions(ComputedValues const& old_style, ComputedProperties::Builder& new_style, DOM::AbstractElement) const;
void resolve_effective_overflow_values(ComputedProperties::Builder&) const;
void transform_box_type_if_needed(ComputedProperties::Builder&, DOM::AbstractElement) const;
void adjust_element_style_if_needed(ComputedProperties::Builder&, DOM::AbstractElement) const;
void adjust_animated_element_style_if_needed(ComputedProperties&, DOM::AbstractElement) const;

[[nodiscard]] CSSPixelRect viewport_rect() const { return m_viewport_rect; }

Expand Down
1 change: 0 additions & 1 deletion Libraries/LibWeb/DOM/Element.h
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,6 @@ class WEB_API Element
[[nodiscard]] CSSPixelRect bounding_client_rect_assuming_layout_clean() const;

virtual RefPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::ComputedValues const>);
virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) { }

virtual void did_receive_focus() { }
virtual void did_lose_focus() { }
Expand Down
9 changes: 0 additions & 9 deletions Libraries/LibWeb/HTML/HTMLAudioElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ void HTMLAudioElement::initialize(JS::Realm& realm)
Base::initialize(realm);
}

void HTMLAudioElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
Base::adjust_computed_style(style);

// https://html.spec.whatwg.org/multipage/rendering.html#embedded-content-rendering-rules
if (!has_attribute(AttributeNames::controls))
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}

RefPtr<Layout::Node> HTMLAudioElement::create_layout_node(NonnullRefPtr<CSS::ComputedValues const> style)
{
return make_ref_counted<Layout::AudioBox>(document(), *this, style);
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLAudioElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@ class HTMLAudioElement final : public HTMLMediaElement {
public:
virtual ~HTMLAudioElement() override;

virtual void adjust_computed_style(CSS::ComputedProperties::Builder& style) override;

Layout::AudioBox* layout_node();
Layout::AudioBox const* layout_node() const;

Expand Down
10 changes: 0 additions & 10 deletions Libraries/LibWeb/HTML/HTMLBRElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,4 @@ bool HTMLBRElement::represents_empty_line() const
return true;
}

void HTMLBRElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://drafts.csswg.org/css-display-3/#unbox
if (style.display().is_contents())
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
else if (!style.display().is_none())
// AD-HOC: Prevent other display values from applying, so that we always create a BreakNode
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::Inline)));
}

}
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLBRElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ class HTMLBRElement final : public HTMLElement {
virtual RefPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::ComputedValues const>) override;
virtual bool is_presentational_hint(Utf16FlyString const&) const override;
virtual void apply_presentational_hints(Vector<CSS::StyleProperty>&) const override;
virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;

// Whether this <br> renders an empty line, i.e. nothing else renders between the start of its line and the <br>
// itself. Such a <br> hosts a caret position on its parent, at its child index.
bool represents_empty_line() const;
Expand Down
17 changes: 0 additions & 17 deletions Libraries/LibWeb/HTML/HTMLButtonElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,23 +31,6 @@ void HTMLButtonElement::initialize(JS::Realm& realm)
Base::initialize(realm);
}

void HTMLButtonElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://html.spec.whatwg.org/multipage/rendering.html#button-layout
// If the computed value of 'display' is 'inline-grid', 'grid', 'inline-flex', 'flex', 'none', or 'contents', then behave as the computed value.
auto display = style.display();
if (display.is_flex_inside() || display.is_grid_inside() || display.is_none() || display.is_contents()) {
// No-op
} else if (display.is_inline_outside()) {
// Otherwise, if the computed value of 'display' is a value such that the outer display type is 'inline', then behave as 'inline-block'.
// AD-HOC: See https://github.com/whatwg/html/issues/11857
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::InlineBlock)));
} else {
// Otherwise, behave as 'flow-root'.
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::FlowRoot)));
}
}

HTMLButtonElement::TypeAttributeState HTMLButtonElement::type_state() const
{
auto value = get_attribute_value_view(HTML::AttributeNames::type);
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLButtonElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ class HTMLButtonElement final
virtual ~HTMLButtonElement() override;

virtual void initialize(JS::Realm&) override;
virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;

enum class TypeAttributeState {
#define __ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTE(_, state) state,
ENUMERATE_HTML_BUTTON_TYPE_ATTRIBUTES
Expand Down
7 changes: 0 additions & 7 deletions Libraries/LibWeb/HTML/HTMLCanvasElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,13 +249,6 @@ RefPtr<Layout::Node> HTMLCanvasElement::create_layout_node(NonnullRefPtr<CSS::Co
return make_ref_counted<Layout::CanvasBox>(document(), *this, style);
}

void HTMLCanvasElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://drafts.csswg.org/css-display-3/#unbox
if (style.display().is_contents())
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}

JS::ThrowCompletionOr<HTMLCanvasElement::HasOrCreatedContext> HTMLCanvasElement::create_2d_context(JS::Value options)
{
if (!m_context.has<Empty>())
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLCanvasElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@ class HTMLCanvasElement final : public HTMLElement {
virtual void apply_presentational_hints(Vector<CSS::StyleProperty>&) const override;

virtual RefPtr<Layout::Node> create_layout_node(NonnullRefPtr<CSS::ComputedValues const>) override;
virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;

template<typename ContextType>
JS::ThrowCompletionOr<HasOrCreatedContext> create_webgl_context(JS::Value options);
WebGL::WebGLRenderingContextBase* webgl_context() const;
Expand Down
9 changes: 0 additions & 9 deletions Libraries/LibWeb/HTML/HTMLElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1199,15 +1199,6 @@ void HTMLElement::set_popover(Optional<Utf16String> value)
remove_attribute(HTML::AttributeNames::popover);
}

void HTMLElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://drafts.csswg.org/css-display-3/#unbox
if (local_name() == HTML::TagNames::wbr) {
if (style.display().is_contents())
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}
}

// https://html.spec.whatwg.org/multipage/popover.html#check-popover-validity
// https://whatpr.org/html/9457/popover.html#check-popover-validity
WebIDL::ExceptionOr<bool> HTMLElement::check_popover_validity(ExpectedToBeShowing expected_to_be_showing, ThrowExceptions throw_exceptions, GC::Ptr<DOM::Document> expected_document, IgnoreDomState ignore_dom_state)
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,8 +202,6 @@ class WEB_API HTMLElement

[[nodiscard]] Utf16String get_the_text_steps();

virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;

private:
virtual bool is_html_element() const final { return true; }

Expand Down
7 changes: 0 additions & 7 deletions Libraries/LibWeb/HTML/HTMLEmbedElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,11 +79,4 @@ void HTMLEmbedElement::apply_presentational_hints(Vector<CSS::StyleProperty>& pr
});
}

void HTMLEmbedElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://drafts.csswg.org/css-display-3/#unbox
if (style.display().is_contents())
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}

}
1 change: 0 additions & 1 deletion Libraries/LibWeb/HTML/HTMLEmbedElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ class HTMLEmbedElement final : public HTMLElement {
virtual void initialize(JS::Realm&) override;
virtual bool is_presentational_hint(Utf16FlyString const&) const override;
virtual void apply_presentational_hints(Vector<CSS::StyleProperty>&) const override;
virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;
};

}
Expand Down
7 changes: 0 additions & 7 deletions Libraries/LibWeb/HTML/HTMLFrameElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,6 @@ i32 HTMLFrameElement::default_tab_index_value() const
return 0;
}

void HTMLFrameElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://drafts.csswg.org/css-display-3/#unbox
if (style.display().is_contents())
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}

// https://html.spec.whatwg.org/multipage/obsolete.html#process-the-frame-attributes
void HTMLFrameElement::process_the_frame_attributes(InitialInsertion initial_insertion)
{
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLFrameElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ class WEB_API HTMLFrameElement final : public NavigableContainer {
virtual void removed_from(IsSubtreeRoot, Node* old_ancestor, Node& old_root) override;
virtual void attribute_changed(Utf16FlyString const& name, Optional<Utf16String> const& old_value, Optional<Utf16String> const& value, Optional<Utf16FlyString> const& namespace_) override;
virtual i32 default_tab_index_value() const override;
virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;

void process_the_frame_attributes(InitialInsertion = InitialInsertion::No);
};

Expand Down
7 changes: 0 additions & 7 deletions Libraries/LibWeb/HTML/HTMLFrameSetElement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,6 @@ HTMLFrameSetElement::HTMLFrameSetElement(DOM::Document& document, DOM::Qualified

HTMLFrameSetElement::~HTMLFrameSetElement() = default;

void HTMLFrameSetElement::adjust_computed_style(CSS::ComputedProperties::Builder& style)
{
// https://drafts.csswg.org/css-display-3/#unbox
if (style.display().is_contents())
style.set_property(CSS::PropertyID::Display, CSS::DisplayStyleValue::create(CSS::Display::from_short(CSS::Display::Short::None)));
}

void HTMLFrameSetElement::initialize(JS::Realm& realm)
{
WEB_SET_PROTOTYPE_FOR_INTERFACE(HTMLFrameSetElement);
Expand Down
2 changes: 0 additions & 2 deletions Libraries/LibWeb/HTML/HTMLFrameSetElement.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@ class HTMLFrameSetElement final

virtual bool is_html_frameset_element() const override { return true; }

virtual void adjust_computed_style(CSS::ComputedProperties::Builder&) override;

virtual void initialize(JS::Realm&) override;
virtual void attribute_changed(Utf16FlyString const& name, Optional<Utf16String> const& old_value, Optional<Utf16String> const& value, Optional<Utf16FlyString> const& namespace_) override;

Expand Down
Loading
Loading