| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2022-10-17 10:46:11 +02:00
										 |  |  |  * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org> | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  |  * | 
					
						
							| 
									
										
										
										
											2021-04-22 01:24:48 -07:00
										 |  |  |  * SPDX-License-Identifier: BSD-2-Clause | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  |  */ | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #include <LibWeb/DOM/Element.h>
 | 
					
						
							| 
									
										
										
										
											2020-07-28 19:18:23 +02:00
										 |  |  | #include <LibWeb/HTML/Parser/ListOfActiveFormattingElements.h>
 | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-28 18:20:36 +02:00
										 |  |  | namespace Web::HTML { | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-14 13:21:51 -06:00
										 |  |  | ListOfActiveFormattingElements::~ListOfActiveFormattingElements() = default; | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-10-17 10:46:11 +02:00
										 |  |  | void ListOfActiveFormattingElements::visit_edges(JS::Cell::Visitor& visitor) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (auto& entry : m_entries) | 
					
						
							|  |  |  |         visitor.visit(entry.element); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 |  |  | void ListOfActiveFormattingElements::add(DOM::Element& element) | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2020-10-12 01:51:28 +01:00
										 |  |  |     // FIXME: Implement the Noah's Ark clause https://html.spec.whatwg.org/multipage/parsing.html#push-onto-the-list-of-active-formatting-elements
 | 
					
						
							| 
									
										
										
										
											2022-10-17 10:46:11 +02:00
										 |  |  |     m_entries.append({ element }); | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ListOfActiveFormattingElements::add_marker() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-10-17 10:46:11 +02:00
										 |  |  |     m_entries.append({ nullptr }); | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 |  |  | bool ListOfActiveFormattingElements::contains(const DOM::Element& element) const | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     for (auto& entry : m_entries) { | 
					
						
							| 
									
										
										
										
											2022-08-28 13:42:07 +02:00
										 |  |  |         if (entry.element.ptr() == &element) | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  |             return true; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return false; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-10-01 20:07:44 +13:00
										 |  |  | DOM::Element* ListOfActiveFormattingElements::last_element_with_tag_name_before_marker(FlyString const& tag_name) | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     for (ssize_t i = m_entries.size() - 1; i >= 0; --i) { | 
					
						
							|  |  |  |         auto& entry = m_entries[i]; | 
					
						
							|  |  |  |         if (entry.is_marker()) | 
					
						
							|  |  |  |             return nullptr; | 
					
						
							| 
									
										
										
										
											2020-07-23 18:18:13 +02:00
										 |  |  |         if (entry.element->local_name() == tag_name) | 
					
						
							| 
									
										
										
										
											2022-08-28 13:42:07 +02:00
										 |  |  |             return entry.element.ptr(); | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  |     } | 
					
						
							|  |  |  |     return nullptr; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-07-26 19:37:56 +02:00
										 |  |  | void ListOfActiveFormattingElements::remove(DOM::Element& element) | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | { | 
					
						
							|  |  |  |     m_entries.remove_first_matching([&](auto& entry) { | 
					
						
							| 
									
										
										
										
											2022-08-28 13:42:07 +02:00
										 |  |  |         return entry.element.ptr() == &element; | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  |     }); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-28 00:27:46 +02:00
										 |  |  | void ListOfActiveFormattingElements::clear_up_to_the_last_marker() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     while (!m_entries.is_empty()) { | 
					
						
							|  |  |  |         auto entry = m_entries.take_last(); | 
					
						
							|  |  |  |         if (entry.is_marker()) | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-03-20 02:11:42 +01:00
										 |  |  | Optional<size_t> ListOfActiveFormattingElements::find_index(DOM::Element const& element) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (size_t i = 0; i < m_entries.size(); i++) { | 
					
						
							| 
									
										
										
										
											2022-08-28 13:42:07 +02:00
										 |  |  |         if (m_entries[i].element.ptr() == &element) | 
					
						
							| 
									
										
										
										
											2022-03-20 02:11:42 +01:00
										 |  |  |             return i; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return {}; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ListOfActiveFormattingElements::replace(DOM::Element& to_remove, DOM::Element& to_add) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     for (size_t i = 0; i < m_entries.size(); i++) { | 
					
						
							| 
									
										
										
										
											2022-08-28 13:42:07 +02:00
										 |  |  |         if (m_entries[i].element.ptr() == &to_remove) | 
					
						
							|  |  |  |             m_entries[i].element = JS::make_handle(to_add); | 
					
						
							| 
									
										
										
										
											2022-03-20 02:11:42 +01:00
										 |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void ListOfActiveFormattingElements::insert_at(size_t index, DOM::Element& element) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2022-10-17 10:46:11 +02:00
										 |  |  |     m_entries.insert(index, { element }); | 
					
						
							| 
									
										
										
										
											2022-03-20 02:11:42 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-05-27 23:22:42 +02:00
										 |  |  | } |