keyboard-52278bd7.js 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. import { K as Keyboard } from './keyboard-73175e24.js';
  5. import './capacitor-59395cbd.js';
  6. import './index-a5d50daf.js';
  7. const KEYBOARD_DID_OPEN = 'ionKeyboardDidShow';
  8. const KEYBOARD_DID_CLOSE = 'ionKeyboardDidHide';
  9. const KEYBOARD_THRESHOLD = 150;
  10. // TODO(FW-2832): types
  11. let previousVisualViewport = {};
  12. let currentVisualViewport = {};
  13. let keyboardOpen = false;
  14. /**
  15. * This is only used for tests
  16. */
  17. const resetKeyboardAssist = () => {
  18. previousVisualViewport = {};
  19. currentVisualViewport = {};
  20. keyboardOpen = false;
  21. };
  22. const startKeyboardAssist = (win) => {
  23. const nativeEngine = Keyboard.getEngine();
  24. /**
  25. * If the native keyboard plugin is available
  26. * then we are running in a native environment. As a result
  27. * we should only listen on the native events instead of
  28. * using the Visual Viewport as the Ionic webview manipulates
  29. * how it resizes such that the Visual Viewport API is not
  30. * reliable here.
  31. */
  32. if (nativeEngine) {
  33. startNativeListeners(win);
  34. }
  35. else {
  36. if (!win.visualViewport) {
  37. return;
  38. }
  39. currentVisualViewport = copyVisualViewport(win.visualViewport);
  40. win.visualViewport.onresize = () => {
  41. trackViewportChanges(win);
  42. if (keyboardDidOpen() || keyboardDidResize(win)) {
  43. setKeyboardOpen(win);
  44. }
  45. else if (keyboardDidClose(win)) {
  46. setKeyboardClose(win);
  47. }
  48. };
  49. }
  50. };
  51. /**
  52. * Listen for events fired by native keyboard plugin
  53. * in Capacitor/Cordova so devs only need to listen
  54. * in one place.
  55. */
  56. const startNativeListeners = (win) => {
  57. win.addEventListener('keyboardDidShow', (ev) => setKeyboardOpen(win, ev));
  58. win.addEventListener('keyboardDidHide', () => setKeyboardClose(win));
  59. };
  60. const setKeyboardOpen = (win, ev) => {
  61. fireKeyboardOpenEvent(win, ev);
  62. keyboardOpen = true;
  63. };
  64. const setKeyboardClose = (win) => {
  65. fireKeyboardCloseEvent(win);
  66. keyboardOpen = false;
  67. };
  68. /**
  69. * Returns `true` if the `keyboardOpen` flag is not
  70. * set, the previous visual viewport width equal the current
  71. * visual viewport width, and if the scaled difference
  72. * of the previous visual viewport height minus the current
  73. * visual viewport height is greater than KEYBOARD_THRESHOLD
  74. *
  75. * We need to be able to accommodate users who have zooming
  76. * enabled in their browser (or have zoomed in manually) which
  77. * is why we take into account the current visual viewport's
  78. * scale value.
  79. */
  80. const keyboardDidOpen = () => {
  81. const scaledHeightDifference = (previousVisualViewport.height - currentVisualViewport.height) * currentVisualViewport.scale;
  82. return (!keyboardOpen &&
  83. previousVisualViewport.width === currentVisualViewport.width &&
  84. scaledHeightDifference > KEYBOARD_THRESHOLD);
  85. };
  86. /**
  87. * Returns `true` if the keyboard is open,
  88. * but the keyboard did not close
  89. */
  90. const keyboardDidResize = (win) => {
  91. return keyboardOpen && !keyboardDidClose(win);
  92. };
  93. /**
  94. * Determine if the keyboard was closed
  95. * Returns `true` if the `keyboardOpen` flag is set and
  96. * the current visual viewport height equals the
  97. * layout viewport height.
  98. */
  99. const keyboardDidClose = (win) => {
  100. return keyboardOpen && currentVisualViewport.height === win.innerHeight;
  101. };
  102. /**
  103. * Dispatch a keyboard open event
  104. */
  105. const fireKeyboardOpenEvent = (win, nativeEv) => {
  106. const keyboardHeight = nativeEv ? nativeEv.keyboardHeight : win.innerHeight - currentVisualViewport.height;
  107. const ev = new CustomEvent(KEYBOARD_DID_OPEN, {
  108. detail: { keyboardHeight },
  109. });
  110. win.dispatchEvent(ev);
  111. };
  112. /**
  113. * Dispatch a keyboard close event
  114. */
  115. const fireKeyboardCloseEvent = (win) => {
  116. const ev = new CustomEvent(KEYBOARD_DID_CLOSE);
  117. win.dispatchEvent(ev);
  118. };
  119. /**
  120. * Given a window object, create a copy of
  121. * the current visual and layout viewport states
  122. * while also preserving the previous visual and
  123. * layout viewport states
  124. */
  125. const trackViewportChanges = (win) => {
  126. previousVisualViewport = Object.assign({}, currentVisualViewport);
  127. currentVisualViewport = copyVisualViewport(win.visualViewport);
  128. };
  129. /**
  130. * Creates a deep copy of the visual viewport
  131. * at a given state
  132. */
  133. const copyVisualViewport = (visualViewport) => {
  134. return {
  135. width: Math.round(visualViewport.width),
  136. height: Math.round(visualViewport.height),
  137. offsetTop: visualViewport.offsetTop,
  138. offsetLeft: visualViewport.offsetLeft,
  139. pageTop: visualViewport.pageTop,
  140. pageLeft: visualViewport.pageLeft,
  141. scale: visualViewport.scale,
  142. };
  143. };
  144. export { KEYBOARD_DID_CLOSE, KEYBOARD_DID_OPEN, copyVisualViewport, keyboardDidClose, keyboardDidOpen, keyboardDidResize, resetKeyboardAssist, setKeyboardClose, setKeyboardOpen, startKeyboardAssist, trackViewportChanges };