native-fn 1.3.2 → 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,
@@ -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,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "native-fn",
3
- "version": "1.3.2",
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",