keyboard-af1bb365.js 5.1 KB

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