-
Notifications
You must be signed in to change notification settings - Fork 4.2k
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
Try/use focus outside iframe #52040
Try/use focus outside iframe #52040
Conversation
c4d0561
to
fbeed05
Compare
Size Change: +161 B (0%) Total Size: 1.44 MB
ℹ️ View Unchanged
|
|
||
await waitForElementToBeRemoved( confirmDialog ); | ||
|
||
expect( confirmDialog ).not.toBeInTheDocument(); | ||
expect( onCancel ).toHaveBeenCalled(); | ||
await waitFor( () => expect( onCancel ).toHaveBeenCalled() ); |
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.
Due to the extra logic and changes in timeout, a few more callbacks related to onFocusOutside
will fire with a bigger delay
Flaky tests detected in 6e7c669. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/5404653930
|
// blur events will fire as expected. | ||
setPollingData( null ); | ||
} | ||
}, 50 ); |
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.
Using 50ms here because it's a sweet spot between not running the internal too frequently, but running it frequently enough that it still feels responsive to users.
// the timeout delay is necessary to wait for browser's focus event to | ||
// fire after the blur event, and therefore for this callback to be able | ||
// to retrieve the correct document.activeElement. | ||
}, 50 ); |
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.
This is a bit hacky, but I didn't have any easy solution for it (and didn't want to spend a lot of time trying to find one).
There may be some related e2e test failures, although it may just be the case to wait for callbacks / dom changes to fire asynchronously (similarly to some of the changes that this PR already includes for unit tests). Regardless, if y'all think that this approach is promising, feel free to take over (cc @stokesman / @t-hamano ). I may not have much time to work on this in the upcoming couple of months. |
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.
This is testing well for me, but I'll hold on of approving while other check it out as well
I tested this on an iPhone 14 Pro simulator and Pixel 3 XL emulator, both functioned as I expected. Additionally, it appears the proposed changes to not modify the native-specific file. So, I believe this looks good from the mobile editor perspective. 🚀 |
Can I test this without building locally? Do not have my Mac on vacation and still trying to get my Windows dev environment running. Vacation might be over by then. 😆 |
@alexstine Not Storybook, but I think the editor can be tested with the Gutenberg PR Previewer. |
) { | ||
// If focus is not inside the wrapper (but the document is in focus), | ||
// we can fire the `onFocusOutside` callback and stop polling. | ||
currentOnFocusOutside.current( event ); |
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.
It's maybe odd to pass the event stored from the last blur
that caused polling to begin. I don't know that it matters for any current use case but it's not actually the event that causes this invocation of the callback.
It looks like we're going to continue with the proposed approach in #51602, therefore I'm going to close this PR. We can always keep this work in mind in case the |
What?
Supersedes #45349
Fixes #40912
Why?
The
useFocusOutside
hook doesn't currently behave as expected when focus moves to aniframe
element inside the container element setting the boundaries for the hook (see related issue for an example)How?
By adding a check, in the blur event, to see if the active element is a child of the wrapper element that we're trying to detect focus outside of.
But when the
iframe
is in focus, the blur event would not fire as expected. That's why, un case the active element is aniframe
, I added extra code to activate a temporary polling function, which checks every 50ms if focus has effectively left the wrapper element.I will highlight a few more details of my changes with inline comments.
Testing Instructions
On Storybook:
ConfirmDialog
example works as expectedPaletteEdit
behaves as expected:onFocusOutside
prop is called as expected (see theModal
component testing instructions above)In the editor:
In the native editor (cc @geriux @dcalhoun @fluiddot )
Known bug
while testing on my machine, I noticed that on MacOS Safari focus is simply not trapped inside the modal. That seems to also happen on
trunk
, so we should probably open a separate issue and treat this separately.Screenshots or screencast
use-focus-outside.mp4