Skip to content

Commit 1160b37

Browse files
authored
Event API: Add responder allowMultipleHostChildren flag (#15646)
1 parent 95e06ac commit 1160b37

11 files changed

Lines changed: 366 additions & 243 deletions

File tree

packages/react-dom/src/events/DOMEventResponderSystem.js

Lines changed: 34 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ import {
1616
EventComponent,
1717
EventTarget as EventTargetWorkTag,
1818
HostComponent,
19-
SuspenseComponent,
20-
Fragment,
2119
} from 'shared/ReactWorkTags';
2220
import type {
2321
ReactEventResponder,
@@ -34,6 +32,10 @@ import warning from 'shared/warning';
3432
import {enableEventAPI} from 'shared/ReactFeatureFlags';
3533
import {invokeGuardedCallbackAndCatchFirstError} from 'shared/ReactErrorUtils';
3634
import invariant from 'shared/invariant';
35+
import {
36+
isFiberSuspenseAndTimedOut,
37+
getSuspenseFallbackChild,
38+
} from 'react-reconciler/src/ReactFiberEvents';
3739

3840
import {getClosestInstanceFromNode} from '../client/ReactDOMComponentTree';
3941

@@ -351,50 +353,11 @@ const eventResponderContext: ReactResponderContext = {
351353
validateResponderContext();
352354
const focusableElements = [];
353355
const eventComponentInstance = ((currentInstance: any): ReactEventComponentInstance);
354-
let node = ((eventComponentInstance.currentFiber: any): Fiber).child;
355-
356-
while (node !== null) {
357-
if (node.tag === SuspenseComponent) {
358-
const suspendedChild = isFiberSuspenseAndTimedOut(node)
359-
? getSuspenseFallbackChild(node)
360-
: getSuspenseChild(node);
361-
if (suspendedChild !== null) {
362-
node = suspendedChild;
363-
continue;
364-
}
365-
} else {
366-
if (isFiberHostComponentFocusable(node)) {
367-
focusableElements.push(node.stateNode);
368-
} else {
369-
const child = node.child;
356+
const child = ((eventComponentInstance.currentFiber: any): Fiber).child;
370357

371-
if (child !== null) {
372-
node = child;
373-
continue;
374-
}
375-
}
376-
}
377-
const sibling = node.sibling;
378-
379-
if (sibling !== null) {
380-
node = sibling;
381-
continue;
382-
}
383-
let parent;
384-
if (isFiberSuspenseChild(node)) {
385-
parent = getSuspenseFiberFromChild(node);
386-
} else {
387-
parent = node.return;
388-
if (parent === null) {
389-
break;
390-
}
391-
}
392-
if (parent.stateNode === currentInstance) {
393-
break;
394-
}
395-
node = parent.sibling;
358+
if (child !== null) {
359+
collectFocusableElements(child, focusableElements);
396360
}
397-
398361
return focusableElements;
399362
},
400363
getActiveDocument,
@@ -455,6 +418,33 @@ const eventResponderContext: ReactResponderContext = {
455418
},
456419
};
457420

421+
function collectFocusableElements(
422+
node: Fiber,
423+
focusableElements: Array<HTMLElement>,
424+
): void {
425+
if (isFiberSuspenseAndTimedOut(node)) {
426+
const fallbackChild = getSuspenseFallbackChild(node);
427+
if (fallbackChild !== null) {
428+
collectFocusableElements(fallbackChild, focusableElements);
429+
}
430+
} else {
431+
if (isFiberHostComponentFocusable(node)) {
432+
focusableElements.push(node.stateNode);
433+
} else {
434+
const child = node.child;
435+
436+
if (child !== null) {
437+
collectFocusableElements(child, focusableElements);
438+
}
439+
}
440+
}
441+
const sibling = node.sibling;
442+
443+
if (sibling !== null) {
444+
collectFocusableElements(sibling, focusableElements);
445+
}
446+
}
447+
458448
function isTargetWithinEventComponent(target: Element | Document): boolean {
459449
validateResponderContext();
460450
if (target != null) {
@@ -605,41 +595,6 @@ export function processEventQueue(): void {
605595
}
606596
}
607597

608-
function isFiberSuspenseAndTimedOut(fiber: Fiber): boolean {
609-
return fiber.tag === SuspenseComponent && fiber.memoizedState !== null;
610-
}
611-
612-
function isFiberSuspenseChild(fiber: Fiber | null): boolean {
613-
if (fiber === null) {
614-
return false;
615-
}
616-
const parent = fiber.return;
617-
if (parent !== null && parent.tag === Fragment) {
618-
const grandParent = parent.return;
619-
620-
if (
621-
grandParent !== null &&
622-
grandParent.tag === SuspenseComponent &&
623-
grandParent.stateNode !== null
624-
) {
625-
return true;
626-
}
627-
}
628-
return false;
629-
}
630-
631-
function getSuspenseFiberFromChild(fiber: Fiber): Fiber {
632-
return ((((fiber.return: any): Fiber).return: any): Fiber);
633-
}
634-
635-
function getSuspenseFallbackChild(fiber: Fiber): Fiber | null {
636-
return ((((fiber.child: any): Fiber).sibling: any): Fiber).child;
637-
}
638-
639-
function getSuspenseChild(fiber: Fiber): Fiber | null {
640-
return (((fiber.child: any): Fiber): Fiber).child;
641-
}
642-
643598
function getTargetEventTypesSet(
644599
eventTypes: Array<ReactEventResponderEventType>,
645600
): Set<string> {

0 commit comments

Comments
 (0)