@jsenv/dom 0.17.31 → 0.17.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/jsenv_dom.js +58 -6
  2. package/package.json +1 -1
package/dist/jsenv_dom.js CHANGED
@@ -15008,17 +15008,69 @@ window.addEventListener("resize", (event) => {
15008
15008
  const getVisibleViewportRect = () => {
15009
15009
  const visualViewport = window.visualViewport;
15010
15010
  const documentElement = document.documentElement;
15011
- const height = visualViewport
15012
- ? visualViewport.height
15013
- : documentElement.clientHeight;
15011
+ if (!visualViewport) {
15012
+ return {
15013
+ left: 0,
15014
+ top: 0,
15015
+ width: documentElement.clientWidth,
15016
+ height: Math.max(
15017
+ 0,
15018
+ documentElement.clientHeight - getVirtualKeyboardOverlayHeight(),
15019
+ ),
15020
+ };
15021
+ }
15022
+ let { offsetLeft, offsetTop, width, height } = visualViewport;
15023
+ // The visual viewport only drifts from the layout viewport while the page is
15024
+ // pinch-zoomed or an on-screen keyboard is up (Safari/Firefox shrink and
15025
+ // pan it to keep the field in view). Neither can be the case at scale 1
15026
+ // with nothing editable focused — an on-screen keyboard is dismissed by
15027
+ // blurring the field — so an offset reported then is a stale one. iOS 26.0
15028
+ // keeps the last keyboard offset and height after the keyboard went away
15029
+ // (https://developer.apple.com/forums/thread/800125): trusted as-is, that
15030
+ // offset sends a bottom-docked sheet past the bottom edge, out of sight.
15031
+ if (
15032
+ visualViewport.scale === 1 &&
15033
+ !isEditableElement(document.activeElement)
15034
+ ) {
15035
+ offsetLeft = 0;
15036
+ offsetTop = 0;
15037
+ if (window.innerHeight > height) {
15038
+ height = window.innerHeight;
15039
+ }
15040
+ }
15014
15041
  return {
15015
- left: visualViewport ? visualViewport.offsetLeft : 0,
15016
- top: visualViewport ? visualViewport.offsetTop : 0,
15017
- width: visualViewport ? visualViewport.width : documentElement.clientWidth,
15042
+ left: offsetLeft,
15043
+ top: offsetTop,
15044
+ width,
15018
15045
  height: Math.max(0, height - getVirtualKeyboardOverlayHeight()),
15019
15046
  };
15020
15047
  };
15021
15048
 
15049
+ const isEditableElement = (element) => {
15050
+ if (!element) {
15051
+ return false;
15052
+ }
15053
+ if (element.tagName === "TEXTAREA" || element.isContentEditable) {
15054
+ return true;
15055
+ }
15056
+ if (element.tagName === "INPUT") {
15057
+ return !NON_TYPING_INPUT_TYPES.has(element.type);
15058
+ }
15059
+ return false;
15060
+ };
15061
+ const NON_TYPING_INPUT_TYPES = new Set([
15062
+ "button",
15063
+ "checkbox",
15064
+ "color",
15065
+ "file",
15066
+ "hidden",
15067
+ "image",
15068
+ "radio",
15069
+ "range",
15070
+ "reset",
15071
+ "submit",
15072
+ ]);
15073
+
15022
15074
  // Minimum fraction of element width/height that must be visible on the preferred side
15023
15075
  // before flipping to the opposite side. Prevents flickering near the flip threshold.
15024
15076
  const MIN_CONTENT_VISIBILITY_RATIO = 0.6;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsenv/dom",
3
- "version": "0.17.31",
3
+ "version": "0.17.32",
4
4
  "type": "module",
5
5
  "description": "DOM utilities for writing frontend code",
6
6
  "repository": {