-
Notifications
You must be signed in to change notification settings - Fork 307
Do not dispatch a trusted event when target and reletedTarget are identical #336
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This has the same issue as the one I pointed out in WICG/webcomponents#577. In general, you can't just compare target and related target or their retargeted counterparts. You need to look at whether we're crossing a shadow boundary, and if both target and related target are in the shadow tree from which we're exiting. For example, it's perfectly fine to dispatch an event with target set to a shadow host and related target set to a node inside that shadow tree, and the event MUST be dispatched. |
Yeah, I am fully aware of that. The point is UA events. There is a case where we should not dispatch a UA event with such a condition. Could you have a chance to see the example in #336 (comment)? Maybe https://cs.chromium.org/chromium/src/third_party/WebKit/LayoutTests/fast/dom/shadow/shadow-boundary-events.html?l=150 might be helpful to understand the case. In this case, we should not dispatch an mouseover event on the shadow host (shadowF). That is the motivation of this change. If we are to dispatch a synthetic event which has the same condition (with target=shadowF and relatedTarget=shadowI), and want to make sure that event is dispatched, we have to check whether an event is a synthetic event or not explicitly in the spec. I do not want to introduce the divergence between synthetic events and UA events in the spec (and the implementation) only because we want to address this very minor case. The benefit looks small, though I am not 100% sure. Thus, in summary, the point is which we prefer (1 or 2):
The PR stands for 2. |
This is not a thing the generic event dispatch algorithm should be dealing with; the same way |
Hmm. Maybe that would be possible. However, is it really worth doing? |
I don't understand. You said earlier that the only case you care about with regards to the related target being inside the shadow tree of the target is when UA fires a trusted event. Specifying this in the UI events spec would specifically solves this issue. Note that UI events spec specifies when and how events gets fired by UA. e.g. mouseout wouldn't get fired constantly whenever mouseover happens. |
I do not think that's a good idea. BTW, do you prefer 1? Is my understanding correct?
|
We do not have to do the same way as we did for |
Anyway, let me update the PR so that a synthetic event is always dispatched in the first tree, at least until the root of the tree. I am fine with this change. The PR would become simpler because the current spec already handles that well. |
54922bc
to
554f1cf
Compare
554f1cf
to
fc07ea8
Compare
I have updated the PR, re-using this thread. Please ignore the first comment in this discussion. The PR became much simpler. |
@@ -1201,6 +1201,9 @@ for discussion). | |||
<a>relatedTarget</a> against <var>target</var> if <var>event</var>'s <a>relatedTarget</a> is | |||
non-null, and null otherwise. | |||
|
|||
<li><p>If <var>event</var>'s {{Event/isTrusted}} attribute is true and <var>target</var> and | |||
<var>relatedTarget</var> are identical, terminate these steps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is that okay to terminate these steps without a return value?
That would be no difference in practice, but I am not sure what is the best.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this actually how we would implement this in practice? It seems somewhat weird to use the isTrusted
attribute. Also in part because I still don't quite know when it's set and when it's not. Does element.click()
set it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
element.click() doesn't dispatch trusted events.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
DOM Standard defines isTrusted as follows:
event . isTrusted
Returns true if event was dispatched by the user agent, and false otherwise.
I am not sure how we could interpret "event was dispatched by the user agent" strictly.
I tend to agree @SmauG: A click event triggered by element.click()
is dispatched by users, instead of UA. I confirmed that element.click() doesn't dispatch trusted events in Blink.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is not a normative description of isTrusted
though. That's just sort of what it does. We don't really have a normative description anywhere. It's currently left to those dispatching events in various specifications.
I thought maybe the ECMAScript stack being empty would be it, but postMessage()
results in untrusted events, so that's not it either.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
postMessage() dispatching untrusted events? That is a bug.
click is the special case similarly to dispatching MouseEvent click explicitly needing to trigger default handling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks. Instead of using isTrusted
here, just saying "If event is dispatched by the user agent" would be safer?
Could we please not use PRs for discussing spec issues. |
FWIW, after reading comments here, I was about to propose the same stuff what hayato then proposes in #336 (review) , I think. Also, I would imagine #336 (review) is what would be implemented, not some per-event-firing-location relatedTarget check. |
@smaug---- I don't really understand what you're proposing. I'd think we want to make the specification match how this is actually implemented in practice. When implementation and specification diverge, there's often room for bugs. @hayatoito we can't say "dispatched by the user agent" since that is too vague. It sounds like what @smaug---- is saying there is that |
The same thing what @hayatoito proposed |
Apologies, I got confused and you are correct. I rebased the PR and applied some minor nit fixes. I have two questions:
|
fc07ea8
to
0a341d8
Compare
Thank you!
I am not sure. Maybe we can return As far as I confirmed in Blink, Blink returns |
Yeah, returning true is probably better, especially if that matches implementations. I can make that change before landing. @rniwa could you please review one more time? If I don't hear anything by tomorrow I'm just going to assume you're okay with this. We can always revisit post-commit. |
@@ -1201,6 +1201,9 @@ for discussion). | |||
<a>relatedTarget</a> against <var>target</var> if <var>event</var>'s <a>relatedTarget</a> is | |||
non-null, and null otherwise. | |||
|
|||
<li><p>If <var>event</var>'s {{Event/isTrusted}} attribute is true and <var>target</var> is | |||
<var>relatedTarget</var>, then terminate these steps. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I don't think we should be specifying this in the DOM specification. Also, this would affect every UI event dispatch beyond just ones inside shadow trees, and I'm not okay with that.
Please don't merge this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, this would affect every UI event dispatch beyond just ones inside shadow trees
We don't have to worry about such a case. UA's UI Event which happens in a document tree never meets this condition. Such an UI Event's target and relatedTarget are always different, as far as I see. A target and a relatedTarget could be identical only if retargeting happens.
@rniwa what do you suggest we do instead? And how would/do you implement this in WebKit? |
I don't think this is a thing that belongs to the DOM specification. It should be specified in https://w3c.github.io/uievents/ which already specifies other conditions under which an event should be dispatched or not dispatched. Adding this text to the DOM means that any event regardless of whether they're UI event or not would not be dispatched by UA if it happens to have a related target and it's equal to the target. |
How would you implement this though? Also, the whole reason DOM has relatedTarget logic is because there is no clean layering. |
I don't know how relevant how each implementation does this check since that'll be an implementation detail but WebKit checks this condition when figuring out which node to fire mouse events. |
The PR does not have an intention to distinguish UI events or not. That is not what we agreed at all. Could you file another bug if you have another concrete proposal? We should not discuss that in this PR because your proposal sounds a new proposal which we have not heard. |
Okay. Let's change the sentence as follows, and land this PR.
@annevk I appreciate if you could merge this PR with this change. |
@rniwa note that relatedTarget in DOM is not generic per se. Only if an event class decides to make use of that internal slot will they participate in the choices DOM makes for it. If you want to call something relatedTarget but have different semantics, you could in theory use your own internal slot for it. (This is all a little hairy since we haven't formalized internal slots yet and UI events is a hopelessly vague specification, but, it should all work...) Anyway, I'll update the PR per the discussion and land it tonight / tomorrow. |
… are identical For example, when a mouse pointer moves from an element in a shadow tree to its shadow host, a "mouseover" event should not be dispatched on the shadow host. The current spec allows a non-empty event path in this case. Fixes #337.
0a341d8
to
b1667d1
Compare
PR updated. |
On my second thought, don't we want this behavior to non-trusted events as well? When someone manually fire a Now I'm re-reading the history of what's been discussed here, I've started to think that we may want some sort of a flag like |
The beginning of this PR thread does touch upon the synthetic event issue. And in #336 (comment) @hayatoito argued for not making them diverge, but then the thread went into a different direction. I also realize I forgot to update the text to make it return true as mentioned in #336 (comment). Will do that now. |
I'm going to land this with the |
@hayatoito are you planning on writing tests for this? |
Ah, I see. Okay to remove I can add tests for WPT. Thank you! |
Revert the part of https://codereview.chromium.org/2384403002 since the DOM Standard was updated and 'isTrusted' guard condition was removed from there. See the discussion at whatwg/dom#336 for details. Blink forgot to address the update of the commit, as mentioned at whatwg/dom#336 (comment). Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98
Revert the part of https://codereview.chromium.org/2384403002 since the DOM Standard was updated and 'isTrusted' guard condition was removed from there. See the discussion at whatwg/dom#336 for details. Blink forgot to address the update of the commit, as mentioned at whatwg/dom#336 (comment). Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98
…atedTarget See the discussion at whatwg/dom#336 for details. Blink implemented it at https://codereview.chromium.org/2384403002, however, it turned out that both the web platform test and the implementation were wrong. This CL fixed the implementation, as well as the web platform test. Compatibility risk is almost none about this change. Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98
…atedTarget See the discussion at whatwg/dom#336 for details. Blink implemented it at https://codereview.chromium.org/2384403002, however, it turned out that both the web platform test and the implementation were wrong. This CL fixed the implementation, as well as the web platform test. Compatibility risk is almost none about this change. Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98
…atedTarget See the discussion at whatwg/dom#336 for details. Blink implemented it at https://codereview.chromium.org/2384403002, however, it turned out that both the web platform test and the implementation were wrong. This CL fixed the implementation, as well as the web platform test. Compatibility risk is almost none about this change. Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98 Reviewed-on: https://chromium-review.googlesource.com/869693 Reviewed-by: Takayoshi Kochi <[email protected]> Commit-Queue: Hayato Ito <[email protected]> Cr-Commit-Position: refs/heads/master@{#530392}
…atedTarget See the discussion at whatwg/dom#336 for details. Blink implemented it at https://codereview.chromium.org/2384403002, however, it turned out that both the web platform test and the implementation were wrong. This CL fixed the implementation, as well as the web platform test. Compatibility risk is almost none about this change. Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98 Reviewed-on: https://chromium-review.googlesource.com/869693 Reviewed-by: Takayoshi Kochi <[email protected]> Commit-Queue: Hayato Ito <[email protected]> Cr-Commit-Position: refs/heads/master@{#530392}
…atedTarget See the discussion at whatwg/dom#336 for details. Blink implemented it at https://codereview.chromium.org/2384403002, however, it turned out that both the web platform test and the implementation were wrong. This CL fixed the implementation, as well as the web platform test. Compatibility risk is almost none about this change. Bug: 655494 Change-Id: I084cd6b748c304f5f2b395f0b62ba02025385a98 Reviewed-on: https://chromium-review.googlesource.com/869693 Reviewed-by: Takayoshi Kochi <[email protected]> Commit-Queue: Hayato Ito <[email protected]> Cr-Commit-Position: refs/heads/master@{#530392}
@hayatoito Well, I've read your issue, I see you avoided in spec using /// Let "target" be the host of a shadow root in an another shadow root
/// Let "relatedTarget" be the node in shadow root of the host
const ev = new Event("click");
ev.relatedTarget = relatedTarget;
target.addEventListener("click", (e) => console.log(e));
target.dispatchEvent(ev) This example will invoke callback but it shouldn't because condition returns I see that browsers don't call callbacks if it conform that condition if it is not synthetic event and call if it is synthetic event.
But if I appoint relatedTarget the following way: const ev = new MouseEvent("click", {relatedTarget}); then condition will work as if it will be an non-synthetic event, hence it won't invoke the callback of the event listener. In theory, it doesn't matter how I set relatedTarget, the condition shouldn't allow callback functions to be called. But for some reason it doesn't match. Could you give some comment about that? |
The internally associated “relatedTarget” (not sure why it’s camel cased in the spec, I thought the norm for this was using regular spaces) isn’t the |
@bathos yeah I observed that Summarize: Inspite of that spec explicit says about |
Right. Despite sharing the same name as an attribute of UIEvent and a dictionary member that UIEvent constructors accept, when the spec says “event’s relatedTarget”, it isn’t referring to an ES property. It’s an abstract internal association, not something specific to the ECMAScript binding. |
…Target are identical
Change the behavior of event dispatch as follows:
and relatedTarget are identical in synthetic events.
retargeted-reletedTarget are identical, but target and relatedTarget are
not identical.
(2) is a bug fix. This sitution happens in UA events. For example,
if a mouse pointer moves from an element in a shadow tree to
its shadow host, a "mouseover" event should not be dispatched on the
shadow host. The current spec allows a non-empty event path in this case.
Fixes WICG/webcomponents#577