UNPKG

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