@@ -30,6 +30,7 @@ export class App {
3030 private _titleSrv : Title = new Title ( DOCUMENT ) ;
3131 private _rootNav : NavController = null ;
3232 private _disableScrollAssist : boolean ;
33+ private _didScroll = false ;
3334
3435 /**
3536 * @hidden
@@ -87,6 +88,11 @@ export class App {
8788 _plt . registerBackButtonAction ( this . goBack . bind ( this ) ) ;
8889 this . _disableScrollAssist = _config . getBoolean ( 'disableScrollAssist' , false ) ;
8990
91+ const blurring = _config . getBoolean ( 'inputBlurring' , false ) ;
92+ if ( blurring ) {
93+ this . _enableInputBlurring ( ) ;
94+ }
95+
9096 runInDev ( ( ) => {
9197 // During developement, navPop can be triggered by calling
9298 const win = < any > _plt . win ( ) ;
@@ -179,6 +185,7 @@ export class App {
179185 */
180186 setScrolling ( ) {
181187 this . _scrollTime = Date . now ( ) + ACTIVE_SCROLLING_TIME ;
188+ this . _didScroll = true ;
182189 }
183190
184191 /**
@@ -289,6 +296,60 @@ export class App {
289296 return recursivePop ( this . getActiveNav ( ) ) ;
290297 }
291298
299+ /**
300+ * @hidden
301+ */
302+ _enableInputBlurring ( ) {
303+ console . debug ( 'App: _enableInputBlurring' ) ;
304+ let focused = true ;
305+ const self = this ;
306+ const platform = this . _plt ;
307+
308+ platform . registerListener ( platform . doc ( ) , 'focusin' , onFocusin , { capture : true , zone : false , passive : true } ) ;
309+ platform . registerListener ( platform . doc ( ) , 'touchend' , onTouchend , { capture : false , zone : false , passive : true } ) ;
310+
311+ function onFocusin ( ev : any ) {
312+ focused = true ;
313+ }
314+ function onTouchend ( ev : any ) {
315+ // if app did scroll return early
316+ if ( self . _didScroll ) {
317+ self . _didScroll = false ;
318+ return ;
319+ }
320+ const active = < HTMLElement > self . _plt . getActiveElement ( ) ;
321+ if ( ! active ) {
322+ return ;
323+ }
324+ // only blur if the active element is a text-input or a textarea
325+ if ( SKIP_BLURRING . indexOf ( active . tagName ) === - 1 ) {
326+ return ;
327+ }
328+
329+ // if the selected target is the active element, do not blur
330+ const tapped = ev . target ;
331+ if ( tapped === active ) {
332+ return ;
333+ }
334+ if ( SKIP_BLURRING . indexOf ( tapped . tagName ) >= 0 ) {
335+ return ;
336+ }
337+
338+ // skip if div is a cover
339+ if ( tapped . classList . contains ( 'input-cover' ) ) {
340+ return ;
341+ }
342+
343+ focused = false ;
344+ // TODO: find a better way, why 50ms?
345+ platform . timeout ( ( ) => {
346+ if ( ! focused ) {
347+ active . blur ( ) ;
348+ }
349+ } , 50 ) ;
350+ }
351+ }
352+
292353}
293354
294355function recursivePop ( nav : any ) : Promise < any > {
@@ -322,5 +383,6 @@ function findTopNav(nav: NavController) {
322383 return nav ;
323384}
324385
386+ const SKIP_BLURRING = [ 'INPUT' , 'TEXTAREA' , 'ION-INPUT' , 'ION-TEXTAREA' ] ;
325387const ACTIVE_SCROLLING_TIME = 100 ;
326388const CLICK_BLOCK_BUFFER_IN_MILLIS = 64 ;
0 commit comments