-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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
Block Editor: Consider events only from DOM descendents (WritingFlow, ObserveTyping) #19879
Conversation
This is great. I’ll review tomorrow if I find some time |
event.stopPropagation(); | ||
|
||
if ( keyCode === ENTER ) { | ||
|
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.
Huh
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.
🤷♂ #19458 (comment)
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.
I noticed this and removed it in #19775.
Not sure how it happened. Sorry!
The failing end-to-end tests could be legitimate, based on the error message, since the new code checks DOM descendent by
Not sure how the |
…Typing Originally necessary to avoid events being interprted by ObserveTyping, WritingFlow. These components now explicitly consider whether the event occurred in the same DOM hierarchy, where the elements rendered here would presumably be rendered outside (Popover, Slot/Fill, etc).
4994912
to
46a8e28
Compare
I've rebased this after merging #19881, so the The test failure was quite bizarre. From debugging, the In any case, it occurred to me there's a better implementation here anyways, avoiding the ref altogether and simply using event.currentTarget, which should be effectively the same as what we're wanting, but more closely associated with the event and the DOM, and is slightly simpler code. See changes in 46a8e28. |
This isn't viable without changing how we approach navigation mode tabbing: gutenberg/packages/block-editor/src/components/writing-flow/index.js Lines 325 to 354 in 9e3c713
The problem is: The Tab event originates from the toolbar button: ...which is now rendered in a Popover as of #19564. And these are the exact sorts of events we're otherwise wanting to ignore. The issue can be reproduced following this test case: gutenberg/packages/e2e-tests/specs/editor/various/keyboard-navigable-blocks.test.js Lines 107 to 134 in 9e3c713
Essentially, the Tab might skip over the logic to focus the next block's label, and instead circle back to the title. A few thoughts on how to approach this:
|
@aduth Trying to understand the issue here: is the problem that the breadcrumb button is not part of the DOM tree or that it is not part of the React tree? |
It's a problem because it's not part of the DOM tree (it is not a DOM descendent of WritingFlow wrapper). |
I see two options.
I find the latter more intuitive since when you're navigating content, focus also moves from block to block. This also ensures that all logic is kept within the I don't really understand why focus is set on a button in navigation mode right now. @youknowriad @MarcoZehe do you remember the reasons behind that? |
This is not an option for navigation mode because it breaks to have keyboard event handlers on non-button elements (div) in some windows screen readers (NVDA I think). That's the main reason the navigation mode was added a bit late. |
That's strange. We currently already have keyboard event handlers on |
Probably not unless that element has a specific role. The specificity here is that this feature was specifically dedicated to a11y users so it didn't make sense for these handlers to not work on all screen readers. |
In #27489, I wrote the missing piece for this PR: moving navigation logic from writing flow to the block selection button (the focussed element in navigation mode). Previously I also rewrote the typing observer as a hook in #27043 (which now only listens for events of DOM descendants). @aduth, thanks for creating this PR. :) |
Alternative to: #19804
This pull request seeks to improve upon how events are interpreted by WritingFlow and ObserveTyping. Historically, we have often resorted to
Event#stopPropagation
within many components for the sole purpose of avoiding this top-level event handling, but this is problematic for a number of reasons:Event#stopPropagation
is an extreme solution and often introduces a lot of unintended incompatibilities and interoperability issues. It should be avoided whenever possible.URLInput
(@wordpress/components
) establishes a dependency on both its editor ancestry (@wordpress/block-editor
WritingFlow
,ObserveTyping
) and an assumption that it is shown inPopover
, despite the fact it is intended to be a general-purpose component.In some of the discussion from #19804 (comment) , it is considered that it might be possible to consider the various dialog components (
Popover
,Modal
) as entirely separate contexts and to not allow events to bubble through to its ancestor components. In some ways, this aligns with its implementation using Slot/Fill, where the intention of rendering the dialogs elsewhere in the DOM is largely to treat it as being positioned independently from its ancestors (in practical terms, to avoid CSS cascading styles).The implementation here achieves this by considering whether the events handled by ObserveTyping and WritingFlow originate from within its own DOM hierarchy. This is meant to be distinguished from event bubbling which occurs through the React hierarchy, and provides an opportunity for any components which do not want to be subject to this handling to avoid detection by rendering elsewhere in the DOM. In the case of popovers, this happens by virtue of the fact that they are rendered using
Slot
andFill
components.Testing Instructions:
Verify that affected components continue to work as expected, notably that: