-
Notifications
You must be signed in to change notification settings - Fork 50.4k
Remove dependency on fbjs/lib/EventListener and fbjs/lib/focusNode #10592
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
Conversation
Inline the part that we actually use. Drop IE8 polyfill and unsubscription code.
Stack still depends on the return value. I just inline this into Stack version since we don't really care about it.
|
|
||
| trapBubbledEvent: function(topLevelType, handlerBaseName, handle) { | ||
| return ReactDOMEventListener.trapBubbledEvent( | ||
| ReactDOMEventListener.trapBubbledEvent( |
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.
Fiber codebase doesn't use return value (which is always allocating an object).
| } | ||
| return EventListener.listen( | ||
| element, | ||
| element.addEventListener( |
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 only case in which this wouldn't be equivalent is if element is truthy but not a DOM node. Doesn't seem like this could happen.
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.
Would it make sense to throw if element is falsy? I don't think there's any current code path where trapBubbledEvent or trapCaptureEvent should be called without a node.
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 think EventListener gets shimmed in www?
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.
There exists a mobile version that wraps into TimeSlice guards but we don't use it. At least not since flat bundles. Nobody complained.
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'm curious about when element is null here too and would +1 an invariant or an action item to investigate this.
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 don't think an invariant is very valuable here because it's a leaf code path (throws immediately with a very obvious message).
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.
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.
Aah, I get it now. We leave fbjs/lib/EventListener import in the www flat bundle, which actually redirects to the internal EventListener fork.
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.
@gaearon what throws immediately? If this is protected from null elements earlier in the code path could we just remove the falsy check?
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.
@aweary Yes I think we can.
| expect(setEventListeners.length).toEqual(dependencies.length); | ||
|
|
||
| for (i = 0; i < setEventListeners.length; i++) { | ||
| expect(dependencies.indexOf(setEventListeners[i])).toBeTruthy(); |
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 deleted this set of assertions. I'm not sure what they're supposed to be testing but they didn't work in the first place.
The intention was probably to match whether an array contains an item, but toBeTruthy() check passes for -1. And -1 is exactly what we get on master because dependencies array looks like this:
[ 'topBlur',
'topChange',
'topClick',
'topFocus',
'topInput',
'topKeyDown',
'topKeyUp',
'topSelectionChange' ]but value being tested looks like
'blur'Maybe there's some better way to test this but I figured just asserting the count is enough.
| case 'object': | ||
| inst._wrapperState.listeners = [ | ||
| ReactBrowserEventEmitter.trapBubbledEvent('topLoad', 'load', node), | ||
| trapBubbledEvent('topLoad', 'load', node), |
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.
Stack code still relies on return value for unsubscribing. Fiber doesn't. I inlined the old Stack-friendly version right into Stack.
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.
How does Fiber handle removing those listeners on unmount? Does it just not do that anymore?
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 think it doesn't. Relies on GC to clean them up.
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.
At some point I need to circle back about this on #9333. We need local listeners and I'm trying to figure out the best way to clean them up.
| } | ||
| for (i = 0; i < captureCalls.length; i++) { | ||
| setEventListeners.push(captureCalls[i][1]); | ||
| } |
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.
Deleted this aggregation because it goes through the same code path now.
| var AutoFocusUtils = { | ||
| focusDOMComponent: function() { | ||
| focusNode(ReactDOMComponentTree.getNodeFromInstance(this)); | ||
| ReactDOMComponentTree.getNodeFromInstance(this).focus(); |
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 Stack-only codepath.
nhunzaker
left a 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.
Fantastic update, 👍
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.
Don't think the EventListener change is right; see https://fburl.com/8jv38orh. It's important for error logging.
|
Probably abandoning—seems like adding injection to work around internal hijack of |
|
We can still get rid of focusNode! |
It's pretty small but still unnecessary indirection now that we don't support IE8.
See inline comments.