Closed theengineear closed 1 year ago
FYI @charricknflx — I documented this issue that you came across and came up with what I think is a pretty straightforward repro.
So far, I haven't figured out what could go wrong. Additionally, I swapped the lines locally and ran our test suite — all checks still pass. There might be some very good reason not to set up listeners ahead of the initial render… but it hasn't dawned on me yet 😅
FYI @klebba — Not sure if this is something that you've ever come across. It's a pretty edge-y edge-case, but feels like it warrants attention.
Nice find and great context! Thanks @theengineear — I haven't come across this situation myself but my first thought is that it seems correct to ensure no events are missed. Out of curiosity how did we encounter the edge case? Either way, I would support making the change
my first thought is that it seems correct to ensure no events are missed
Yep. I'm leaning in the same direction on this one. Seems like the right fundamental position to ensure this for listeners setup through the system.
Out of curiosity how did we encounter the edge case?
In development, Chris had setup a validation system that works roughly like this:
<context-menu>
component is passed a JSON object which declares the setup for the entire menu.<context-menu-item>
are each passed their individual chunk of properties.observe
callback and fires an event.<context-menu>
listens to all the events, adds a path
for context, and re-dispatches a top-level event.It's hard, but possible to configure / render this DOM tree synchronously (if you have the demo set up just right) and there's an edge case where the top-level listeners miss the lower-level events.
And by "just right" above, note how in the top-level description's code snippet, we don't manually add document.body.append(document.createElement('parent-element'));
inside the script file. Again, it's an edge case, but I do think we should try and support it for consistency.
I see — that's interesting. Programmatically dispatched events (rather than user initiated) are typically avoidable in my experience, but again I wouldn't use that as a reason not to make this change
Closed by #126.
Because the initial render of an
x-element
is synchronous, events dispatched by children in their firstrender
orobserve
methods will not be heard by parent listeners!One solution would be to literally swap these lines in
x-element.js
:The obvious risk here is that we could introduce a race condition where a listener is expecting some DOM to exist before initialization is complete. I believe that shouldn't be possible though since the tree should be resolved depth-first — i.e., all the DOM should arrive just in time in this case.
Here's a repro html file (scroll to the bottom for the printout):
If you run that, you should see the following logs:
☝️ — See how
listening for "error" on parent element's shadow root
happens too late?