mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 17:42:43 +00:00 
			
		
		
		
	 9303e9e76f
			
		
	
	
		9303e9e76f
		
	
	
	
	
		
			
			Which pretty much needs to be done together due to the amount of places where they are compared together. This also involves porting over StackOfOpenElements over to FlyString from DeprecatedFly string to prevent a gazillion calls to `.to_deprecated_fly_string` calls in HTMLParser.
		
			
				
	
	
		
			90 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2020-2022, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include <LibWeb/DOM/Element.h>
 | |
| #include <LibWeb/HTML/Parser/ListOfActiveFormattingElements.h>
 | |
| 
 | |
| namespace Web::HTML {
 | |
| 
 | |
| ListOfActiveFormattingElements::~ListOfActiveFormattingElements() = default;
 | |
| 
 | |
| void ListOfActiveFormattingElements::visit_edges(JS::Cell::Visitor& visitor)
 | |
| {
 | |
|     for (auto& entry : m_entries)
 | |
|         visitor.visit(entry.element);
 | |
| }
 | |
| 
 | |
| void ListOfActiveFormattingElements::add(DOM::Element& element)
 | |
| {
 | |
|     // FIXME: Implement the Noah's Ark clause https://html.spec.whatwg.org/multipage/parsing.html#push-onto-the-list-of-active-formatting-elements
 | |
|     m_entries.append({ element });
 | |
| }
 | |
| 
 | |
| void ListOfActiveFormattingElements::add_marker()
 | |
| {
 | |
|     m_entries.append({ nullptr });
 | |
| }
 | |
| 
 | |
| bool ListOfActiveFormattingElements::contains(const DOM::Element& element) const
 | |
| {
 | |
|     for (auto& entry : m_entries) {
 | |
|         if (entry.element.ptr() == &element)
 | |
|             return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| DOM::Element* ListOfActiveFormattingElements::last_element_with_tag_name_before_marker(FlyString const& tag_name)
 | |
| {
 | |
|     for (ssize_t i = m_entries.size() - 1; i >= 0; --i) {
 | |
|         auto& entry = m_entries[i];
 | |
|         if (entry.is_marker())
 | |
|             return nullptr;
 | |
|         if (entry.element->local_name() == tag_name)
 | |
|             return entry.element.ptr();
 | |
|     }
 | |
|     return nullptr;
 | |
| }
 | |
| 
 | |
| void ListOfActiveFormattingElements::remove(DOM::Element& element)
 | |
| {
 | |
|     m_entries.remove_first_matching([&](auto& entry) {
 | |
|         return entry.element.ptr() == &element;
 | |
|     });
 | |
| }
 | |
| 
 | |
| void ListOfActiveFormattingElements::clear_up_to_the_last_marker()
 | |
| {
 | |
|     while (!m_entries.is_empty()) {
 | |
|         auto entry = m_entries.take_last();
 | |
|         if (entry.is_marker())
 | |
|             break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| Optional<size_t> ListOfActiveFormattingElements::find_index(DOM::Element const& element) const
 | |
| {
 | |
|     for (size_t i = 0; i < m_entries.size(); i++) {
 | |
|         if (m_entries[i].element.ptr() == &element)
 | |
|             return i;
 | |
|     }
 | |
|     return {};
 | |
| }
 | |
| 
 | |
| void ListOfActiveFormattingElements::replace(DOM::Element& to_remove, DOM::Element& to_add)
 | |
| {
 | |
|     for (size_t i = 0; i < m_entries.size(); i++) {
 | |
|         if (m_entries[i].element.ptr() == &to_remove)
 | |
|             m_entries[i].element = JS::make_handle(to_add);
 | |
|     }
 | |
| }
 | |
| 
 | |
| void ListOfActiveFormattingElements::insert_at(size_t index, DOM::Element& element)
 | |
| {
 | |
|     m_entries.insert(index, { element });
 | |
| }
 | |
| 
 | |
| }
 |