mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-01 08:48:49 +00:00
LibWeb: Initialize clearTargets in event dispatch correctly
Corresponds to https://github.com/whatwg/dom/pull/1347
This commit is contained in:
parent
3775f3399c
commit
a5be7cb6fb
Notes:
github-actions[bot]
2025-01-30 16:15:47 +00:00
Author: https://github.com/AtkinsSJ
Commit: a5be7cb6fb
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/3397
Reviewed-by: https://github.com/gmta ✅
4 changed files with 24 additions and 21 deletions
|
@ -118,13 +118,13 @@ bool DOMTokenList::contains(String const& token)
|
|||
// https://dom.spec.whatwg.org/#dom-domtokenlist-add
|
||||
WebIDL::ExceptionOr<void> DOMTokenList::add(Vector<String> const& tokens)
|
||||
{
|
||||
// 1. For each token in tokens:
|
||||
// 1. For each token of tokens:
|
||||
for (auto const& token : tokens) {
|
||||
// a. If token is the empty string, then throw a "SyntaxError" DOMException.
|
||||
// b. If token contains any ASCII whitespace, then throw an "InvalidCharacterError" DOMException.
|
||||
TRY(validate_token(token));
|
||||
|
||||
// 2. For each token in tokens, append token to this’s token set.
|
||||
// 2. For each token of tokens, append token to this’s token set.
|
||||
append_to_ordered_set(m_token_set, token);
|
||||
}
|
||||
|
||||
|
@ -136,13 +136,13 @@ WebIDL::ExceptionOr<void> DOMTokenList::add(Vector<String> const& tokens)
|
|||
// https://dom.spec.whatwg.org/#dom-domtokenlist-remove
|
||||
WebIDL::ExceptionOr<void> DOMTokenList::remove(Vector<String> const& tokens)
|
||||
{
|
||||
// 1. For each token in tokens:
|
||||
// 1. For each token of tokens:
|
||||
for (auto const& token : tokens) {
|
||||
// a. If token is the empty string, then throw a "SyntaxError" DOMException.
|
||||
// b. If token contains any ASCII whitespace, then throw an "InvalidCharacterError" DOMException.
|
||||
TRY(validate_token(token));
|
||||
|
||||
// 2. For each token in tokens, remove token from this’s token set.
|
||||
// 2. For each token of tokens, remove token from this’s token set.
|
||||
remove_from_ordered_set(m_token_set, token);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ bool EventDispatcher::inner_invoke(Event& event, Vector<GC::Root<DOM::DOMEventLi
|
|||
// 1. Let found be false.
|
||||
bool found = false;
|
||||
|
||||
// 2. For each listener in listeners, whose removed is false:
|
||||
// 2. For each listener of listeners, whose removed is false:
|
||||
for (auto& listener : listeners) {
|
||||
if (listener->removed)
|
||||
continue;
|
||||
|
@ -212,8 +212,10 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
// 4. Let relatedTarget be the result of retargeting event’s relatedTarget against target.
|
||||
GC::Ptr<EventTarget> related_target = retarget(event.related_target(), target);
|
||||
|
||||
// 5. Let clearTargets be false.
|
||||
bool clear_targets = false;
|
||||
// 5. If target is not relatedTarget or target is event’s relatedTarget, then:
|
||||
|
||||
// 6. If target is not relatedTarget or target is event’s relatedTarget, then:
|
||||
if (related_target != target || event.related_target() == target) {
|
||||
// 1. Let touchTargets be a new list.
|
||||
Event::TouchTargetList touch_targets;
|
||||
|
@ -320,8 +322,9 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
|
||||
VERIFY(clear_targets_struct.has_value());
|
||||
|
||||
// 11. Let clearTargets be true if clearTargetsStruct’s shadow-adjusted target, clearTargetsStruct’s relatedTarget,
|
||||
// or an EventTarget object in clearTargetsStruct’s touch target list is a node and its root is a shadow root; otherwise false.
|
||||
// 11. If clearTargetsStruct’s shadow-adjusted target, clearTargetsStruct’s relatedTarget, or an EventTarget
|
||||
// object in clearTargetsStruct’s touch target list is a node whose root is a shadow root:
|
||||
// set clearTargets to true.
|
||||
if (is<Node>(clear_targets_struct.value().shadow_adjusted_target.ptr())) {
|
||||
auto& shadow_adjusted_target_node = as<Node>(*clear_targets_struct.value().shadow_adjusted_target);
|
||||
if (is<ShadowRoot>(shadow_adjusted_target_node.root()))
|
||||
|
@ -350,7 +353,7 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
if (activation_target)
|
||||
activation_target->legacy_pre_activation_behavior();
|
||||
|
||||
// 13. For each struct in event’s path, in reverse order:
|
||||
// 13. For each struct of event’s path, in reverse order:
|
||||
for (auto& entry : event.path().in_reverse()) {
|
||||
// 1. If struct’s shadow-adjusted target is non-null, then set event’s eventPhase attribute to AT_TARGET.
|
||||
if (entry.shadow_adjusted_target)
|
||||
|
@ -363,7 +366,7 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
invoke(entry, event, Event::Phase::CapturingPhase, legacy_output_did_listeners_throw);
|
||||
}
|
||||
|
||||
// 14. For each struct in event’s path:
|
||||
// 14. For each struct of event’s path:
|
||||
for (auto& entry : event.path()) {
|
||||
// 1. If struct’s shadow-adjusted target is non-null, then set event’s eventPhase attribute to AT_TARGET.
|
||||
if (entry.shadow_adjusted_target) {
|
||||
|
@ -384,21 +387,21 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
}
|
||||
}
|
||||
|
||||
// 6. Set event’s eventPhase attribute to NONE.
|
||||
// 7. Set event’s eventPhase attribute to NONE.
|
||||
event.set_phase(Event::Phase::None);
|
||||
|
||||
// 7. Set event’s currentTarget attribute to null.
|
||||
// 8. Set event’s currentTarget attribute to null.
|
||||
event.set_current_target(nullptr);
|
||||
|
||||
// 8. Set event’s path to the empty list.
|
||||
// 9. Set event’s path to the empty list.
|
||||
event.clear_path();
|
||||
|
||||
// 9. Unset event’s dispatch flag, stop propagation flag, and stop immediate propagation flag.
|
||||
// 10. Unset event’s dispatch flag, stop propagation flag, and stop immediate propagation flag.
|
||||
event.set_dispatched(false);
|
||||
event.set_stop_propagation(false);
|
||||
event.set_stop_immediate_propagation(false);
|
||||
|
||||
// 10. If clearTargets, then:
|
||||
// 11. If clearTargets, then:
|
||||
if (clear_targets) {
|
||||
// 1. Set event’s target to null.
|
||||
event.set_target(nullptr);
|
||||
|
@ -410,7 +413,7 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
event.clear_touch_target_list();
|
||||
}
|
||||
|
||||
// 11. If activationTarget is non-null, then:
|
||||
// 12. If activationTarget is non-null, then:
|
||||
if (activation_target) {
|
||||
// 1. If event’s canceled flag is unset, then run activationTarget’s activation behavior with event.
|
||||
if (!event.cancelled()) {
|
||||
|
@ -423,7 +426,7 @@ bool EventDispatcher::dispatch(GC::Ref<EventTarget> target, Event& event, bool l
|
|||
}
|
||||
}
|
||||
|
||||
// 12. Return false if event’s canceled flag is set; otherwise true.
|
||||
// 13. Return false if event’s canceled flag is set; otherwise true.
|
||||
return !event.cancelled();
|
||||
}
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ Vector<FlyString> NamedNodeMap::supported_property_names() const
|
|||
names.append(attribute_name.to_string());
|
||||
}
|
||||
|
||||
// 2. If this NamedNodeMap object’s element is in the HTML namespace and its node document is an HTML document, then for each name in names:
|
||||
// 2. If this NamedNodeMap object’s element is in the HTML namespace and its node document is an HTML document, then for each name of names:
|
||||
if (associated_element().namespace_uri() == Namespace::HTML && associated_element().document().is_html_document()) {
|
||||
// 1. Let lowercaseName be name, in ASCII lowercase.
|
||||
// 2. If lowercaseName is not equal to name, remove name from names.
|
||||
|
|
|
@ -1502,18 +1502,18 @@ u16 Node::compare_document_position(GC::Ptr<Node> other)
|
|||
// 4. If node1 is an attribute, then set attr1 to node1 and node1 to attr1’s element.
|
||||
if (is<Attr>(node1)) {
|
||||
attr1 = as<Attr>(node1);
|
||||
node1 = const_cast<Element*>(attr1->owner_element());
|
||||
node1 = attr1->owner_element();
|
||||
}
|
||||
|
||||
// 5. If node2 is an attribute, then:
|
||||
if (is<Attr>(node2)) {
|
||||
// 1. Set attr2 to node2 and node2 to attr2’s element.
|
||||
attr2 = as<Attr>(node2);
|
||||
node2 = const_cast<Element*>(attr2->owner_element());
|
||||
node2 = attr2->owner_element();
|
||||
|
||||
// 2. If attr1 and node1 are non-null, and node2 is node1, then:
|
||||
if (attr1 && node1 && node2 == node1) {
|
||||
// FIXME: 1. For each attr in node2’s attribute list:
|
||||
// FIXME: 1. For each attr of node2’s attribute list:
|
||||
// 1. If attr equals attr1, then return the result of adding DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC and DOCUMENT_POSITION_PRECEDING.
|
||||
// 2. If attr equals attr2, then return the result of adding DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC and DOCUMENT_POSITION_FOLLOWING.
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue