mirror of
				https://github.com/LadybirdBrowser/ladybird.git
				synced 2025-10-31 21:30:58 +00:00 
			
		
		
		
	LibWeb: Keep track of the order in which option elements are selected
This allows us to locate the most-recently-selected when running the selectedness update algorithm.
This commit is contained in:
		
							parent
							
								
									581597cb34
								
							
						
					
					
						commit
						dc9179bb1b
					
				
				
				Notes:
				
					github-actions[bot]
				
				2024-11-14 22:07:21 +00:00 
				
			
			Author: https://github.com/awesomekling
Commit: dc9179bb1b
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/2348
			
					 10 changed files with 107 additions and 27 deletions
				
			
		|  | @ -1,6 +1,6 @@ | |||
| /*
 | ||||
|  * Copyright (c) 2020, the SerenityOS developers. | ||||
|  * Copyright (c) 2022, Andreas Kling <andreas@ladybird.org> | ||||
|  * Copyright (c) 2022-2024, Andreas Kling <andreas@ladybird.org> | ||||
|  * | ||||
|  * SPDX-License-Identifier: BSD-2-Clause | ||||
|  */ | ||||
|  | @ -15,12 +15,15 @@ | |||
| #include <LibWeb/HTML/HTMLOptionElement.h> | ||||
| #include <LibWeb/HTML/HTMLScriptElement.h> | ||||
| #include <LibWeb/HTML/HTMLSelectElement.h> | ||||
| #include <LibWeb/HighResolutionTime/TimeOrigin.h> | ||||
| #include <LibWeb/Infra/Strings.h> | ||||
| 
 | ||||
| namespace Web::HTML { | ||||
| 
 | ||||
| JS_DEFINE_ALLOCATOR(HTMLOptionElement); | ||||
| 
 | ||||
| static u64 m_next_selectedness_update_index = 1; | ||||
| 
 | ||||
| HTMLOptionElement::HTMLOptionElement(DOM::Document& document, DOM::QualifiedName qualified_name) | ||||
|     : HTMLElement(document, move(qualified_name)) | ||||
| { | ||||
|  | @ -42,13 +45,13 @@ void HTMLOptionElement::attribute_changed(FlyString const& name, Optional<String | |||
|         if (!value.has_value()) { | ||||
|             // Whenever an option element's selected attribute is removed, if its dirtiness is false, its selectedness must be set to false.
 | ||||
|             if (!m_dirty) | ||||
|                 m_selected = false; | ||||
|                 set_selected_internal(false); | ||||
|         } else { | ||||
|             // Except where otherwise specified, when the element is created, its selectedness must be set to true
 | ||||
|             // if the element has a selected attribute. Whenever an option element's selected attribute is added,
 | ||||
|             // if its dirtiness is false, its selectedness must be set to true.
 | ||||
|             if (!m_dirty) | ||||
|                 m_selected = true; | ||||
|                 set_selected_internal(true); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | @ -65,6 +68,8 @@ void HTMLOptionElement::set_selected(bool selected) | |||
| void HTMLOptionElement::set_selected_internal(bool selected) | ||||
| { | ||||
|     m_selected = selected; | ||||
|     if (selected) | ||||
|         m_selectedness_update_index = m_next_selectedness_update_index++; | ||||
| } | ||||
| 
 | ||||
| // https://html.spec.whatwg.org/multipage/form-elements.html#dom-option-value
 | ||||
|  | @ -139,7 +144,7 @@ void HTMLOptionElement::ask_for_a_reset() | |||
| { | ||||
|     // If an option element in the list of options asks for a reset, then run that select element's selectedness setting algorithm.
 | ||||
|     if (auto* select = first_ancestor_of_type<HTMLSelectElement>()) { | ||||
|         select->update_selectedness(this); | ||||
|         select->update_selectedness(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -177,4 +182,35 @@ Optional<ARIA::Role> HTMLOptionElement::default_role() const | |||
|     return ARIA::Role::option; | ||||
| } | ||||
| 
 | ||||
| void HTMLOptionElement::inserted() | ||||
| { | ||||
|     Base::inserted(); | ||||
| 
 | ||||
|     set_selected_internal(selected()); | ||||
| 
 | ||||
|     // 1. The option HTML element insertion steps, given insertedNode, are:
 | ||||
|     //    If insertedNode's parent is a select element,
 | ||||
|     //    or insertedNode's parent is an optgroup element whose parent is a select element,
 | ||||
|     //    then run that select element's selectedness setting algorithm.
 | ||||
|     if (is<HTMLSelectElement>(*parent())) | ||||
|         static_cast<HTMLSelectElement&>(*parent()).update_selectedness(); | ||||
|     else if (is<HTMLOptGroupElement>(parent()) && parent()->parent() && is<HTMLSelectElement>(*parent()->parent())) | ||||
|         static_cast<HTMLSelectElement&>(*parent()->parent()).update_selectedness(); | ||||
| } | ||||
| 
 | ||||
| void HTMLOptionElement::removed_from(Node* old_parent) | ||||
| { | ||||
|     Base::removed_from(old_parent); | ||||
| 
 | ||||
|     // The option HTML element removing steps, given removedNode and oldParent, are:
 | ||||
|     // 1. If oldParent is a select element, or oldParent is an optgroup element whose parent is a select element,
 | ||||
|     //    then run that select element's selectedness setting algorithm.
 | ||||
|     if (old_parent) { | ||||
|         if (is<HTMLSelectElement>(*old_parent)) | ||||
|             static_cast<HTMLSelectElement&>(*old_parent).update_selectedness(); | ||||
|         else if (is<HTMLOptGroupElement>(*old_parent) && old_parent->parent_element() && is<HTMLSelectElement>(old_parent->parent_element())) | ||||
|             static_cast<HTMLSelectElement&>(*old_parent->parent_element()).update_selectedness(); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| } | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling