[whatwg/dom] `event.target` not cleared if event is not fired on `ShadowRoot` (Issue #1072)

DOM events can be used on both `Node` and non-`Node` objects. Particularly an `EventTarget` can be constructed by the user.

For example:
```javascript
const myEvent = new Event('test');
const myTarget = new EventTarget();
console.log(myEvent.target == null); // true
const listener = event => { console.log(event.target === myTarget); // true };
myTarget.addEventListener('test', listener);
myTarget.dispatchEvent(myEvent);
console.log(myEvent.target == null); // false
console.log(myEvent.target === myTarget); // true
```

It seems similar behavior is experienced when dispatching event on a `Node`. The only time `event.target` is cleared is when the `EventTarget` is a `Node` in a shadow-tree. Is this the intended behavior?

It seems clearing depends on a single variable `clearTargets` which requires one of the shadow-adjusted target, the `relatedTarget`, or any `EventTarget` in the touch target list to be a descendant of a `ShadowRoot`:

> 2.9. Dispatching events
> > 5. If _target_ is not [relatedTarget](https://dom.spec.whatwg.org/#event-relatedtarget) or target is event’s relatedTarget, then:
> > > 11. Let _clearTargets_ be true if _clearTargetsStruct_’s [shadow-adjusted target](https://dom.spec.whatwg.org/#event-path-shadow-adjusted-target), _clearTargetsStruct_’s [relatedTarget](https://dom.spec.whatwg.org/#event-path-relatedtarget), or an [EventTarget](https://dom.spec.whatwg.org/#eventtarget) object in _clearTargetsStruct_’s [touch target list](https://dom.spec.whatwg.org/#event-path-touch-target-list) is a [node](https://dom.spec.whatwg.org/#concept-node) and its [root](https://dom.spec.whatwg.org/#concept-tree-root) is a [shadow root](https://dom.spec.whatwg.org/#concept-shadow-root); otherwise _false_.

This also Introduce variable `clearTargets` that is not used within the scope of point 5, of section 2.9. A more appropriate way it to introduce:
> 5. Let _clearTargets_ be _false_
> 6. If _target_ is not ...
> >  11. Set _clearTargets_ to true if ...

Beside the syntax, the semantic problem at:
> 10. If _clearTargets_, then:
> > 1. Set _event_’s [target](https://dom.spec.whatwg.org/#event-target) to **null**.
> > 2. Set _event_’s [relatedTarget](https://dom.spec.whatwg.org/#event-relatedtarget) to **null**.
> > 3. Set _event_’s [touch target list](https://dom.spec.whatwg.org/#event-touch-target-list) to the empty list.

will never clear the `event.target`, if the dispatch target is not a shadow root. This is also observed as an actual behavior in Google Chrome (v99.0.4844.84).

If this is not intended, perhaps a more appropriate behavior will be:
> 10. Set _event_’s [target](https://dom.spec.whatwg.org/#event-target) to **null**.
> 11. If _clearTargets_, then:
> > 1. Set _event_’s [relatedTarget](https://dom.spec.whatwg.org/#event-relatedtarget) to **null**.
> > 2. Set _event_’s [touch target list](https://dom.spec.whatwg.org/#event-touch-target-list) to the empty list.

While `event.relatedTarget` and touch target list might never by changed for non-shadow elements, `event.target` is guarantee to be changed, as at least one invocation would be `AT_TARGET` (and for non-`Node` `EventTarget` the only invocation will be `AT_TARGET`). Therefore, `event.target` is guaranteed to be modified by the `dispatchEvent`, while `event.relatedTarget` might not be if the `EventTarget` is not a `Node` and not in a shadow tree (I am not sure about the touch target list, but I assume the same).

-- 
Reply to this email directly or view it on GitHub:
https://github.com/whatwg/dom/issues/1072

You are receiving this because you are subscribed to this thread.

Message ID: <whatwg/dom/issues/1072@github.com>

Received on Saturday, 9 April 2022 13:08:20 UTC