mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-02 01:08:48 +00:00
LibWeb: Add textarea placeholder
This commit is contained in:
parent
091faf1aae
commit
52397d01bd
Notes:
sideshowbarker
2024-07-17 01:28:15 +09:00
Author: https://github.com/bplaat
Commit: 52397d01bd
Pull-request: https://github.com/SerenityOS/serenity/pull/22243
Reviewed-by: https://github.com/kalenikaliaksandr
Reviewed-by: https://github.com/shannonbooth
6 changed files with 85 additions and 33 deletions
|
@ -47,6 +47,8 @@ void HTMLTextAreaElement::initialize(JS::Realm& realm)
|
|||
void HTMLTextAreaElement::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_placeholder_element);
|
||||
visitor.visit(m_placeholder_text_node);
|
||||
visitor.visit(m_inner_text_element);
|
||||
visitor.visit(m_text_node);
|
||||
}
|
||||
|
@ -86,6 +88,8 @@ void HTMLTextAreaElement::reset_algorithm()
|
|||
m_dirty = false;
|
||||
// and set the raw value of element to its child text content.
|
||||
m_raw_value = child_text_content();
|
||||
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
void HTMLTextAreaElement::form_associated_element_was_inserted()
|
||||
|
@ -181,9 +185,22 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed()
|
|||
return;
|
||||
|
||||
auto shadow_root = heap().allocate<DOM::ShadowRoot>(realm(), document(), *this, Bindings::ShadowRootMode::Closed);
|
||||
set_shadow_root(shadow_root);
|
||||
|
||||
auto element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
||||
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::Selector::PseudoElement::Type::Placeholder);
|
||||
MUST(element->append_child(*m_placeholder_element));
|
||||
|
||||
m_placeholder_text_node = heap().allocate<DOM::Text>(realm(), document(), String {});
|
||||
m_placeholder_text_node->set_data(get_attribute(HTML::AttributeNames::placeholder).value_or(String {}));
|
||||
m_placeholder_text_node->set_editable_text_node_owner(Badge<HTMLTextAreaElement> {}, *this);
|
||||
MUST(m_placeholder_element->append_child(*m_placeholder_text_node));
|
||||
|
||||
m_inner_text_element = MUST(DOM::create_element(document(), HTML::TagNames::div, Namespace::HTML));
|
||||
MUST(element->append_child(*m_inner_text_element));
|
||||
|
||||
m_text_node = heap().allocate<DOM::Text>(realm(), document(), String {});
|
||||
m_text_node->set_always_editable(true);
|
||||
|
@ -191,11 +208,23 @@ void HTMLTextAreaElement::create_shadow_tree_if_needed()
|
|||
// NOTE: If `children_changed()` was called before now, `m_raw_value` will hold the text content.
|
||||
// Otherwise, it will get filled in whenever that does get called.
|
||||
m_text_node->set_text_content(m_raw_value);
|
||||
|
||||
MUST(m_inner_text_element->append_child(*m_text_node));
|
||||
MUST(element->append_child(*m_inner_text_element));
|
||||
MUST(shadow_root->append_child(element));
|
||||
set_shadow_root(shadow_root);
|
||||
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
void HTMLTextAreaElement::update_placeholder_visibility()
|
||||
{
|
||||
if (!m_placeholder_element)
|
||||
return;
|
||||
if (!m_text_node)
|
||||
return;
|
||||
auto placeholder_text = get_attribute(AttributeNames::placeholder);
|
||||
if (placeholder_text.has_value() && m_text_node->data().is_empty()) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element:children-changed-steps
|
||||
|
@ -207,6 +236,16 @@ void HTMLTextAreaElement::children_changed()
|
|||
m_raw_value = child_text_content();
|
||||
if (m_text_node)
|
||||
m_text_node->set_text_content(m_raw_value);
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
}
|
||||
|
||||
void HTMLTextAreaElement::attribute_changed(FlyString const& name, Optional<String> const& value)
|
||||
{
|
||||
HTMLElement::attribute_changed(name, value);
|
||||
if (name == HTML::AttributeNames::placeholder) {
|
||||
if (m_placeholder_text_node)
|
||||
m_placeholder_text_node->set_data(value.value_or(String {}));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,6 +253,8 @@ void HTMLTextAreaElement::did_edit_text_node(Badge<Web::HTML::BrowsingContext>)
|
|||
{
|
||||
// A textarea element's dirty value flag must be set to true whenever the user interacts with the control in a way that changes the raw value.
|
||||
m_dirty = true;
|
||||
|
||||
update_placeholder_visibility();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue