40 lines
1.6 KiB
JavaScript
40 lines
1.6 KiB
JavaScript
|
import getWindow from "./getWindow.js";
|
||
|
import getDocumentElement from "./getDocumentElement.js";
|
||
|
import getWindowScrollBarX from "./getWindowScrollBarX.js";
|
||
|
export default function getViewportRect(element) {
|
||
|
var win = getWindow(element);
|
||
|
var html = getDocumentElement(element);
|
||
|
var visualViewport = win.visualViewport;
|
||
|
var width = html.clientWidth;
|
||
|
var height = html.clientHeight;
|
||
|
var x = 0;
|
||
|
var y = 0; // NB: This isn't supported on iOS <= 12. If the keyboard is open, the popper
|
||
|
// can be obscured underneath it.
|
||
|
// Also, `html.clientHeight` adds the bottom bar height in Safari iOS, even
|
||
|
// if it isn't open, so if this isn't available, the popper will be detected
|
||
|
// to overflow the bottom of the screen too early.
|
||
|
|
||
|
if (visualViewport) {
|
||
|
width = visualViewport.width;
|
||
|
height = visualViewport.height; // 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
|
||
|
// 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;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
width: width,
|
||
|
height: height,
|
||
|
x: x + getWindowScrollBarX(element),
|
||
|
y: y
|
||
|
};
|
||
|
}
|