diff options
author | Andreas Kling <kling@serenityos.org> | 2022-08-28 13:42:07 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2022-09-06 00:27:09 +0200 |
commit | 6f433c86564c24d47d520cb5bdcc2209d724ac96 (patch) | |
tree | 886a2f727782e466e99c61c628637872c1b7403f /Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp | |
parent | bb547ce1c4251e3689287eac845593398a379ca5 (diff) | |
download | serenity-6f433c86564c24d47d520cb5bdcc2209d724ac96.zip |
LibWeb+LibJS: Make the EventTarget hierarchy (incl. DOM) GC-allocated
This is a monster patch that turns all EventTargets into GC-allocated
PlatformObjects. Their C++ wrapper classes are removed, and the LibJS
garbage collector is now responsible for their lifetimes.
There's a fair amount of hacks and band-aids in this patch, and we'll
have a lot of cleanup to do after this.
Diffstat (limited to 'Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp')
-rw-r--r-- | Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp index 66557d5cae..4ca7cc2f05 100644 --- a/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp +++ b/Userland/Libraries/LibWeb/HTML/HTMLInputElement.cpp @@ -5,6 +5,7 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <LibWeb/Bindings/HTMLInputElementPrototype.h> #include <LibWeb/DOM/Document.h> #include <LibWeb/DOM/Event.h> #include <LibWeb/DOM/ShadowRoot.h> @@ -24,6 +25,8 @@ HTMLInputElement::HTMLInputElement(DOM::Document& document, DOM::QualifiedName q : HTMLElement(document, move(qualified_name)) , m_value(String::empty()) { + set_prototype(&window().ensure_web_prototype<Bindings::HTMLInputElementPrototype>("HTMLInputElement")); + activation_behavior = [this](auto&) { // The activation behavior for input elements are these steps: @@ -36,6 +39,13 @@ HTMLInputElement::HTMLInputElement(DOM::Document& document, DOM::QualifiedName q HTMLInputElement::~HTMLInputElement() = default; +void HTMLInputElement::visit_edges(Cell::Visitor& visitor) +{ + Base::visit_edges(visitor); + visitor.visit(m_text_node.ptr()); + visitor.visit(m_legacy_pre_activation_behavior_checked_element_in_group.ptr()); +} + RefPtr<Layout::Node> HTMLInputElement::create_layout_node(NonnullRefPtr<CSS::StyleProperties> style) { if (type_state() == TypeAttributeState::Hidden) @@ -90,17 +100,17 @@ void HTMLInputElement::run_input_activation_behavior() return; // 2. Fire an event named input at the element with the bubbles and composed attributes initialized to true. - auto input_event = DOM::Event::create(document().preferred_window_object(), HTML::EventNames::input); + auto input_event = DOM::Event::create(document().window(), HTML::EventNames::input); input_event->set_bubbles(true); input_event->set_composed(true); dispatch_event(*input_event); // 3. Fire an event named change at the element with the bubbles attribute initialized to true. - auto change_event = DOM::Event::create(document().preferred_window_object(), HTML::EventNames::change); + auto change_event = DOM::Event::create(document().window(), HTML::EventNames::change); change_event->set_bubbles(true); dispatch_event(*change_event); } else if (type_state() == TypeAttributeState::SubmitButton) { - RefPtr<HTMLFormElement> form; + JS::GCPtr<HTMLFormElement> form; // 1. If the element does not have a form owner, then return. if (!(form = this->form())) return; @@ -112,7 +122,7 @@ void HTMLInputElement::run_input_activation_behavior() // 3. Submit the form owner from the element. form->submit_form(this); } else { - dispatch_event(*DOM::Event::create(document().preferred_window_object(), EventNames::change)); + dispatch_event(*DOM::Event::create(document().window(), EventNames::change)); } } @@ -125,13 +135,13 @@ void HTMLInputElement::did_edit_text_node(Badge<BrowsingContext>) // NOTE: This is a bit ad-hoc, but basically implements part of "4.10.5.5 Common event behaviors" // https://html.spec.whatwg.org/multipage/input.html#common-input-element-events queue_an_element_task(HTML::Task::Source::UserInteraction, [this] { - auto input_event = DOM::Event::create(document().preferred_window_object(), HTML::EventNames::input); + auto input_event = DOM::Event::create(document().window(), HTML::EventNames::input); input_event->set_bubbles(true); input_event->set_composed(true); dispatch_event(*input_event); // FIXME: This should only fire when the input is "committed", whatever that means. - auto change_event = DOM::Event::create(document().preferred_window_object(), HTML::EventNames::change); + auto change_event = DOM::Event::create(document().window(), HTML::EventNames::change); change_event->set_bubbles(true); dispatch_event(*change_event); }); @@ -184,13 +194,13 @@ void HTMLInputElement::create_shadow_tree_if_needed() break; } - auto shadow_root = adopt_ref(*new DOM::ShadowRoot(document(), *this)); + auto* shadow_root = heap().allocate<DOM::ShadowRoot>(realm(), document(), *this); auto initial_value = m_value; if (initial_value.is_null()) initial_value = String::empty(); auto element = document().create_element(HTML::TagNames::div).release_value(); element->set_attribute(HTML::AttributeNames::style, "white-space: pre; padding-top: 1px; padding-bottom: 1px; padding-left: 2px; padding-right: 2px"); - m_text_node = adopt_ref(*new DOM::Text(document(), initial_value)); + m_text_node = heap().allocate<DOM::Text>(realm(), document(), initial_value); m_text_node->set_always_editable(true); m_text_node->set_owner_input_element({}, *this); element->append_child(*m_text_node); @@ -348,7 +358,7 @@ void HTMLInputElement::legacy_pre_activation_behavior() document().for_each_in_inclusive_subtree_of_type<HTML::HTMLInputElement>([&](auto& element) { if (element.checked() && element.name() == name) { - m_legacy_pre_activation_behavior_checked_element_in_group = element; + m_legacy_pre_activation_behavior_checked_element_in_group = &element; return IterationDecision::Break; } return IterationDecision::Continue; |