Skip to content

Commit 025b07b

Browse files
authored
[Flare] Ensure getAbsoluteBoundingClientRect aligns with offsetParent (#15720)
1 parent 61f6224 commit 025b07b

File tree

2 files changed

+24
-13
lines changed

2 files changed

+24
-13
lines changed

packages/react-events/src/Press.js

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,18 @@ function calculateDelayMS(delay: ?number, min = 0, fallback = 0) {
426426
return Math.max(min, maybeNumber != null ? maybeNumber : fallback);
427427
}
428428

429+
function isNodeFixedPositioned(node: Node | null | void): boolean {
430+
return (
431+
node != null &&
432+
(node: any).offsetParent === null &&
433+
!isNodeDocumentNode(node.parentNode)
434+
);
435+
}
436+
437+
function isNodeDocumentNode(node: Node | null | void): boolean {
438+
return node != null && node.nodeType === Node.DOCUMENT_NODE;
439+
}
440+
429441
function getAbsoluteBoundingClientRect(
430442
target: Element,
431443
): {left: number, right: number, bottom: number, top: number} {
@@ -440,25 +452,23 @@ function getAbsoluteBoundingClientRect(
440452
const parent = node.parentNode;
441453
const scrollTop = (node: any).scrollTop;
442454
const scrollLeft = (node: any).scrollLeft;
443-
const isParentDocumentNode =
444-
parent != null && parent.nodeType === Node.DOCUMENT_NODE;
445-
446-
// Check if the current node is fixed position, by using
447-
// offsetParent node for a fast-path. Then we need to
448-
// check if it's a scrollable container by checking if
449-
// either scrollLeft or scrollTop are not 0. If it is
450-
// a scrollable container and the parent node is not
451-
// the document, then we can stop traversing the tree.
455+
456+
// We first need to check if it's a scrollable container by
457+
// checking if either scrollLeft or scrollTop are not 0.
458+
// Then we check if either the current node or its parent
459+
// are fixed position, using offsetParent node for a fast-path.
460+
// We need to check both as offsetParent accounts for both
461+
// itself and the parent; so we need to align with that API.
462+
// If these all pass, we can stop traversing the tree.
452463
if (
453-
!isParentDocumentNode &&
454-
(node: any).offsetParent === null &&
455-
(scrollLeft !== 0 || scrollTop !== 0)
464+
(scrollLeft !== 0 || scrollTop !== 0) &&
465+
(isNodeFixedPositioned(parent) || isNodeFixedPositioned(node))
456466
) {
457467
break;
458468
}
459469
offsetX += scrollLeft;
460470
offsetY += scrollTop;
461-
if (isParentDocumentNode) {
471+
if (isNodeDocumentNode(parent)) {
462472
break;
463473
}
464474
node = parent;

packages/react-events/src/__tests__/Press-test.internal.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,6 +1167,7 @@ describe('Event responder: Press', () => {
11671167

11681168
// The fixed container is not scrolled
11691169
fixedDiv.scrollTop = 0;
1170+
fixedDiv.scrollLeft = 0;
11701171
ref.current.getBoundingClientRect = getBoundingClientRectMock;
11711172
// Emulate the <html> element being offset with scroll
11721173
document.firstElementChild.scrollTop = 1000;

0 commit comments

Comments
 (0)