Skip to content
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

Token Input: Fix Firefox blur problems #6162

Merged
merged 7 commits into from
Jun 30, 2016
Merged

Token Input: Fix Firefox blur problems #6162

merged 7 commits into from
Jun 30, 2016

Conversation

marekhrabe
Copy link
Contributor

@marekhrabe marekhrabe commented Jun 20, 2016

Due to some browser event inconsistencies, in Firefox, there is a strange bug that makes TokenField steal focus back even after you selected another input and interacted with it.

Steps to reproduce

  • Use Firefox
  • Open up New post
  • Select tag input
  • Insert some tag
  • Focus Post title input and try to enter "test"
WordPress.com This Branch
dot-com-focus fix-branch

On WordPress, you should be only able to enter the first letter before tag input steals back the focus. This PR fixes that.


It is fixed by moving onBlur listener to <input> (instead of div) and adding preventDefault as a response to mouseDown on suggestion elements.

I tested this in Chrome, Safari and Firefox. I have not tested IE, I hope someone can.

Test live: https://calypso.live/?branch=fix/token-input-blur

Fixed by moving onBlur listener to input (instead of div) and adding preventDefault as a response to mouseDown on suggestion.
@marekhrabe marekhrabe added Framework [Feature] Post/Page Editor The editor for editing posts and pages. labels Jun 20, 2016
@marekhrabe marekhrabe self-assigned this Jun 20, 2016
@marekhrabe
Copy link
Contributor Author

There were three tests failing, I fixed one of them by editing it to test exactly what it describes and not to test side-effects of that action cc524a7. I removed a source of those side effects in this PR — clicking a suggestion no longer triggers blur, because it preventsDefault on mouseDown event. That allowed me to really simplify the problem here.

There are currently two failing tests left (they are both targeted specifically for Firefox), but honestly, I have no idea what to do with them. They test that if you can click anywhere in the field, the component will be activated. That seems to work in browsers (including Firefox) but it fails in tests.

It might be related to the fact, that I removed some onClick as by my other changes, it was rendered useless. There is no need to listen for onClick anymore because we listen for onFocus on the parent element and it catches clicks correctly. I think it is safe to remove those two tests, but I'd like some other opinion on that.

I saw that @gziolo wrote those tests and @nylen fixed some issues regarding the Firefox blur previously. Can any of you (or anyone else) help me test the functionality and give me your suggestion on removing tests? Thanks

@gziolo
Copy link
Member

gziolo commented Jun 21, 2016

I only refactored those tests to work with Enzyme. @nylen can confirm if it is okey to remove them.

BTW, you have 5 failing tests on Circle CI at the moment:

Your build ran 3351 tests with 5 failures

all of them complain about:

TypeError: this._clearBlurTimeout is not a function

@marekhrabe marekhrabe force-pushed the fix/token-input-blur branch from bcab96b to d3a03a7 Compare June 21, 2016 07:27
@marekhrabe
Copy link
Contributor Author

TypeError: this._clearBlurTimeout is not a function

Oh, thanks for noticing this one. I have made everything synchronous, so there is no need for the timeout anymore. However, I left one call there which caused tests to fail. It should be fine now. Only those 2 tests fail

@nylen
Copy link
Contributor

nylen commented Jun 21, 2016

Thanks for working on this. I would love to see this messy code removed, but there are some bugs with the current implementation.

In Chrome, if you type part of a tag, then click the post title, the tags input steals the focus. After that, if you click the tags input again, the current token is added (it seems the code gets confused about whether the field is active):

tokenfield-without-blur-handling

Same behavior in Safari, but everything seems to work well in Firefox.

I'd recommend getting an IE virtual machine from http://modern.ie/

This change also needs to be tested on mobile browsers. I ran through it on Android Chrome and iOS Safari (v8.2), everything seems OK on both of these. Do you have any others handy that you can test with?

I agree that the tests are tightly coupled to the implementation at the moment. Let's get everything working well then circle back around to the tests.

if ( this.refs.input && ! this.refs.input.hasFocus() ) {
debug( '_onClick focusing input' );
this.refs.input.focus();
debug( '_onBlur setting component inactive' );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the new _onBlur code is very simple we can remove this debug statement...

@gziolo
Copy link
Member

gziolo commented Jun 22, 2016

You have changed behavior of _onBlur handler. Those 2 failing tests simulate blur event, so that probably has some connection. I don't have time to investigate that further this week, I hope you can figure it out yourself ;)

@marekhrabe
Copy link
Contributor Author

@nylen Thanks a lot for finding the bug that slipped under my radar. The problem was that _addCurrentToken (which onBlur is calling), was checking state.isActive and forcing focus if it is true. I added a reset for isActive, just before calling _addCurrentToken. It seems to be working well now.

@nylen
Copy link
Contributor

nylen commented Jun 27, 2016

Found another bug... since the onBlur handler was moved from the div.token-field to the input we can trigger a blur by clicking on the div. I've added background: #fcc to the input to illustrate the issue.

@@ -94,6 +94,7 @@ var SuggestionsList = React.createClass( {
<li
className={ classes }
key={ suggestion }
onMouseDown={ this._handleMouseDown }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need onTouchStart here as well?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've tested this on the iPhone and mouseDown seems to do the job.

@nylen
Copy link
Contributor

nylen commented Jun 27, 2016

Took a shot at fixing the bug I noted above, and cleaned up the tests. Flipping to Needs Review.

@nylen nylen added [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. and removed [Status] In Progress labels Jun 27, 2016
@marekhrabe
Copy link
Contributor Author

Thanks for going ahead and fixing the problem & tests :)

I just tested this in Chrome, Firefox, macOS Safari, iOS Safari & IE11. It seems to work consistently everywhere now. I've been mainly testing to blur token input by different methods (clicking outside, clicking inside, click on suggestion, Tab) and I haven't found focus stealing anymore, which was the original problem this PR fixes. After a code review, I think this is ready to be merged.

@nylen nylen added [Status] Ready to Merge and removed [Status] Needs Review The PR is ready for review. This also triggers e2e canary tests and wp-desktop tests automatically. labels Jun 30, 2016
@nylen
Copy link
Contributor

nylen commented Jun 30, 2016

Nice work again, and thanks for taking another look!

@nylen nylen merged commit c4bc027 into master Jun 30, 2016
@nylen nylen deleted the fix/token-input-blur branch June 30, 2016 18:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Feature] Post/Page Editor The editor for editing posts and pages. Framework
Projects
None yet
4 participants