mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 07:02:44 +00:00 
			
		
		
		
	LibWeb: Allow non-HTMLInputElements to have did_edit_text_node() called
HTMLTextAreaElement also needs to be told when its contained text node has been edited, so let's make this functionality work for anyone who extends the new EditableTextNodeOwner interface class.
This commit is contained in:
		
							parent
							
								
									ce556c9566
								
							
						
					
					
						commit
						4897643ffb
					
				
					 5 changed files with 22 additions and 18 deletions
				
			
		|  | @ -7,7 +7,6 @@ | |||
| #include <LibWeb/Bindings/Intrinsics.h> | ||||
| #include <LibWeb/DOM/Range.h> | ||||
| #include <LibWeb/DOM/Text.h> | ||||
| #include <LibWeb/HTML/HTMLInputElement.h> | ||||
| #include <LibWeb/HTML/Scripting/Environments.h> | ||||
| #include <LibWeb/HTML/Window.h> | ||||
| #include <LibWeb/Layout/TextNode.h> | ||||
|  | @ -33,7 +32,7 @@ void Text::initialize(JS::Realm& realm) | |||
| void Text::visit_edges(Cell::Visitor& visitor) | ||||
| { | ||||
|     Base::visit_edges(visitor); | ||||
|     visitor.visit(m_owner_input_element.ptr()); | ||||
|     visitor.visit(dynamic_cast<JS::Cell*>(m_owner.ptr())); | ||||
| } | ||||
| 
 | ||||
| // https://dom.spec.whatwg.org/#dom-text-text
 | ||||
|  | @ -44,11 +43,6 @@ WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> Text::construct_impl(JS::Realm& real | |||
|     return realm.heap().allocate<Text>(realm, window.associated_document(), data); | ||||
| } | ||||
| 
 | ||||
| void Text::set_owner_input_element(Badge<HTML::HTMLInputElement>, HTML::HTMLInputElement& input_element) | ||||
| { | ||||
|     m_owner_input_element = &input_element; | ||||
| } | ||||
| 
 | ||||
| // https://dom.spec.whatwg.org/#dom-text-splittext
 | ||||
| // https://dom.spec.whatwg.org/#concept-text-split
 | ||||
| WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> Text::split_text(size_t offset) | ||||
|  |  | |||
|  | @ -1,5 +1,6 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org> | ||||
|  * Copyright (c) 2023, Sam Atkins <atkinssj@serenityos.org> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
|  | @ -12,6 +13,12 @@ | |||
| 
 | ||||
| namespace Web::DOM { | ||||
| 
 | ||||
| class EditableTextNodeOwner { | ||||
| public: | ||||
|     virtual ~EditableTextNodeOwner() = default; | ||||
|     virtual void did_edit_text_node(Badge<HTML::BrowsingContext>) = 0; | ||||
| }; | ||||
| 
 | ||||
| class Text : public CharacterData { | ||||
|     WEB_PLATFORM_OBJECT(Text, CharacterData); | ||||
| 
 | ||||
|  | @ -26,8 +33,9 @@ public: | |||
| 
 | ||||
|     void set_always_editable(bool b) { m_always_editable = b; } | ||||
| 
 | ||||
|     void set_owner_input_element(Badge<HTML::HTMLInputElement>, HTML::HTMLInputElement&); | ||||
|     HTML::HTMLInputElement* owner_input_element() { return m_owner_input_element.ptr(); } | ||||
|     template<DerivedFrom<EditableTextNodeOwner> T> | ||||
|     void set_editable_text_node_owner(Badge<T>, EditableTextNodeOwner& owner_element) { m_owner = &owner_element; } | ||||
|     EditableTextNodeOwner* editable_text_node_owner() { return m_owner.ptr(); } | ||||
| 
 | ||||
|     WebIDL::ExceptionOr<JS::NonnullGCPtr<Text>> split_text(size_t offset); | ||||
| 
 | ||||
|  | @ -42,7 +50,7 @@ protected: | |||
|     virtual void visit_edges(Cell::Visitor&) override; | ||||
| 
 | ||||
| private: | ||||
|     JS::GCPtr<HTML::HTMLInputElement> m_owner_input_element; | ||||
|     JS::GCPtr<EditableTextNodeOwner> m_owner; | ||||
| 
 | ||||
|     bool m_always_editable { false }; | ||||
|     bool m_is_password_input { false }; | ||||
|  |  | |||
|  | @ -483,8 +483,8 @@ void BrowsingContext::did_edit(Badge<EditEventHandler>) | |||
| 
 | ||||
|     if (m_cursor_position.node() && is<DOM::Text>(*m_cursor_position.node())) { | ||||
|         auto& text_node = static_cast<DOM::Text&>(*m_cursor_position.node()); | ||||
|         if (auto* input_element = text_node.owner_input_element()) | ||||
|             input_element->did_edit_text_node({}); | ||||
|         if (auto* text_node_owner = text_node.editable_text_node_owner()) | ||||
|             text_node_owner->did_edit_text_node({}); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,7 +13,6 @@ | |||
| #include <LibWeb/DOM/ElementFactory.h> | ||||
| #include <LibWeb/DOM/Event.h> | ||||
| #include <LibWeb/DOM/ShadowRoot.h> | ||||
| #include <LibWeb/DOM/Text.h> | ||||
| #include <LibWeb/HTML/BrowsingContext.h> | ||||
| #include <LibWeb/HTML/EventNames.h> | ||||
| #include <LibWeb/HTML/HTMLDivElement.h> | ||||
|  | @ -504,7 +503,7 @@ void HTMLInputElement::create_shadow_tree_if_needed() | |||
| 
 | ||||
|     m_placeholder_text_node = heap().allocate<DOM::Text>(realm(), document(), MUST(String::from_deprecated_string(initial_value))); | ||||
|     m_placeholder_text_node->set_data(deprecated_attribute(HTML::AttributeNames::placeholder)); | ||||
|     m_placeholder_text_node->set_owner_input_element({}, *this); | ||||
|     m_placeholder_text_node->set_editable_text_node_owner(Badge<HTMLInputElement> {}, *this); | ||||
|     MUST(m_placeholder_element->append_child(*m_placeholder_text_node)); | ||||
|     MUST(element->append_child(*m_placeholder_element)); | ||||
| 
 | ||||
|  | @ -519,7 +518,7 @@ void HTMLInputElement::create_shadow_tree_if_needed() | |||
|         handle_readonly_attribute(deprecated_attribute(HTML::AttributeNames::readonly)); | ||||
|     } | ||||
| 
 | ||||
|     m_text_node->set_owner_input_element({}, *this); | ||||
|     m_text_node->set_editable_text_node_owner(Badge<HTMLInputElement> {}, *this); | ||||
| 
 | ||||
|     if (m_type == TypeAttributeState::Password) | ||||
|         m_text_node->set_is_password_input({}, true); | ||||
|  |  | |||
|  | @ -7,6 +7,7 @@ | |||
| 
 | ||||
| #pragma once | ||||
| 
 | ||||
| #include <LibWeb/DOM/Text.h> | ||||
| #include <LibWeb/FileAPI/FileList.h> | ||||
| #include <LibWeb/HTML/FormAssociatedElement.h> | ||||
| #include <LibWeb/HTML/HTMLElement.h> | ||||
|  | @ -41,7 +42,8 @@ namespace Web::HTML { | |||
| 
 | ||||
| class HTMLInputElement final | ||||
|     : public HTMLElement | ||||
|     , public FormAssociatedElement { | ||||
|     , public FormAssociatedElement | ||||
|     , public DOM::EditableTextNodeOwner { | ||||
|     WEB_PLATFORM_OBJECT(HTMLInputElement, HTMLElement); | ||||
|     FORM_ASSOCIATED_ELEMENT(HTMLElement, HTMLInputElement) | ||||
| 
 | ||||
|  | @ -83,8 +85,6 @@ public: | |||
| 
 | ||||
|     bool is_mutable() const { return m_is_mutable; } | ||||
| 
 | ||||
|     void did_edit_text_node(Badge<BrowsingContext>); | ||||
| 
 | ||||
|     JS::GCPtr<FileAPI::FileList> files(); | ||||
|     void set_files(JS::GCPtr<FileAPI::FileList>); | ||||
| 
 | ||||
|  | @ -101,6 +101,9 @@ public: | |||
| 
 | ||||
|     WebIDL::ExceptionOr<void> show_picker(); | ||||
| 
 | ||||
|     // ^DOM::EditableTextNodeOwner
 | ||||
|     virtual void did_edit_text_node(Badge<BrowsingContext>) override; | ||||
| 
 | ||||
|     // ^EventTarget
 | ||||
|     // https://html.spec.whatwg.org/multipage/interaction.html#the-tabindex-attribute:the-input-element
 | ||||
|     virtual bool is_focusable() const override { return m_type != TypeAttributeState::Hidden; } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sam Atkins
						Sam Atkins