This is an archived snapshot of W3C's public bugzilla bug tracker, decommissioned in April 2019. Please see the home page for more details.
From https://bugs.webkit.org/show_bug.cgi?id=76217: "... the meaning of AT_TARGET changes in the presence of the shadow DOM, and the AT_TARGET must be fired more than one time -- once for each shadow boundary. Since we are retargeting events, we must also report each "new" target as a separate occurrence."
That reminds me of this bug: https://bugs.webkit.org/show_bug.cgi?id=64160. Should we apply a rule of 'AT_TARGET must be fired multiple times' to only bubbling events? Non-bubbling events, such as FocusEvent, is out of scope of this rule?
Let me ask another question. After some thought, I am wondering how we should define MULTIPLE AT_TARGET rule. Let me explain using the following tree: - A - B <Shadow boundary> - C - D <Shadow boundary> - E - F Suppose 'click' event happens in 'F'. In the current spec, events will be fired in the following order: * Legend (currentTarget - target - phase) 1. A - B - CAPTURE 2. B - B - CAPTURE 3. C - D - CAPTURE 4. D - D - CAPTURE 5. E - F - CAPTURE 6. F - F - TARGET 7. E - F - BUBBLE 8. D - D - BUBBLE 9. C - D - BUBBLE 10. B - B - BUBBLE 11. A - B - BUBBLE With multiple AT_TARGET rule, in which orders events should be fired? e.g. 1. A - B - CAPTURE 2. B - B - TARGET 3. C - D - CAPTURE 4. D - D - TARGET 5. E - F - CAPTURE 6. F - F - TARGET 7. E - F - BUBBLE 9. C - D - BUBBLE 11. A - B - BUBBLE Otherwise, we should isolate each event dispatching flow by shadow boundary, should we? flow1) 1. A - B - CAPTURE 2. B - B - TARGET 3. A - B - BUBBLE flow2) 1. C - D - CAPTURE 2. D - D - TARGET 3. C - D - BUBBLE flow3) 1. E - F - CAPTURE 2. F - F - TARGET 3. E - F - BUBBLE - We don't define orders between flow1, 2 and 3. Each flow should be independent. - event.stopPropagation() called in some flow should not take effect on other flows. Any thoughts?
I think it should be: 1. A - B - CAPTURE 2. B - B - CAPTURE 3. C - D - CAPTURE 4. D - D - CAPTURE 5. E - F - CAPTURE 6. B - B - TARGET 7. D - D - TARGET 8. F - F - TARGET 9. E - F - BUBBLE 10. D - D - BUBBLE 11. C - D - BUBBLE 12. B - B - BUBBLE 13. A - B - BUBBLE This way, the event phase always only progresses from CAPTURE to TARGET to BUBBLE. The stopPropagation() should just work as usual. And yes, you're right -- bug https://bugs.webkit.org/show_bug.cgi?id=64160 is relevant here. We should've seen that firing AT_TARGET on shadow host was necessary for the non-bubbling events. WDYT?
(In reply to comment #3) No wait -- it should be 1. A - B - CAPTURE 2. B - B - TARGET 3. C - D - CAPTURE 4. D - D - TARGET 5. E - F - CAPTURE 6. F - F - TARGET 7. E - F - BUBBLE 9. C - D - BUBBLE 10. B - B - BUBBLE 11. A - B - BUBBLE As you mentioned before. You were right, Hayato-san. > > This way, the event phase always only progresses from CAPTURE to TARGET to > BUBBLE. The stopPropagation() should just work as usual. > > And yes, you're right -- bug https://bugs.webkit.org/show_bug.cgi?id=64160 is > relevant here. We should've seen that firing AT_TARGET on shadow host was > necessary for the non-bubbling events. > > WDYT?
The rule is easy -- anytime a node and adjusted target match is considered AT_TARGET. Weee!
This is all wrong. I am going to need to rewrite this section. Wait please...
http://dvcs.w3.org/hg/webcomponents/rev/50eb1e7fbc98 I reworked the algorithm to do the right thing. The resulting sequence for Hayato-san's example is: 1. A - B - CAPTURE 2. C - D - CAPTURE 3. E - F - CAPTURE 4. F - F - TARGET 5. E - F - BUBBLE 6. D - D - TARGET 7. C - D - BUBBLE 8. B - B - TARGET 9. A - B - BUBBLE
LGTM. Thank you. That seems natural and reasonable order. (In reply to comment #7) > http://dvcs.w3.org/hg/webcomponents/rev/50eb1e7fbc98 > > I reworked the algorithm to do the right thing. The resulting sequence for > Hayato-san's example is: > > 1. A - B - CAPTURE > 2. C - D - CAPTURE > 3. E - F - CAPTURE > 4. F - F - TARGET > 5. E - F - BUBBLE > 6. D - D - TARGET > 7. C - D - BUBBLE > 8. B - B - TARGET > 9. A - B - BUBBLE (In reply to comment #7) > http://dvcs.w3.org/hg/webcomponents/rev/50eb1e7fbc98 > > I reworked the algorithm to do the right thing. The resulting sequence for > Hayato-san's example is: > > 1. A - B - CAPTURE > 2. C - D - CAPTURE > 3. E - F - CAPTURE > 4. F - F - TARGET > 5. E - F - BUBBLE > 6. D - D - TARGET > 7. C - D - BUBBLE > 8. B - B - TARGET > 9. A - B - BUBBLE
I think that the new rule, > When processing step 3 of the event dispatch algorithm, the event listeners must not be invoked on a node when it is the same as its relative target introduces a compatibility issue for non-bubbling events. If we register a listener, which uses (useCapture=true), for a non-bubbling event (event.bublles() == false) to each elements as follow: A.addListener('focus', listener, true); B.addListener('focus', listner, true); ... ... Before the new rule, the following events will be fired: A - B - CAPTURE B - B - CAPTURE C - D - CAPTURE D - D - CAPTURE E - F - CAPTURE F - F - TARGET Ater the new rule, only the following events will be fired: 1. A - B - CAPTURE 2. C - D - CAPTURE 3. E - F - CAPTURE 4. F - F - TARGET So we miss AT_TARGET events at B and D for non-bubbling events, which should be called, shouldn't we?
So what about this? When processing step 3 of the event dispatch algorithm, if event.target == event.currentTarget: if event.bubbles: do not call event listeners. else: call event listeners with eventPhase attribute == AT_TARGET else: call event listeners. (In reply to comment #9) > I think that the new rule, > > > When processing step 3 of the event dispatch algorithm, the event listeners must not be invoked on a node when it is the same as its relative target > > introduces a compatibility issue for non-bubbling events. If we register a > listener, which uses (useCapture=true), for a non-bubbling event > (event.bublles() == false) to each elements as follow: > > A.addListener('focus', listener, true); > B.addListener('focus', listner, true); > ... > ... > > > Before the new rule, the following events will be fired: > > A - B - CAPTURE > B - B - CAPTURE > C - D - CAPTURE > D - D - CAPTURE > E - F - CAPTURE > F - F - TARGET > > > Ater the new rule, only the following events will be fired: > > 1. A - B - CAPTURE > 2. C - D - CAPTURE > 3. E - F - CAPTURE > 4. F - F - TARGET > > So we miss AT_TARGET events at B and D for non-bubbling events, which should be > called, shouldn't we?
(In reply to comment #10) > So what about this? > > When processing step 3 of the event dispatch algorithm, > if event.target == event.currentTarget: > if event.bubbles: > do not call event listeners. > else: > call event listeners with eventPhase attribute == AT_TARGET > else: > call event listeners. This seems to change the order of how capture->target->bubbling progresses... What do you think about this? http://dvcs.w3.org/hg/webcomponents/rev/f46cfd9b0832
Yours is concise and better than mine. I like it. Thank you. I'll close this bug. (In reply to comment #11) > > This seems to change the order of how capture->target->bubbling progresses... > What do you think about this? > http://dvcs.w3.org/hg/webcomponents/rev/f46cfd9b0832
Let me note the order in both cases (in my original proposal and the current spec) for the record. Case I). If we register eventListener, using (useCapture=false), The events will be fired in the following order: 1) In my original proposal F - F - TARGET E - F - BUBBLE D - D - TARGET C - D - BUBBLE B - B - TARGET A - B - BUBBLE 2) In new proposal, B - B - TARGET D - D - TARGET F - F - TARGET E - F - BUBBLE C - D - BUBBLE A - B - BUBBLE Case II). If we register eventListener, using (useCapture=true), 1) In my original proposal: A - B - CAPTURE C - D - CAPTURE E - F - CAPTURE F - F - TARGET D - D - TARGET B - B - TARGET 2) In new proposal: A - B - CAPTURE B - B - TARGET C - D - CAPTURE D - D - TARGET E - F - CAPTURE F - F - TARGET Case III). If we register eventListener, using (useCapture=true), for non-bubble events 1) In my original proposal: A - B - CAPTURE B - B - TARGET C - D - CAPTURE D - D - TARGET E - F - CAPTURE F - F - TARGET 2) In new proposal: A - B - CAPTURE B - B - TARGET C - D - CAPTURE D - D - TARGET E - F - CAPTURE F - F - TARGET Case IV). If we register eventListener, using both (useCapture=true) and (useCapture=true) 1) In my original proposal: A - B - CAPTURE C - D - CAPTURE E - F - CAPTURE F - F - TARGET E - F - BUBBLE D - D - TARGET C - D - BUBBLE B - B - TARGET A - B - BUBBLE 2) In new proposal: A - B - CAPTURE B - B - TARGET C - D - CAPTURE D - D - TARGET E - F - CAPTURE F - F - TARGET E - F - BUBBLE C - D - BUBBLE A - B - BUBBLE