From d9ce8a1a8b8d7d3acf72a2cae76b1f23236dcf95 Mon Sep 17 00:00:00 2001 From: Jon Surrell Date: Thu, 3 Dec 2020 14:38:36 +0100 Subject: [PATCH] Popover: Fix issue with undefined getBoundingClientRect (#27445) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix an issue where the `Popover` component throws a runtime `TypeError: Cannot read property 'getBoundingClientRect' of undefined.` This may happen in WordPress if a Popover is rendered in an iframe. It's been observed by rendering a `BlockList` component containing `RichText` in an iframe 😵 The issue is that `instanceof` checks fail across iframe boundaries, where `anchorRef instanceof window.Element` fails because `anchorRef` when it _is_ an instance of Element in the frame but not `window.Element`. Instead of `instanceof` checks that fail across iframe boundaries, check for expected methods as the predicate. --- packages/components/src/popover/index.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/components/src/popover/index.js b/packages/components/src/popover/index.js index a71c6cc6ad895..6063c11c04e62 100644 --- a/packages/components/src/popover/index.js +++ b/packages/components/src/popover/index.js @@ -71,11 +71,17 @@ function computeAnchorRect( return; } - if ( anchorRef instanceof window.Range ) { + // Duck-type to check if `anchorRef` is an instance of Range + // `anchorRef instanceof window.Range` checks will break across document boundaries + // such as in an iframe + if ( typeof anchorRef?.cloneRange === 'function' ) { return getRectangleFromRange( anchorRef ); } - if ( anchorRef instanceof window.Element ) { + // Duck-type to check if `anchorRef` is an instance of Element + // `anchorRef instanceof window.Element` checks will break across document boundaries + // such as in an iframe + if ( typeof anchorRef?.getBoundingClientRect === 'function' ) { const rect = anchorRef.getBoundingClientRect(); if ( shouldAnchorIncludePadding ) {