LibWeb: Replace templated retarget function with a regular one

The templating is not necessary anywhere and was effectively just a cast
This commit is contained in:
circl 2024-07-21 15:06:05 +02:00 committed by Andrew Kaster
parent 3adfdd3257
commit 37f93e4be1
Notes: github-actions[bot] 2024-07-21 22:02:25 +00:00
5 changed files with 49 additions and 39 deletions

View file

@ -192,6 +192,7 @@ set(SOURCES
DOM/StyleElementUtils.cpp
DOM/Text.cpp
DOM/TreeWalker.cpp
DOM/Utils.cpp
DOM/XMLDocument.cpp
DOMParsing/XMLSerializer.cpp
DOMURL/DOMURL.cpp

View file

@ -1911,7 +1911,7 @@ void Document::update_active_element()
Node* candidate = focused_element();
// 2. Set candidate to the result of retargeting candidate against this DocumentOrShadowRoot.
candidate = retarget<Node>(candidate, this);
candidate = verify_cast<Node>(retarget(candidate, this));
// 3. If candidate's root is not this DocumentOrShadowRoot, then return null.
if (&candidate->root() != this) {

View file

@ -196,7 +196,7 @@ bool EventDispatcher::dispatch(JS::NonnullGCPtr<EventTarget> target, Event& even
JS::GCPtr<EventTarget> activation_target;
// 4. Let relatedTarget be the result of retargeting events relatedTarget against target.
JS::GCPtr<EventTarget> related_target = retarget<EventTarget>(event.related_target(), target);
JS::GCPtr<EventTarget> related_target = retarget(event.related_target(), target);
bool clear_targets = false;
// 5. If target is not relatedTarget or target is events relatedTarget, then:
@ -206,7 +206,7 @@ bool EventDispatcher::dispatch(JS::NonnullGCPtr<EventTarget> target, Event& even
// 2. For each touchTarget of events touch target list, append the result of retargeting touchTarget against target to touchTargets.
for (auto& touch_target : event.touch_target_list()) {
touch_targets.append(retarget<EventTarget>(touch_target, target));
touch_targets.append(retarget(touch_target, target));
}
// 3. Append to an event path with event, target, targetOverride, relatedTarget, touchTargets, and false.
@ -253,14 +253,14 @@ bool EventDispatcher::dispatch(JS::NonnullGCPtr<EventTarget> target, Event& even
slottable = parent;
// 3. Let relatedTarget be the result of retargeting events relatedTarget against parent.
related_target = retarget<EventTarget>(event.related_target(), parent);
related_target = retarget(event.related_target(), parent);
// 4. Let touchTargets be a new list.
touch_targets.clear();
// 5. For each touchTarget of events touch target list, append the result of retargeting touchTarget against parent to touchTargets.
for (auto& touch_target : event.touch_target_list()) {
touch_targets.append(retarget<EventTarget>(touch_target, parent));
touch_targets.append(retarget(touch_target, parent));
}
// 6. If parent is a Window object, or parent is a node and targets root is a shadow-including inclusive ancestor of parent, then:

View file

@ -0,0 +1,41 @@
/*
* Copyright (c) 2020, Luke Wilde <lukew@serenityos.org>
* Copyright (c) 2024, circl <circl.lastname@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#include <LibWeb/DOM/EventTarget.h>
#include <LibWeb/DOM/Node.h>
#include <LibWeb/DOM/ShadowRoot.h>
#include <LibWeb/DOM/Utils.h>
namespace Web::DOM {
// https://dom.spec.whatwg.org/#retarget
EventTarget* retarget(EventTarget* a, EventTarget* b)
{
// To retarget an object A against an object B, repeat these steps until they return an object:
for (;;) {
// 1. If one of the following is true then return A.
// - A is not a node
if (!is<Node>(a))
return a;
// - As root is not a shadow root
auto* a_node = verify_cast<Node>(a);
auto& a_root = a_node->root();
if (!is<ShadowRoot>(a_root))
return a;
// - B is a node and As root is a shadow-including inclusive ancestor of B
if (is<Node>(b) && a_root.is_shadow_including_inclusive_ancestor_of(verify_cast<Node>(*b)))
return a;
// 2. Set A to As roots host.
auto& a_shadow_root = verify_cast<ShadowRoot>(a_root);
a = a_shadow_root.host();
}
}
}

View file

@ -7,42 +7,10 @@
#pragma once
#include <LibWeb/DOM/Node.h>
#include <LibWeb/DOM/ShadowRoot.h>
#include <LibWeb/DOM/EventTarget.h>
namespace Web::DOM {
// https://dom.spec.whatwg.org/#retarget
inline EventTarget* retarget_impl(EventTarget* a, EventTarget* b)
{
// To retarget an object A against an object B, repeat these steps until they return an object:
for (;;) {
// 1. If one of the following is true then return A.
// - A is not a node
if (!is<Node>(a))
return a;
// - As root is not a shadow root
auto* a_node = verify_cast<Node>(a);
auto& a_root = a_node->root();
if (!is<ShadowRoot>(a_root))
return a;
// - B is a node and As root is a shadow-including inclusive ancestor of B
if (is<Node>(b) && a_root.is_shadow_including_inclusive_ancestor_of(verify_cast<Node>(*b)))
return a;
// 2. Set A to As roots host.
auto& a_shadow_root = verify_cast<ShadowRoot>(a_root);
a = a_shadow_root.host();
}
}
// https://dom.spec.whatwg.org/#retarget
template<typename T>
T* retarget(T* a, T* b)
{
return static_cast<T*>(retarget_impl(a, b));
}
EventTarget* retarget(EventTarget* a, EventTarget* b);
}