@samitouri / QOS-React-2 / commits / 1078029af6

Revert "Revert focus event PRs (#18655)" (#18671)

This reverts commit 58c895e59cd2822a9a7a67606d5fe7da5e09ba2a.

Dominic Gannaway committed Apr 20, 2020 at 16:00 UTC 1078029af6ecf9f85c5235e4323b853b78d86da0
4 files changed +56 -65
packages/react-dom/src/client/ReactDOMComponent.js
-4
@@ -1355,10 +1355,6 @@ export function listenToEventResponderEventTypes(
1355 const targetEventType = isPassive
1356 ? eventType
1357 : eventType.substring(0, eventType.length - 7);
1358 - // We don't listen to this as we actually emulate it in the host config
1359 - if (targetEventType === 'beforeblur') {
1360 - continue;
1361 - }
1358 if (!listenerMap.has(eventKey)) {
1359 if (isPassive) {
1360 const activeKey = targetEventType + '_active';
packages/react-dom/src/client/ReactDOMHostConfig.js
+2 -31
@@ -62,7 +62,6 @@ import {REACT_OPAQUE_ID_TYPE} from 'shared/ReactSymbols';
62 import {
63 mountEventResponder,
64 unmountEventResponder,
65 - DEPRECATED_dispatchEventForResponderEventSystem,
65 } from '../events/DeprecatedDOMEventResponderSystem';
66 import {retryIfBlockedOn} from '../events/ReactDOMEventReplaying';
67
@@ -74,8 +73,6 @@ import {
73 enableScopeAPI,
74 } from 'shared/ReactFeatureFlags';
75 import {
77 - RESPONDER_EVENT_SYSTEM,
78 - IS_PASSIVE,
76 PLUGIN_EVENT_SYSTEM,
77 USE_EVENT_SYSTEM,
78 } from '../events/EventSystemFlags';
@@ -528,22 +525,9 @@ function createEvent(type: TopLevelType): Event {
525 }
526
527 function dispatchBeforeDetachedBlur(target: HTMLElement): void {
531 - const targetInstance = getClosestInstanceFromNode(target);
528 ((selectionInformation: any): SelectionInformation).activeElementDetached = target;
529
534 - if (enableDeprecatedFlareAPI) {
535 - DEPRECATED_dispatchEventForResponderEventSystem(
536 - 'beforeblur',
537 - targetInstance,
538 - ({
539 - target,
540 - timeStamp: Date.now(),
541 - }: any),
542 - target,
543 - RESPONDER_EVENT_SYSTEM | IS_PASSIVE,
544 - );
545 - }
546 - if (enableUseEventAPI) {
530 + if (enableDeprecatedFlareAPI || enableUseEventAPI) {
531 const event = createEvent(TOP_BEFORE_BLUR);
532 // Dispatch "beforeblur" directly on the target,
533 // so it gets picked up by the event system and
@@ -553,20 +537,7 @@ function dispatchBeforeDetachedBlur(target: HTMLElement): void {
537 }
538
539 function dispatchAfterDetachedBlur(target: HTMLElement): void {
556 - if (enableDeprecatedFlareAPI) {
557 - DEPRECATED_dispatchEventForResponderEventSystem(
558 - 'blur',
559 - null,
560 - ({
561 - isTargetAttached: false,
562 - target,
563 - timeStamp: Date.now(),
564 - }: any),
565 - target,
566 - RESPONDER_EVENT_SYSTEM | IS_PASSIVE,
567 - );
568 - }
569 - if (enableUseEventAPI) {
540 + if (enableDeprecatedFlareAPI || enableUseEventAPI) {
541 const event = createEvent(TOP_AFTER_BLUR);
542 // So we know what was detached, make the relatedTarget the
543 // detached target on the "afterblur" event.
packages/react-interactions/events/src/dom/DeprecatedFocus.js
+39 -15
@@ -22,7 +22,7 @@ import {DiscreteEvent} from 'shared/ReactTypes';
22 */
23
24 type FocusEvent = {|
25 - isTargetAttached: boolean,
25 + relatedTarget: null | Element | Document,
26 target: Element | Document,
27 type: FocusEventType | FocusWithinEventType,
28 pointerType: PointerType,
@@ -53,6 +53,7 @@ type FocusEventType = 'focus' | 'blur' | 'focuschange' | 'focusvisiblechange';
53 type FocusWithinProps = {
54 disabled?: boolean,
55 onFocusWithin?: (e: FocusEvent) => void,
56 + onAfterBlurWithin?: (e: FocusEvent) => void,
57 onBeforeBlurWithin?: (e: FocusEvent) => void,
58 onBlurWithin?: (e: FocusEvent) => void,
59 onFocusWithinChange?: boolean => void,
@@ -65,7 +66,8 @@ type FocusWithinEventType =
66 | 'focuswithinchange'
67 | 'blurwithin'
68 | 'focuswithin'
68 - | 'beforeblurwithin';
69 + | 'beforeblurwithin'
70 + | 'afterblurwithin';
71
72 /**
73 * Shared between Focus and FocusWithin
@@ -116,8 +118,7 @@ const focusVisibleEvents = hasPointerEvents
118
119 const targetEventTypes = ['focus', 'blur', 'beforeblur', ...focusVisibleEvents];
120
119 -// Used only for the blur "detachedTarget" logic
120 -const rootEventTypes = ['blur'];
121 +const rootEventTypes = ['afterblur'];
122
123 function addWindowEventListener(types, callback, options) {
124 types.forEach(type => {
@@ -192,10 +193,10 @@ function createFocusEvent(
193 type: FocusEventType | FocusWithinEventType,
194 target: Element | Document,
195 pointerType: PointerType,
195 - isTargetAttached: boolean,
196 + relatedTarget: null | Element | Document,
197 ): FocusEvent {
198 return {
198 - isTargetAttached,
199 + relatedTarget,
200 target,
201 type,
202 pointerType,
@@ -297,7 +298,7 @@ function dispatchFocusEvents(
298 'focus',
299 target,
300 pointerType,
300 - true,
301 + null,
302 );
303 context.dispatchEvent(syntheticEvent, onFocus, DiscreteEvent);
304 }
@@ -321,7 +322,7 @@ function dispatchBlurEvents(
322 'blur',
323 target,
324 pointerType,
324 - true,
325 + null,
326 );
327 context.dispatchEvent(syntheticEvent, onBlur, DiscreteEvent);
328 }
@@ -346,7 +347,7 @@ function dispatchFocusWithinEvents(
347 'focuswithin',
348 target,
349 pointerType,
349 - true,
350 + null,
351 );
352 context.dispatchEvent(syntheticEvent, onFocusWithin, DiscreteEvent);
353 }
@@ -361,19 +362,39 @@ function dispatchBlurWithinEvents(
362 const pointerType = state.pointerType;
363 const target = ((state.focusTarget: any): Element | Document) || event.target;
364 const onBlurWithin = (props.onBlurWithin: any);
364 - const isTargetAttached = state.detachedTarget === null;
365 if (isFunction(onBlurWithin)) {
366 const syntheticEvent = createFocusEvent(
367 context,
368 'blurwithin',
369 target,
370 pointerType,
371 - isTargetAttached,
371 + null,
372 );
373 context.dispatchEvent(syntheticEvent, onBlurWithin, DiscreteEvent);
374 }
375 }
376
377 +function dispatchAfterBlurWithinEvents(
378 + context: ReactDOMResponderContext,
379 + event: ReactDOMResponderEvent,
380 + props: FocusWithinProps,
381 + state: FocusState,
382 +) {
383 + const pointerType = state.pointerType;
384 + const onAfterBlurWithin = (props.onAfterBlurWithin: any);
385 + const relatedTarget = state.detachedTarget;
386 + if (isFunction(onAfterBlurWithin) && relatedTarget !== null) {
387 + const syntheticEvent = createFocusEvent(
388 + context,
389 + 'afterblurwithin',
390 + relatedTarget,
391 + pointerType,
392 + relatedTarget,
393 + );
394 + context.dispatchEvent(syntheticEvent, onAfterBlurWithin, DiscreteEvent);
395 + }
396 +}
397 +
398 function dispatchFocusChange(
399 context: ReactDOMResponderContext,
400 props: FocusProps,
@@ -616,7 +637,7 @@ const focusWithinResponderImpl = {
637 'beforeblurwithin',
638 event.target,
639 state.pointerType,
619 - true,
640 + null,
641 );
642 state.detachedTarget = event.target;
643 context.dispatchEvent(
@@ -660,10 +681,13 @@ const focusWithinResponderImpl = {
681 props: FocusWithinProps,
682 state: FocusState,
683 ): void {
663 - if (event.type === 'blur') {
684 + if (event.type === 'afterblur') {
685 const detachedTarget = state.detachedTarget;
665 - if (detachedTarget !== null && detachedTarget === event.target) {
666 - dispatchBlurWithinEvents(context, event, props, state);
686 + if (
687 + detachedTarget !== null &&
688 + detachedTarget === event.nativeEvent.relatedTarget
689 + ) {
690 + dispatchAfterBlurWithinEvents(context, event, props, state);
691 state.detachedTarget = null;
692 if (state.addedRootEvents) {
693 state.addedRootEvents = false;
packages/react-interactions/events/src/dom/__tests__/FocusWithin-test.internal.js
+15 -15
@@ -290,11 +290,11 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
290 });
291
292 describe('onBeforeBlurWithin', () => {
293 - let onBeforeBlurWithin, onBlurWithin, ref, innerRef, innerRef2;
293 + let onBeforeBlurWithin, onAfterBlurWithin, ref, innerRef, innerRef2;
294
295 beforeEach(() => {
296 onBeforeBlurWithin = jest.fn();
297 - onBlurWithin = jest.fn();
297 + onAfterBlurWithin = jest.fn();
298 ref = React.createRef();
299 innerRef = React.createRef();
300 innerRef2 = React.createRef();
@@ -305,7 +305,7 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
305 const Component = ({show}) => {
306 const listener = useFocusWithin({
307 onBeforeBlurWithin,
308 - onBlurWithin,
308 + onAfterBlurWithin,
309 });
310 return (
311 <div ref={ref} DEPRECATED_flareListeners={listener}>
@@ -322,12 +322,12 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
322 target.keydown({key: 'Tab'});
323 target.focus();
324 expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
325 - expect(onBlurWithin).toHaveBeenCalledTimes(0);
325 + expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);
326 ReactDOM.render(<Component show={false} />, container);
327 expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);
328 - expect(onBlurWithin).toHaveBeenCalledTimes(1);
329 - expect(onBlurWithin).toHaveBeenCalledWith(
330 - expect.objectContaining({isTargetAttached: false}),
328 + expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);
329 + expect(onAfterBlurWithin).toHaveBeenCalledWith(
330 + expect.objectContaining({relatedTarget: inner}),
331 );
332 });
333
@@ -336,7 +336,7 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
336 const Component = ({show}) => {
337 const listener = useFocusWithin({
338 onBeforeBlurWithin,
339 - onBlurWithin,
339 + onAfterBlurWithin,
340 });
341 return (
342 <div ref={ref} DEPRECATED_flareListeners={listener}>
@@ -357,12 +357,12 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
357 target.keydown({key: 'Tab'});
358 target.focus();
359 expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
360 - expect(onBlurWithin).toHaveBeenCalledTimes(0);
360 + expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);
361 ReactDOM.render(<Component show={false} />, container);
362 expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);
363 - expect(onBlurWithin).toHaveBeenCalledTimes(1);
364 - expect(onBlurWithin).toHaveBeenCalledWith(
365 - expect.objectContaining({isTargetAttached: false}),
363 + expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);
364 + expect(onAfterBlurWithin).toHaveBeenCalledWith(
365 + expect.objectContaining({relatedTarget: inner}),
366 );
367 });
368
@@ -418,7 +418,7 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
418 const Component = ({show}) => {
419 const listener = useFocusWithin({
420 onBeforeBlurWithin,
421 - onBlurWithin,
421 + onAfterBlurWithin,
422 });
423
424 return (
@@ -444,7 +444,7 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
444 target.keydown({key: 'Tab'});
445 target.focus();
446 expect(onBeforeBlurWithin).toHaveBeenCalledTimes(0);
447 - expect(onBlurWithin).toHaveBeenCalledTimes(0);
447 + expect(onAfterBlurWithin).toHaveBeenCalledTimes(0);
448
449 suspend = true;
450 root.render(<Component />);
@@ -454,7 +454,7 @@ describe.each(table)('FocusWithin responder', hasPointerEvents => {
454 '<div><input style="display: none;">Loading...</div>',
455 );
456 expect(onBeforeBlurWithin).toHaveBeenCalledTimes(1);
457 - expect(onBlurWithin).toHaveBeenCalledTimes(1);
457 + expect(onAfterBlurWithin).toHaveBeenCalledTimes(1);
458 resolve();
459
460 document.body.removeChild(container2);