native-fn 1.3.1 → 1.3.3

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.
@@ -607,8 +607,8 @@ function createViewportSegmentObserver() {
607
607
  segments = viewport.segments;
608
608
  else
609
609
  segments = visualViewport.segments;
610
- if (segments === null || typeof segments === 'undefined')
611
- return [];
610
+ if (segments === null || typeof segments === 'undefined' || segments.length === 0)
611
+ return [buildFullViewportSegment()];
612
612
  var results = [];
613
613
  for (var i = 0; i < segments.length; i++) {
614
614
  var segment = segments[i];
@@ -725,31 +725,101 @@ function createViewportSegmentObserver() {
725
725
  }
726
726
  function createVirtualKeyboardObserver() {
727
727
  var onChangeSubscriptionManager = createSubscriptionManager(attachOnChange, detachOnChange);
728
+ var virtualKeyboard = globalThis.navigator.virtualKeyboard;
729
+ var pendingRaf = null;
730
+ var pendingStabilize = null;
731
+ var stableInnerHeight = globalThis.innerHeight;
732
+ var stableInnerWidth = globalThis.innerWidth;
728
733
  function attachOnChange() {
729
- EventListener.add(globalThis.navigator.virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
734
+ EventListener.add(virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
735
+ EventListener.add(globalThis, { type: 'resize', callback: onResize, options: { passive: true } });
730
736
  }
731
737
  function detachOnChange() {
732
- EventListener.remove(globalThis.navigator.virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
738
+ EventListener.remove(virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
739
+ EventListener.remove(globalThis, { type: 'resize', callback: onResize, options: { passive: true } });
740
+ if (pendingRaf !== null) {
741
+ globalThis.cancelAnimationFrame(pendingRaf);
742
+ pendingRaf = null;
743
+ }
744
+ if (pendingStabilize !== null) {
745
+ globalThis.clearTimeout(pendingStabilize);
746
+ pendingStabilize = null;
747
+ }
748
+ }
749
+ function emitAfterFrame() {
750
+ if (pendingRaf !== null)
751
+ globalThis.cancelAnimationFrame(pendingRaf);
752
+ if (typeof globalThis.requestAnimationFrame === 'function') {
753
+ pendingRaf = globalThis.requestAnimationFrame(function () {
754
+ pendingRaf = null;
755
+ onChangeSubscriptionManager.emit(getValue());
756
+ });
757
+ }
758
+ else {
759
+ defer(function () {
760
+ onChangeSubscriptionManager.emit(getValue());
761
+ });
762
+ }
733
763
  }
734
764
  function onGeometryChange() {
735
- onChangeSubscriptionManager.emit(getValue());
765
+ var rect = virtualKeyboard.boundingRect;
766
+ if (rect.height === 0) {
767
+ if (pendingStabilize !== null) {
768
+ globalThis.clearTimeout(pendingStabilize);
769
+ pendingStabilize = null;
770
+ }
771
+ emitAfterFrame();
772
+ return;
773
+ }
774
+ if (pendingStabilize !== null)
775
+ globalThis.clearTimeout(pendingStabilize);
776
+ pendingStabilize = globalThis.setTimeout(function () {
777
+ pendingStabilize = null;
778
+ emitAfterFrame();
779
+ }, 100);
780
+ }
781
+ function onResize() {
782
+ var rect = virtualKeyboard.boundingRect;
783
+ if (rect.height === 0) {
784
+ stableInnerHeight = globalThis.innerHeight;
785
+ stableInnerWidth = globalThis.innerWidth;
786
+ }
787
+ else {
788
+ var currentInnerHeight = globalThis.innerHeight;
789
+ if (rect.y + rect.height > currentInnerHeight)
790
+ stableInnerHeight = currentInnerHeight - rect.height;
791
+ else
792
+ stableInnerHeight = currentInnerHeight;
793
+ stableInnerWidth = globalThis.innerWidth;
794
+ }
736
795
  }
737
796
  function getValue() {
738
- var rect = globalThis.navigator.virtualKeyboard.boundingRect;
739
- var left = rect.x;
740
- var top = rect.y;
797
+ var rect = virtualKeyboard.boundingRect;
741
798
  var width = rect.width;
742
799
  var height = rect.height;
743
- var right;
744
- if (width === 0)
745
- right = 0;
746
- else
747
- right = Math.max(0, globalThis.innerWidth - (left + width));
748
- var bottom;
749
- if (height === 0)
750
- bottom = 0;
751
- else
752
- bottom = Math.max(0, globalThis.innerHeight - (top + height));
800
+ var top = 0;
801
+ var bottom = 0;
802
+ var left = 0;
803
+ var right = 0;
804
+ if (height === 0) {
805
+ stableInnerHeight = globalThis.innerHeight;
806
+ stableInnerWidth = globalThis.innerWidth;
807
+ }
808
+ else {
809
+ var keyboardMidY = rect.y + height / 2;
810
+ if (keyboardMidY < stableInnerHeight / 2 || rect.y + height > stableInnerHeight) {
811
+ top = stableInnerHeight - height;
812
+ bottom = 0;
813
+ }
814
+ else {
815
+ top = rect.y;
816
+ bottom = Math.max(0, stableInnerHeight - (rect.y + height));
817
+ }
818
+ }
819
+ if (width > 0) {
820
+ left = Math.max(0, rect.x);
821
+ right = Math.max(0, stableInnerWidth - (rect.x + width));
822
+ }
753
823
  return {
754
824
  top: top,
755
825
  right: right,
@@ -1222,26 +1292,26 @@ function screenOrientationSupported() {
1222
1292
  }
1223
1293
  function attachOnScreenOrientationChange() {
1224
1294
  if (typeof globalThis.screen !== 'undefined' && typeof globalThis.screen.orientation !== 'undefined' && typeof globalThis.screen.orientation.addEventListener === 'function')
1225
- EventListener.add(globalThis.screen.orientation, {
1295
+ return EventListener.add(globalThis.screen.orientation, {
1226
1296
  type: 'change',
1227
1297
  callback: onScreenOrientationChange
1228
1298
  });
1229
1299
  else if (typeof globalThis.orientation !== 'undefined')
1230
- EventListener.add(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1300
+ return EventListener.add(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1231
1301
  else if (exports.ORIENTATION_MEDIA_QUERY_LIST.media !== 'not all')
1232
- EventListener.add(exports.ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1302
+ return EventListener.add(exports.ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1233
1303
  throw new NotSupportedError('\'screen.orientation\', \'window.orientation\', and the orientation media query are all unsupported');
1234
1304
  }
1235
1305
  function detachOnScreenOrientationChange() {
1236
1306
  if (typeof globalThis.screen !== 'undefined' && typeof globalThis.screen.orientation !== 'undefined' && typeof globalThis.screen.orientation.removeEventListener === 'function')
1237
- EventListener.remove(globalThis.screen.orientation, {
1307
+ return EventListener.remove(globalThis.screen.orientation, {
1238
1308
  type: 'change',
1239
1309
  callback: onScreenOrientationChange
1240
1310
  });
1241
1311
  else if (typeof globalThis.orientation !== 'undefined')
1242
- EventListener.remove(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1312
+ return EventListener.remove(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1243
1313
  else if (exports.ORIENTATION_MEDIA_QUERY_LIST.media !== 'not all')
1244
- EventListener.remove(exports.ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1314
+ return EventListener.remove(exports.ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1245
1315
  throw new NotSupportedError('\'screen.orientation\', \'window.orientation\', and the orientation media query are all unsupported');
1246
1316
  }
1247
1317
  function onScreenOrientationChange() {
@@ -603,8 +603,8 @@ function createViewportSegmentObserver() {
603
603
  segments = viewport.segments;
604
604
  else
605
605
  segments = visualViewport.segments;
606
- if (segments === null || typeof segments === 'undefined')
607
- return [];
606
+ if (segments === null || typeof segments === 'undefined' || segments.length === 0)
607
+ return [buildFullViewportSegment()];
608
608
  var results = [];
609
609
  for (var i = 0; i < segments.length; i++) {
610
610
  var segment = segments[i];
@@ -721,31 +721,101 @@ function createViewportSegmentObserver() {
721
721
  }
722
722
  function createVirtualKeyboardObserver() {
723
723
  var onChangeSubscriptionManager = createSubscriptionManager(attachOnChange, detachOnChange);
724
+ var virtualKeyboard = globalThis.navigator.virtualKeyboard;
725
+ var pendingRaf = null;
726
+ var pendingStabilize = null;
727
+ var stableInnerHeight = globalThis.innerHeight;
728
+ var stableInnerWidth = globalThis.innerWidth;
724
729
  function attachOnChange() {
725
- EventListener.add(globalThis.navigator.virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
730
+ EventListener.add(virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
731
+ EventListener.add(globalThis, { type: 'resize', callback: onResize, options: { passive: true } });
726
732
  }
727
733
  function detachOnChange() {
728
- EventListener.remove(globalThis.navigator.virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
734
+ EventListener.remove(virtualKeyboard, { type: 'geometrychange', callback: onGeometryChange, options: { passive: true } });
735
+ EventListener.remove(globalThis, { type: 'resize', callback: onResize, options: { passive: true } });
736
+ if (pendingRaf !== null) {
737
+ globalThis.cancelAnimationFrame(pendingRaf);
738
+ pendingRaf = null;
739
+ }
740
+ if (pendingStabilize !== null) {
741
+ globalThis.clearTimeout(pendingStabilize);
742
+ pendingStabilize = null;
743
+ }
744
+ }
745
+ function emitAfterFrame() {
746
+ if (pendingRaf !== null)
747
+ globalThis.cancelAnimationFrame(pendingRaf);
748
+ if (typeof globalThis.requestAnimationFrame === 'function') {
749
+ pendingRaf = globalThis.requestAnimationFrame(function () {
750
+ pendingRaf = null;
751
+ onChangeSubscriptionManager.emit(getValue());
752
+ });
753
+ }
754
+ else {
755
+ defer(function () {
756
+ onChangeSubscriptionManager.emit(getValue());
757
+ });
758
+ }
729
759
  }
730
760
  function onGeometryChange() {
731
- onChangeSubscriptionManager.emit(getValue());
761
+ var rect = virtualKeyboard.boundingRect;
762
+ if (rect.height === 0) {
763
+ if (pendingStabilize !== null) {
764
+ globalThis.clearTimeout(pendingStabilize);
765
+ pendingStabilize = null;
766
+ }
767
+ emitAfterFrame();
768
+ return;
769
+ }
770
+ if (pendingStabilize !== null)
771
+ globalThis.clearTimeout(pendingStabilize);
772
+ pendingStabilize = globalThis.setTimeout(function () {
773
+ pendingStabilize = null;
774
+ emitAfterFrame();
775
+ }, 100);
776
+ }
777
+ function onResize() {
778
+ var rect = virtualKeyboard.boundingRect;
779
+ if (rect.height === 0) {
780
+ stableInnerHeight = globalThis.innerHeight;
781
+ stableInnerWidth = globalThis.innerWidth;
782
+ }
783
+ else {
784
+ var currentInnerHeight = globalThis.innerHeight;
785
+ if (rect.y + rect.height > currentInnerHeight)
786
+ stableInnerHeight = currentInnerHeight - rect.height;
787
+ else
788
+ stableInnerHeight = currentInnerHeight;
789
+ stableInnerWidth = globalThis.innerWidth;
790
+ }
732
791
  }
733
792
  function getValue() {
734
- var rect = globalThis.navigator.virtualKeyboard.boundingRect;
735
- var left = rect.x;
736
- var top = rect.y;
793
+ var rect = virtualKeyboard.boundingRect;
737
794
  var width = rect.width;
738
795
  var height = rect.height;
739
- var right;
740
- if (width === 0)
741
- right = 0;
742
- else
743
- right = Math.max(0, globalThis.innerWidth - (left + width));
744
- var bottom;
745
- if (height === 0)
746
- bottom = 0;
747
- else
748
- bottom = Math.max(0, globalThis.innerHeight - (top + height));
796
+ var top = 0;
797
+ var bottom = 0;
798
+ var left = 0;
799
+ var right = 0;
800
+ if (height === 0) {
801
+ stableInnerHeight = globalThis.innerHeight;
802
+ stableInnerWidth = globalThis.innerWidth;
803
+ }
804
+ else {
805
+ var keyboardMidY = rect.y + height / 2;
806
+ if (keyboardMidY < stableInnerHeight / 2 || rect.y + height > stableInnerHeight) {
807
+ top = stableInnerHeight - height;
808
+ bottom = 0;
809
+ }
810
+ else {
811
+ top = rect.y;
812
+ bottom = Math.max(0, stableInnerHeight - (rect.y + height));
813
+ }
814
+ }
815
+ if (width > 0) {
816
+ left = Math.max(0, rect.x);
817
+ right = Math.max(0, stableInnerWidth - (rect.x + width));
818
+ }
749
819
  return {
750
820
  top: top,
751
821
  right: right,
@@ -1218,26 +1288,26 @@ function screenOrientationSupported() {
1218
1288
  }
1219
1289
  function attachOnScreenOrientationChange() {
1220
1290
  if (typeof globalThis.screen !== 'undefined' && typeof globalThis.screen.orientation !== 'undefined' && typeof globalThis.screen.orientation.addEventListener === 'function')
1221
- EventListener.add(globalThis.screen.orientation, {
1291
+ return EventListener.add(globalThis.screen.orientation, {
1222
1292
  type: 'change',
1223
1293
  callback: onScreenOrientationChange
1224
1294
  });
1225
1295
  else if (typeof globalThis.orientation !== 'undefined')
1226
- EventListener.add(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1296
+ return EventListener.add(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1227
1297
  else if (ORIENTATION_MEDIA_QUERY_LIST.media !== 'not all')
1228
- EventListener.add(ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1298
+ return EventListener.add(ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1229
1299
  throw new NotSupportedError('\'screen.orientation\', \'window.orientation\', and the orientation media query are all unsupported');
1230
1300
  }
1231
1301
  function detachOnScreenOrientationChange() {
1232
1302
  if (typeof globalThis.screen !== 'undefined' && typeof globalThis.screen.orientation !== 'undefined' && typeof globalThis.screen.orientation.removeEventListener === 'function')
1233
- EventListener.remove(globalThis.screen.orientation, {
1303
+ return EventListener.remove(globalThis.screen.orientation, {
1234
1304
  type: 'change',
1235
1305
  callback: onScreenOrientationChange
1236
1306
  });
1237
1307
  else if (typeof globalThis.orientation !== 'undefined')
1238
- EventListener.remove(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1308
+ return EventListener.remove(globalThis, { type: 'orientationchange', callback: onScreenOrientationChange });
1239
1309
  else if (ORIENTATION_MEDIA_QUERY_LIST.media !== 'not all')
1240
- EventListener.remove(ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1310
+ return EventListener.remove(ORIENTATION_MEDIA_QUERY_LIST, { type: 'change', callback: onScreenOrientationChange });
1241
1311
  throw new NotSupportedError('\'screen.orientation\', \'window.orientation\', and the orientation media query are all unsupported');
1242
1312
  }
1243
1313
  function onScreenOrientationChange() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-fn",
3
- "version": "1.3.1",
3
+ "version": "1.3.3",
4
4
  "description": "TypeScript library bridging Web APIs to native device capabilities — Picture-in-Picture, Fullscreen, Clipboard, Geolocation, Battery, Notifications, Vibration, Platform detection, and more.",
5
5
  "author": "Park Jungyoung <qkrwnss0509@gmail.com> (https://github.com/pjy0509)",
6
6
  "type": "module",