-
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
Title: Unselect title by blur event #2948
Conversation
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.
LGTM
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.
The problem with this change (I've already tried it) is that we can't click on the "Copy" permalink button anymore.
It's not an easy task to get right. I was hoping we could move Permalink Modal outside of the Post Title at some point to solve this issue
I've tried an approach to get the copy button to work as well. It is available here:#2974 The key parts are:
|
ca44284
to
464c45b
Compare
Codecov Report
@@ Coverage Diff @@
## master #2948 +/- ##
==========================================
- Coverage 32.31% 32.25% -0.06%
==========================================
Files 216 216
Lines 6137 6148 +11
Branches 1079 1080 +1
==========================================
Hits 1983 1983
- Misses 3505 3515 +10
- Partials 649 650 +1
Continue to review full report at Codecov.
|
464c45b
to
c562413
Compare
@ephox-mogran I cherry-picked some of your revisions in #2974 back into this pull request, specifically around assigning a custom container for the clipboard button textarea. Where this differs from #2974 is:
Future revisions I think we should make:
|
If react makes relatedTarget supported in all browsers that you need to support, that's a great solution. I was worried that it wouldn't be ... but maybe that information is out-of-date. The only reason I was doing the blurOutside HOC was because in the past when you get the blur event, you don't always know what the newly focused element is. If you do now, you can definitely do it this way. |
https://developer.mozilla.org/en-US/docs/Web/API/FocusEvent/relatedTarget#Browser_compatibility ...but I do recall at least one note about it being buggy in a specific version of Safari? In any case, we are using |
Yeah, it looks like all relevant browsers might support it now. |
Perhaps this is tangential, and it's certainly a bit late. But the permalink showing as a Title block toolbar is arguably a failed experiment (I'm allowed to say that as it was my idea). If we move the permalink to the Status bar, perhaps the newly merged publish dropdown, we can remove it from here. |
I'm still seeing the "copy" button bug where we can't click the button. But If we think we're moving this elsewhere after this PR, I'm ok with the simplest solution we had with the first commit. |
Hmm, are you sure you're running the latest version of the branch? Which browser are you using? |
Even if we simplify to remove the permalink from the title, I think some of the additional changes such as the clipboard button container are worth keeping to avoid future unexpected bugs. |
@aduth yep confirmed it's working properly on Chrome but not Firefox |
😩 Might just be better off making the effort to move the permalink elsewhere. |
c562413
to
553f546
Compare
Okay, tracked it down to Firefox not assigning the correct Should be working okay after 553f546 . Also did a rebase, so you may need to delete your local branch. |
I'd agree with @aduth , keeping the code to preserve the focus inside an expected container will save you trouble down the path. If you don't specify that container, then the clipboard library will transfer focus to a temporary textarea on the body, and that could active some of your blur/focus handling logic, and make it harder to track the flow of focus. |
Just another note on what seems to be happening with that clipboard library. We're now working against its expected use case again. There is a click handler that is put on container, that is responsible for removing the textarea that it creates. Now, because of the change to make that container a div that is beside the button that we are clicking to trigger it, that click on the button never bubbles to the container, so the textarea is not removed until the button is clicked again. It doesn't seem to be designed to work in the react ecosystem out of the box. Perhaps this library would be a better fit: https://github.com/nihey/react-clipboard.js (I haven't looked into it), though potentially it doesn't care about focus. We essentially need:
Or we could leave it like this, and just accept that the textarea will stay in the DOM until the next click event on the button. It's not visible, so that might be the best compromise. Or, potentially, look into another library. |
Nice investigative work @ephox-mogran . This is indeed tricky to handle. The library you reference doesn't seem to be much different than what we already have; in fact, it doesn't do anything about handling the container, so almost identical to the implementation prior to this pull request. As an alternative to letting the click event bubble to the container for clean-up, we might be able to manually handle the clean-up ourselves by binding to the |
Yeah, I was worried it would be more of the same. If you have access to the |
I was looking earlier today and I was having trouble accessing it. It should be available on |
So the other (theoretical) option is dispatching a simulated click event on the container after we've received the click on the button. What? Too hacky ;) ? |
553f546
to
b8eea4e
Compare
I tried a number of approaches here, including the mouse event, each not working exactly right. One of the main issues I didn't discover until later was that the removal of the fake textarea causes a blur event which was intercepted by the PostTitle field, causing it to trigger its unselection logic. In the latest approach I decided to revert closer to what exists in the current implementation, except with an added wrapping component to serve as the container for the fake textarea to be appended. In this way, the button click event still bubbles to the container and allows for the fake textarea cleanup. I think the original concern with this was whether React reconciliation would cause conflict with Clipboard's handlers, but I don't think there should ever be a case where React's reconciliation is destructive to manually assigned event handlers, and since Clipboard will immediately clean-up any of its own inserted textarea children, React should never observe any of these unexpected children. |
handleClickOutside() { | ||
this.setState( { isSelected: false } ); | ||
blurIfOutside( event ) { | ||
if ( ! this.nodes.container.contains( event.relatedTarget ) ) { |
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.
Shouldn't this mean that the textarea
blurring if filtered out? Why are you needing to stop propagation in the clipboard container? Is the relatedTarget not set?
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 turns out it isn't. I thought relatedTarget
was fragile. It may be that it is set in situations where something else has received a specific focus() call, and isn't set in situations where the focused element has been suddenly removed from the page and the body gets focus by default. In this situation, the active element seems to be body, but relatedTarget is nothing (when the textarea is removed).
Aside from being confused that the blurOutside isn't making a blur inside the textarea not call unselect, this looks good to me - but I'm probably just missing something. However, without the stop propagation, it doesn't work. The blurIfOutside isn't even called. Right, relatedTarget is null. This approach will work then. Because we can at least stop the blur propagating because we are controlling the container. |
@ephox-mogran Great feedback. Yes, the The better solution is to return focus to the triggering button before the fake textarea is removed, ensuring that it never leaves the title field. Digging through Clipboard's source, I find that they expose this directly via the Why this is not the default behavior I'm unsure, but it was simple enough for me to add this into the success callback and drop the |
Excellent. |
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.
Nice 🚢 it
Title: Detect blur outside root container node Components: Enable title wrapper as focusable Firefox won't include relatedTarget on blur event for div unless focusable. Assign as negative tab index to avoid creating a tab stop.
Components: Refactor ClipboardContainer to access sibling node Components: Move ClipboardButton callbacks to function Ensure that if props have changed since original mount, latest value is reflected at time of copy Components: Render clipboard button with wrapping container Components: Clear selection on clipboard button press Clearing selection will move focus back to the triggering button, ensuring that it is not reset to the body, and further that it is kept within the rendered node.
Was logging error when unselecting title after clicking copy since timeout was never canceled
5c342e3
to
8ef869d
Compare
Fixes #1390
This pull request seeks to resolve an issue where the post title retains selected styles when tabbing away, since the title had only become unselected when explicitly clicking outside. The changes here capture focus being lost by blur event, thereby capturing both click outside and tabbing.
Testing instructions:
Future tasks:
There are a few other easy wins in the title component:
Move(Allow going down to the editor from the post title using keyboard #2052) Edit: Was already included in Framework: Extract arrow navigation to its own component #2424<PostTitle />
to be handled within<WritingFlow />
to allow arrow navigation to move downward within content<PostTitle />
or<WritingFlow />
to create a new default block after (Pressing return in the title field does not create a block #1650)