diff --git a/Libraries/LibWeb/DOM/Element.cpp b/Libraries/LibWeb/DOM/Element.cpp index 6782f0c8176..cf830055967 100644 --- a/Libraries/LibWeb/DOM/Element.cpp +++ b/Libraries/LibWeb/DOM/Element.cpp @@ -925,6 +925,12 @@ GC::Ref Element::style_for_bindings() return *m_inline_style; } +void Element::set_inline_style(GC::Ptr style) +{ + m_inline_style = style; + set_needs_style_update(true); +} + // https://dom.spec.whatwg.org/#element-html-uppercased-qualified-name void Element::make_html_uppercased_qualified_name() { diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h index fb4494cb14a..3bb562ed201 100644 --- a/Libraries/LibWeb/DOM/Element.h +++ b/Libraries/LibWeb/DOM/Element.h @@ -213,6 +213,7 @@ public: GC::Ptr inline_style() { return m_inline_style; } GC::Ptr inline_style() const { return m_inline_style; } + void set_inline_style(GC::Ptr); GC::Ref style_for_bindings(); diff --git a/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 2d7e159a214..bff078f009d 100644 --- a/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2023, Andreas Kling + * Copyright (c) 2018-2025, Andreas Kling * Copyright (c) 2022, Adam Hodgen * Copyright (c) 2022, Andrew Kaster * Copyright (c) 2023-2025, Shannon Booth @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -744,15 +745,40 @@ void HTMLInputElement::commit_pending_changes() dispatch_event(change_event); } +static GC::Ref placeholder_style_when_visible() +{ + static GC::Root style; + if (!style) { + style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); + style->set_declarations_from_text(R"~~~( + width: 100%; + align-items: center; + text-overflow: clip; + white-space: nowrap; + display: block; + )~~~"sv); + } + return *style; +} + +static GC::Ref placeholder_style_when_hidden() +{ + static GC::Root style; + if (!style) { + style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); + style->set_declarations_from_text("display: none;"sv); + } + return *style; +} + void HTMLInputElement::update_placeholder_visibility() { if (!m_placeholder_element) return; - if (this->placeholder_value().has_value()) { - MUST(m_placeholder_element->style_for_bindings()->set_property(CSS::PropertyID::Display, "block"sv)); - } else { - MUST(m_placeholder_element->style_for_bindings()->set_property(CSS::PropertyID::Display, "none"sv)); - } + if (this->placeholder_value().has_value()) + m_placeholder_element->set_inline_style(placeholder_style_when_visible()); + else + m_placeholder_element->set_inline_style(placeholder_style_when_hidden()); } void HTMLInputElement::update_button_input_shadow_tree() @@ -989,26 +1015,27 @@ void HTMLInputElement::create_text_input_shadow_tree() auto initial_value = m_value; auto element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML)); - MUST(element->set_attribute(HTML::AttributeNames::style, R"~~~( - display: flex; - height: 100%; - align-items: center; - white-space: pre; - border: none; - padding: 1px 2px; - )~~~"_string)); + { + static GC::Root style; + if (!style) { + style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); + style->set_declarations_from_text(R"~~~( + display: flex; + height: 100%; + align-items: center; + white-space: pre; + border: none; + padding: 1px 2px; + )~~~"sv); + } + element->set_inline_style(*style); + } MUST(shadow_root->append_child(element)); m_placeholder_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML)); m_placeholder_element->set_use_pseudo_element(CSS::PseudoElement::Placeholder); + update_placeholder_visibility(); - // https://www.w3.org/TR/css-ui-4/#input-rules - MUST(m_placeholder_element->set_attribute(HTML::AttributeNames::style, R"~~~( - width: 100%; - align-items: center; - text-overflow: clip; - white-space: nowrap; - )~~~"_string)); MUST(element->append_child(*m_placeholder_element)); m_placeholder_text_node = realm().create(document(), String {}); @@ -1017,13 +1044,20 @@ void HTMLInputElement::create_text_input_shadow_tree() // https://www.w3.org/TR/css-ui-4/#input-rules m_inner_text_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML)); - MUST(m_inner_text_element->set_attribute(HTML::AttributeNames::style, R"~~~( - width: 100%; - height: 1lh; - align-items: center; - text-overflow: clip; - white-space: nowrap; - )~~~"_string)); + { + static GC::Root style; + if (!style) { + style = CSS::CSSStyleProperties::create(internal_css_realm(), {}, {}); + style->set_declarations_from_text(R"~~~( + width: 100%; + height: 1lh; + align-items: center; + text-overflow: clip; + white-space: nowrap; + )~~~"sv); + } + m_inner_text_element->set_inline_style(*style); + } MUST(element->append_child(*m_inner_text_element)); m_text_node = realm().create(document(), move(initial_value));