keyboard.js 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. (function (factory) {
  2. if (typeof module === "object" && typeof module.exports === "object") {
  3. var v = factory(require, exports);
  4. if (v !== undefined) module.exports = v;
  5. }
  6. else if (typeof define === "function" && define.amd) {
  7. define(["require", "exports", "@angular/core", "../config/config", "./dom-controller", "../util/dom", "./key", "./platform"], factory);
  8. }
  9. })(function (require, exports) {
  10. "use strict";
  11. Object.defineProperty(exports, "__esModule", { value: true });
  12. var core_1 = require("@angular/core");
  13. var config_1 = require("../config/config");
  14. var dom_controller_1 = require("./dom-controller");
  15. var dom_1 = require("../util/dom");
  16. var key_1 = require("./key");
  17. var platform_1 = require("./platform");
  18. /**
  19. * @name Keyboard
  20. * @description
  21. * The `Keyboard` class allows you to work with the keyboard events provided
  22. * by the Ionic keyboard plugin.
  23. *
  24. * @usage
  25. * ```ts
  26. * export class MyClass {
  27. *
  28. * constructor(public keyboard: Keyboard) { }
  29. *
  30. * }
  31. * ```
  32. */
  33. var Keyboard = (function () {
  34. function Keyboard(config, _plt, _zone, _dom) {
  35. this._plt = _plt;
  36. this._zone = _zone;
  37. this._dom = _dom;
  38. this.willShow = new core_1.EventEmitter();
  39. this.willHide = new core_1.EventEmitter();
  40. this.didShow = new core_1.EventEmitter();
  41. this.didHide = new core_1.EventEmitter();
  42. this.eventsAvailable = false;
  43. this.focusOutline(config.get('focusOutline'));
  44. var win = _plt.win();
  45. if (win.Ionic && win.Ionic.keyboardPlugin) {
  46. this.listenV2(win);
  47. }
  48. else {
  49. this.listenV1(win);
  50. }
  51. }
  52. Keyboard.prototype.listenV2 = function (win) {
  53. var _this = this;
  54. var platform = this._plt;
  55. platform.registerListener(win, 'keyboardWillShow', function (ev) {
  56. _this._zone.run(function () {
  57. _this.willShow.emit(ev.keyboardHeight);
  58. });
  59. }, { zone: false, passive: true });
  60. platform.registerListener(win, 'keyboardWillHide', function () {
  61. _this._zone.run(function () {
  62. _this.willHide.emit();
  63. });
  64. }, { zone: false, passive: true });
  65. platform.registerListener(win, 'keyboardDidShow', function (ev) {
  66. _this._zone.run(function () {
  67. _this.didShow.emit(ev.keyboardHeight);
  68. });
  69. }, { zone: false, passive: true });
  70. platform.registerListener(win, 'keyboardDidHide', function () {
  71. _this._zone.run(function () {
  72. _this.didHide.emit();
  73. });
  74. }, { zone: false, passive: true });
  75. this.eventsAvailable = true;
  76. };
  77. Keyboard.prototype.listenV1 = function (win) {
  78. var _this = this;
  79. var platform = this._plt;
  80. platform.registerListener(win, 'native.keyboardhide', function () {
  81. _this.blurActiveInput(true);
  82. }, { zone: false, passive: true });
  83. platform.registerListener(win, 'native.keyboardshow', function () {
  84. _this.blurActiveInput(false);
  85. }, { zone: false, passive: true });
  86. };
  87. Keyboard.prototype.blurActiveInput = function (shouldBlur) {
  88. var _this = this;
  89. var platform = this._plt;
  90. platform.cancelTimeout(this._tmr);
  91. if (shouldBlur) {
  92. this._tmr = platform.timeout(function () {
  93. // this custom cordova plugin event fires when the keyboard will hide
  94. // useful when the virtual keyboard is closed natively
  95. // https://github.com/ionic-team/ionic-plugin-keyboard
  96. if (_this.isOpen()) {
  97. platform.focusOutActiveElement();
  98. }
  99. }, 80);
  100. }
  101. };
  102. /**
  103. * Check to see if the keyboard is open or not.
  104. *
  105. * ```ts
  106. * export class MyClass {
  107. * constructor(public keyboard: Keyboard) {
  108. *
  109. * }
  110. *
  111. * keyboardCheck() {
  112. * console.log('The keyboard is open:', this.keyboard.isOpen());
  113. * }
  114. * }
  115. * ```
  116. *
  117. * @return {boolean} returns a true or false value if the keyboard is open or not.
  118. */
  119. Keyboard.prototype.isOpen = function () {
  120. return this.hasFocusedTextInput();
  121. };
  122. /**
  123. * When the keyboard is closed, call any methods you want.
  124. *
  125. * ```ts
  126. * export class MyClass {
  127. * constructor(public keyboard: Keyboard) {
  128. * this.keyboard.onClose(this.closeCallback);
  129. * }
  130. * closeCallback() {
  131. * // call what ever functionality you want on keyboard close
  132. * console.log('Closing time');
  133. * }
  134. * }
  135. * ```
  136. *
  137. * @param {function} callback method you want to call when the keyboard has been closed.
  138. * @return {function} returns a callback that gets fired when the keyboard is closed.
  139. */
  140. Keyboard.prototype.onClose = function (callback, pollingInternval, pollingChecksMax) {
  141. if (pollingInternval === void 0) { pollingInternval = KEYBOARD_CLOSE_POLLING; }
  142. if (pollingChecksMax === void 0) { pollingChecksMax = KEYBOARD_POLLING_CHECKS_MAX; }
  143. (void 0) /* console.debug */;
  144. var self = this;
  145. var checks = 0;
  146. var promise = null;
  147. if (!callback) {
  148. // a callback wasn't provided, so let's return a promise instead
  149. promise = new Promise(function (resolve) { callback = resolve; });
  150. }
  151. function checkKeyboard() {
  152. (void 0) /* console.debug */;
  153. if (!self.isOpen() || checks > pollingChecksMax) {
  154. self._plt.timeout(function () {
  155. self._zone.run(function () {
  156. (void 0) /* console.debug */;
  157. callback();
  158. });
  159. }, 400);
  160. }
  161. else {
  162. self._plt.timeout(checkKeyboard, pollingInternval);
  163. }
  164. checks++;
  165. }
  166. self._plt.timeout(checkKeyboard, pollingInternval);
  167. return promise;
  168. };
  169. /**
  170. * Programmatically close the keyboard.
  171. */
  172. Keyboard.prototype.close = function () {
  173. var _this = this;
  174. this._dom.read(function () {
  175. if (_this.isOpen()) {
  176. // only focus out when a text input has focus
  177. (void 0) /* console.debug */;
  178. _this._dom.write(function () {
  179. _this._plt.focusOutActiveElement();
  180. });
  181. }
  182. });
  183. };
  184. /**
  185. * @hidden
  186. */
  187. Keyboard.prototype.focusOutline = function (setting) {
  188. /* Focus Outline
  189. * --------------------------------------------------
  190. * By default, when a keydown event happens from a tab key, then
  191. * the 'focus-outline' css class is added to the body element
  192. * so focusable elements have an outline. On a mousedown or
  193. * touchstart event, then the 'focus-outline' css class is removed.
  194. *
  195. * Config default overrides:
  196. * focusOutline: true - Always add the focus-outline
  197. * focusOutline: false - Do not add the focus-outline
  198. */
  199. var self = this;
  200. var platform = self._plt;
  201. var doc = platform.doc();
  202. var isKeyInputEnabled = false;
  203. var unRegMouse;
  204. var unRegTouch;
  205. var evOpts = { passive: true, zone: false };
  206. function cssClass() {
  207. self._dom.write(function () {
  208. platform.doc().body.classList[isKeyInputEnabled ? 'add' : 'remove']('focus-outline');
  209. });
  210. }
  211. if (setting === true) {
  212. isKeyInputEnabled = true;
  213. return cssClass();
  214. }
  215. else if (setting === false) {
  216. return;
  217. }
  218. // default is to add the focus-outline when the tab key is used
  219. function keyDown(ev) {
  220. if (!isKeyInputEnabled && ev.keyCode === key_1.KEY_TAB) {
  221. isKeyInputEnabled = true;
  222. enableKeyInput();
  223. }
  224. }
  225. function pointerDown() {
  226. isKeyInputEnabled = false;
  227. enableKeyInput();
  228. }
  229. function enableKeyInput() {
  230. cssClass();
  231. unRegMouse && unRegMouse();
  232. unRegTouch && unRegTouch();
  233. if (isKeyInputEnabled) {
  234. // listen for when a mousedown or touchstart event happens
  235. unRegMouse = platform.registerListener(doc, 'mousedown', pointerDown, evOpts);
  236. unRegTouch = platform.registerListener(doc, 'touchstart', pointerDown, evOpts);
  237. }
  238. }
  239. // always listen for tab keydown events
  240. platform.registerListener(platform.doc(), 'keydown', keyDown, evOpts);
  241. };
  242. Keyboard.prototype.hasFocusedTextInput = function () {
  243. var activeEle = this._plt.getActiveElement();
  244. if (dom_1.isTextInput(activeEle)) {
  245. return (activeEle.parentElement.querySelector(':focus') === activeEle);
  246. }
  247. return false;
  248. };
  249. /**
  250. * Set to true to hide the additional toolbar that is on top of the keyboard.
  251. * This toolbar features the Prev, Next, and Done buttons.
  252. * @param hidden
  253. */
  254. Keyboard.prototype.hideFormAccessoryBar = function (hidden) {
  255. var win = this._plt.win();
  256. if (win && win.Keyboard && win.Keyboard.hideFormAccessoryBar) {
  257. win.Keyboard.hideFormAccessoryBar(hidden);
  258. }
  259. };
  260. Keyboard.decorators = [
  261. { type: core_1.Injectable },
  262. ];
  263. /** @nocollapse */
  264. Keyboard.ctorParameters = function () { return [
  265. { type: config_1.Config, },
  266. { type: platform_1.Platform, },
  267. { type: core_1.NgZone, },
  268. { type: dom_controller_1.DomController, },
  269. ]; };
  270. return Keyboard;
  271. }());
  272. exports.Keyboard = Keyboard;
  273. var KEYBOARD_CLOSE_POLLING = 150;
  274. var KEYBOARD_POLLING_CHECKS_MAX = 100;
  275. });
  276. //# sourceMappingURL=keyboard.js.map