From 89cf78d529d2a1e46a247b27c9a0a869416f440f Mon Sep 17 00:00:00 2001 From: Nicolas Gallagher Date: Thu, 8 Apr 2021 18:20:19 -0700 Subject: [PATCH] [change] Fix the Dimensions.window value Fixes issues in Safari from using window.innerWidth. Using documentElement.clientWidth doesn't have issues and provides a more practical value for the canvas width that excludes the width of scrollbars. Fix #1369 Fix #1905 --- .../src/exports/Dimensions/index.js | 49 ++++++++++++------- scripts/jest/setupFiles.js | 13 ++++- 2 files changed, 42 insertions(+), 20 deletions(-) diff --git a/packages/react-native-web/src/exports/Dimensions/index.js b/packages/react-native-web/src/exports/Dimensions/index.js index 0c557727..8d48285d 100644 --- a/packages/react-native-web/src/exports/Dimensions/index.js +++ b/packages/react-native-web/src/exports/Dimensions/index.js @@ -27,19 +27,20 @@ type DimensionKey = 'window' | 'screen'; type DimensionEventListenerType = 'change'; -const win = canUseDOM - ? window - : { - devicePixelRatio: undefined, - innerHeight: (undefined: any), - innerWidth: (undefined: any), - screen: { - height: (undefined: any), - width: (undefined: any) - } - }; - -const dimensions = {}; +const dimensions = { + window: { + fontScale: 1, + height: 0, + scale: 1, + width: 0 + }, + screen: { + fontScale: 1, + height: 0, + scale: 1, + width: 0 + } +}; const listeners = {}; export default class Dimensions { @@ -53,18 +54,29 @@ export default class Dimensions { if (canUseDOM) { invariant(false, 'Dimensions cannot be set in the browser'); } else { - dimensions.screen = initialDimensions.screen; - dimensions.window = initialDimensions.window; + if (initialDimensions.screen != null) { + dimensions.screen = initialDimensions.screen; + } + if (initialDimensions.window != null) { + dimensions.window = initialDimensions.window; + } } } } static _update() { + if (!canUseDOM) { + return; + } + + const win = window; + const docEl = win.document.documentElement; + dimensions.window = { fontScale: 1, - height: win.innerHeight, + height: docEl.clientHeight, scale: win.devicePixelRatio || 1, - width: win.innerWidth + width: docEl.clientWidth }; dimensions.screen = { @@ -97,8 +109,7 @@ export default class Dimensions { } } -Dimensions._update(); - if (canUseDOM) { + Dimensions._update(); window.addEventListener('resize', Dimensions._update, false); } diff --git a/scripts/jest/setupFiles.js b/scripts/jest/setupFiles.js index 804c1def..61bf83bd 100644 --- a/scripts/jest/setupFiles.js +++ b/scripts/jest/setupFiles.js @@ -6,5 +6,16 @@ class ResizeObserver { observe() {} unobserve() {} } - window.ResizeObserver = ResizeObserver; + +// JSDOM doesn't provide values for 'clientWidth' etc +Object.defineProperty(window.document.documentElement, 'clientHeight', { + get: function () { + return this._jsdomClientWidth || window.innerHeight; + } +}); +Object.defineProperty(window.document.documentElement, 'clientWidth', { + get: function () { + return this._jsdomClientWidth || window.innerWidth; + } +});