mirror of
https://github.com/RGBCube/serenity
synced 2025-05-23 18:55:08 +00:00
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.
This commit is contained in:
parent
bb547ce1c4
commit
6f433c8656
445 changed files with 4797 additions and 4268 deletions
|
@ -17,9 +17,9 @@ StackOfOpenElements::~StackOfOpenElements() = default;
|
|||
bool StackOfOpenElements::has_in_scope_impl(FlyString const& tag_name, Vector<FlyString> const& list) const
|
||||
{
|
||||
for (auto const& element : m_elements.in_reverse()) {
|
||||
if (element.local_name() == tag_name)
|
||||
if (element->local_name() == tag_name)
|
||||
return true;
|
||||
if (list.contains_slow(element.local_name()))
|
||||
if (list.contains_slow(element->local_name()))
|
||||
return false;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -33,9 +33,9 @@ bool StackOfOpenElements::has_in_scope(FlyString const& tag_name) const
|
|||
bool StackOfOpenElements::has_in_scope_impl(const DOM::Element& target_node, Vector<FlyString> const& list) const
|
||||
{
|
||||
for (auto& element : m_elements.in_reverse()) {
|
||||
if (&element == &target_node)
|
||||
if (element.ptr() == &target_node)
|
||||
return true;
|
||||
if (list.contains_slow(element.local_name()))
|
||||
if (list.contains_slow(element->local_name()))
|
||||
return false;
|
||||
}
|
||||
VERIFY_NOT_REACHED();
|
||||
|
@ -78,11 +78,11 @@ bool StackOfOpenElements::has_in_select_scope(FlyString const& tag_name) const
|
|||
// 1. Initialize node to be the current node (the bottommost node of the stack).
|
||||
for (auto& node : m_elements.in_reverse()) {
|
||||
// 2. If node is the target node, terminate in a match state.
|
||||
if (node.local_name() == tag_name)
|
||||
if (node->local_name() == tag_name)
|
||||
return true;
|
||||
// 3. Otherwise, if node is one of the element types in list, terminate in a failure state.
|
||||
// NOTE: Here "list" refers to all elements except option and optgroup
|
||||
if (node.local_name() != HTML::TagNames::option && node.local_name() != HTML::TagNames::optgroup)
|
||||
if (node->local_name() != HTML::TagNames::option && node->local_name() != HTML::TagNames::optgroup)
|
||||
return false;
|
||||
// 4. Otherwise, set node to the previous entry in the stack of open elements and return to step 2.
|
||||
}
|
||||
|
@ -94,7 +94,7 @@ bool StackOfOpenElements::has_in_select_scope(FlyString const& tag_name) const
|
|||
bool StackOfOpenElements::contains(const DOM::Element& element) const
|
||||
{
|
||||
for (auto& element_on_stack : m_elements) {
|
||||
if (&element == &element_on_stack)
|
||||
if (&element == element_on_stack.ptr())
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -103,7 +103,7 @@ bool StackOfOpenElements::contains(const DOM::Element& element) const
|
|||
bool StackOfOpenElements::contains(FlyString const& tag_name) const
|
||||
{
|
||||
for (auto& element_on_stack : m_elements) {
|
||||
if (element_on_stack.local_name() == tag_name)
|
||||
if (element_on_stack->local_name() == tag_name)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -111,68 +111,68 @@ bool StackOfOpenElements::contains(FlyString const& tag_name) const
|
|||
|
||||
void StackOfOpenElements::pop_until_an_element_with_tag_name_has_been_popped(FlyString const& tag_name)
|
||||
{
|
||||
while (m_elements.last().local_name() != tag_name)
|
||||
while (m_elements.last()->local_name() != tag_name)
|
||||
(void)pop();
|
||||
(void)pop();
|
||||
}
|
||||
|
||||
DOM::Element* StackOfOpenElements::topmost_special_node_below(const DOM::Element& formatting_element)
|
||||
JS::GCPtr<DOM::Element> StackOfOpenElements::topmost_special_node_below(DOM::Element const& formatting_element)
|
||||
{
|
||||
DOM::Element* found_element = nullptr;
|
||||
JS::GCPtr<DOM::Element> found_element = nullptr;
|
||||
for (auto& element : m_elements.in_reverse()) {
|
||||
if (&element == &formatting_element)
|
||||
if (element.ptr() == &formatting_element)
|
||||
break;
|
||||
if (HTMLParser::is_special_tag(element.local_name(), element.namespace_()))
|
||||
found_element = &element;
|
||||
if (HTMLParser::is_special_tag(element->local_name(), element->namespace_()))
|
||||
found_element = element.ptr();
|
||||
}
|
||||
return found_element;
|
||||
return found_element.ptr();
|
||||
}
|
||||
|
||||
StackOfOpenElements::LastElementResult StackOfOpenElements::last_element_with_tag_name(FlyString const& tag_name)
|
||||
{
|
||||
for (ssize_t i = m_elements.size() - 1; i >= 0; --i) {
|
||||
auto& element = m_elements[i];
|
||||
if (element.local_name() == tag_name)
|
||||
return { &element, i };
|
||||
if (element->local_name() == tag_name)
|
||||
return { element.ptr(), i };
|
||||
}
|
||||
return { nullptr, -1 };
|
||||
}
|
||||
|
||||
DOM::Element* StackOfOpenElements::element_immediately_above(DOM::Element const& target)
|
||||
JS::GCPtr<DOM::Element> StackOfOpenElements::element_immediately_above(DOM::Element const& target)
|
||||
{
|
||||
bool found_target = false;
|
||||
for (auto& element : m_elements.in_reverse()) {
|
||||
if (&element == &target) {
|
||||
if (element.ptr() == &target) {
|
||||
found_target = true;
|
||||
} else if (found_target)
|
||||
return &element;
|
||||
return element.ptr();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void StackOfOpenElements::remove(const DOM::Element& element)
|
||||
void StackOfOpenElements::remove(DOM::Element const& element)
|
||||
{
|
||||
m_elements.remove_first_matching([&element](DOM::Element const& other) {
|
||||
return &other == &element;
|
||||
m_elements.remove_first_matching([&element](auto& other) {
|
||||
return other.ptr() == &element;
|
||||
});
|
||||
}
|
||||
|
||||
void StackOfOpenElements::replace(const DOM::Element& to_remove, NonnullRefPtr<DOM::Element> to_add)
|
||||
void StackOfOpenElements::replace(DOM::Element const& to_remove, JS::NonnullGCPtr<DOM::Element> to_add)
|
||||
{
|
||||
for (size_t i = 0; i < m_elements.size(); i++) {
|
||||
if (&m_elements[i] == &to_remove) {
|
||||
if (m_elements[i].ptr() == &to_remove) {
|
||||
m_elements.remove(i);
|
||||
m_elements.insert(i, move(to_add));
|
||||
m_elements.insert(i, JS::make_handle(*to_add));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StackOfOpenElements::insert_immediately_below(NonnullRefPtr<DOM::Element> element_to_add, DOM::Element const& target)
|
||||
void StackOfOpenElements::insert_immediately_below(JS::NonnullGCPtr<DOM::Element> element_to_add, DOM::Element const& target)
|
||||
{
|
||||
for (size_t i = 0; i < m_elements.size(); i++) {
|
||||
if (&m_elements[i] == &target) {
|
||||
m_elements.insert(i + 1, move(element_to_add));
|
||||
if (m_elements[i].ptr() == &target) {
|
||||
m_elements.insert(i + 1, JS::make_handle(*element_to_add));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue