From 75c78313be79c41616e92f61651e0f499e0997bf Mon Sep 17 00:00:00 2001 From: atomiks Date: Fri, 1 May 2020 15:19:07 +1000 Subject: [PATCH 1/2] fix: root rects --- src/dom-utils/getDocumentRect.js | 17 +++++++++++++---- src/dom-utils/getViewportRect.js | 12 +++++++----- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/dom-utils/getDocumentRect.js b/src/dom-utils/getDocumentRect.js index 815cae59fa..8fd10d4bf5 100644 --- a/src/dom-utils/getDocumentRect.js +++ b/src/dom-utils/getDocumentRect.js @@ -1,17 +1,26 @@ // @flow import type { Rect } from '../types'; import getDocumentElement from './getDocumentElement'; +import getComputedStyle from './getComputedStyle'; +import getWindowScrollBarX from './getWindowScrollBarX'; import getWindowScroll from './getWindowScroll'; +// Gets the entire size of the scrollable document area, even extending outside +// of the `` and `` rect bounds if horizontally scrollable export default function getDocumentRect(element: HTMLElement): Rect { - const winScroll = getWindowScroll(element); const html = getDocumentElement(element); + const winScroll = getWindowScroll(element); const body = element.ownerDocument.body; - const width = Math.max(html.clientWidth, body ? body.clientWidth : 0); - const height = Math.max(html.clientHeight, body ? body.clientHeight : 0); - const x = -winScroll.scrollLeft; + const width = Math.max(html.scrollWidth, body ? body.scrollWidth : 0); + const height = Math.max(html.scrollHeight, body ? body.scrollHeight : 0); + + let x = -winScroll.scrollLeft + getWindowScrollBarX(element); const y = -winScroll.scrollTop; + if (getComputedStyle(body || html).direction === 'rtl') { + x += Math.max(html.clientWidth, body ? body.clientWidth : 0) - width; + } + return { width, height, x, y }; } diff --git a/src/dom-utils/getViewportRect.js b/src/dom-utils/getViewportRect.js index c14326b036..44421f848a 100644 --- a/src/dom-utils/getViewportRect.js +++ b/src/dom-utils/getViewportRect.js @@ -25,11 +25,13 @@ export default function getViewportRect(element: Element) { // Uses Layout Viewport (like Chrome; Safari does not currently) // In Chrome, it returns a value very close to 0 (+/-) but contains rounding // errors due to floating point numbers, so we need to check precision. - // Safari returns a number <= 0, usually <= 1 when pinch-zoomed - if ( - Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) < - 0.001 - ) { + // Safari returns a number <= 0, usually < -1 when pinch-zoomed + + // Feature detection fails in mobile emulation mode in Chrome. + // Math.abs(win.innerWidth / visualViewport.scale - visualViewport.width) < + // 0.001 + // Fallback here: "Not Safari" userAgent + if (!/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) { x = visualViewport.offsetLeft; y = visualViewport.offsetTop; } From 90afbbaf91748b6a1a703f7f780f0126d38e70d1 Mon Sep 17 00:00:00 2001 From: atomiks Date: Fri, 1 May 2020 15:40:31 +1000 Subject: [PATCH 2/2] fix: add more document size checks --- src/dom-utils/getDocumentRect.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/dom-utils/getDocumentRect.js b/src/dom-utils/getDocumentRect.js index 8fd10d4bf5..15b1990aea 100644 --- a/src/dom-utils/getDocumentRect.js +++ b/src/dom-utils/getDocumentRect.js @@ -12,8 +12,18 @@ export default function getDocumentRect(element: HTMLElement): Rect { const winScroll = getWindowScroll(element); const body = element.ownerDocument.body; - const width = Math.max(html.scrollWidth, body ? body.scrollWidth : 0); - const height = Math.max(html.scrollHeight, body ? body.scrollHeight : 0); + const width = Math.max( + html.scrollWidth, + html.clientWidth, + body ? body.scrollWidth : 0, + body ? body.clientWidth : 0 + ); + const height = Math.max( + html.scrollHeight, + html.clientHeight, + body ? body.scrollHeight : 0, + body ? body.clientHeight : 0 + ); let x = -winScroll.scrollLeft + getWindowScrollBarX(element); const y = -winScroll.scrollTop;