From e0d876e9f04355c5fc223e16df5816cdfe0536ce Mon Sep 17 00:00:00 2001 From: "Manu Mtz.-Almeida" Date: Wed, 7 Dec 2016 16:49:13 +0100 Subject: [PATCH] fix(clickblock): clickblock applies longer references #9531 --- src/components/app/app.ts | 5 ++-- src/components/app/test/app.spec.ts | 25 +++++------------- src/components/menu/menu.ts | 1 + src/themes/ionic.globals.scss | 2 +- src/themes/util.scss | 5 ++++ src/util/click-block.ts | 41 +++++++++++++++++------------ 6 files changed, 41 insertions(+), 38 deletions(-) diff --git a/src/components/app/app.ts b/src/components/app/app.ts index 7b8de851a9..4ce583d191 100644 --- a/src/components/app/app.ts +++ b/src/components/app/app.ts @@ -19,6 +19,7 @@ import { MenuController } from '../menu/menu-controller'; */ @Injectable() export class App { + private _disTime: number = 0; private _scrollTime: number = 0; private _title: string = ''; @@ -122,9 +123,9 @@ export class App { this._disTime = (isEnabled ? 0 : Date.now() + duration); if (this._clickBlock) { - if (isEnabled || duration <= 32) { + if (isEnabled) { // disable the click block if it's enabled, or the duration is tiny - this._clickBlock.activate(false, 0); + this._clickBlock.activate(false, CLICK_BLOCK_BUFFER_IN_MILLIS); } else { // show the click block for duration + some number diff --git a/src/components/app/test/app.spec.ts b/src/components/app/test/app.spec.ts index d20cf803ce..051e76e6b6 100644 --- a/src/components/app/test/app.spec.ts +++ b/src/components/app/test/app.spec.ts @@ -354,7 +354,7 @@ describe('App', () => { }); describe('setEnabled', () => { - it('should disable click block when app is enabled', () => { + it('should disable click block when app is enabled', (done) => { // arrange let mockClickBlock: any = { activate: () => {} @@ -368,25 +368,14 @@ describe('App', () => { app.setEnabled(true); // assert - expect(mockClickBlock.activate).toHaveBeenCalledWith(false, 0); - }); + expect(mockClickBlock.activate).not.toHaveBeenCalled(); - it('should disable click block when app is disabled but duration of less than 32 passed', () => { - // arrange - let mockClickBlock: any = { - activate: () => {} - }; + setTimeout(() => { + expect(mockClickBlock.activate).toHaveBeenCalledWith(false, 0); + done(); + }, 120); + }, 1000); - spyOn(mockClickBlock, 'activate'); - - app._clickBlock = mockClickBlock; - - // act - app.setEnabled(false, 20); - - // assert - expect(mockClickBlock.activate).toHaveBeenCalledWith(false, 0); - }); it('should enable click block when false is passed with duration', () => { // arrange diff --git a/src/components/menu/menu.ts b/src/components/menu/menu.ts index 7e1868778f..c37542c010 100644 --- a/src/components/menu/menu.ts +++ b/src/components/menu/menu.ts @@ -508,6 +508,7 @@ export class Menu { private _after(isOpen: boolean) { assert(this._isAnimating, '_before() should be called while animating'); + this._app.setEnabled(false, 100); // keep opening/closing the menu disabled for a touch more yet // only add listeners/css if it's enabled and isOpen // and only remove listeners/css if it's not open diff --git a/src/themes/ionic.globals.scss b/src/themes/ionic.globals.scss index 500933fde4..564d596b2c 100644 --- a/src/themes/ionic.globals.scss +++ b/src/themes/ionic.globals.scss @@ -34,7 +34,7 @@ $hairlines-width: .55px !default; $z-index-menu-overlay: 80; $z-index-menu-backdrop: 79; $z-index-overlay: 1000; -$z-index-click-block: 9999; +$z-index-click-block: 99999; $z-index-fixed-content: 999; $z-index-scroll-content: 1; diff --git a/src/themes/util.scss b/src/themes/util.scss index 3588e362ce..79ef88ed27 100755 --- a/src/themes/util.scss +++ b/src/themes/util.scss @@ -48,6 +48,10 @@ ion-input :focus { // to avoid full-page reflows and paints which can cause flickers .click-block { + display: none; +} + +.click-block-enabled { position: absolute; top: 0; right: 0; @@ -61,6 +65,7 @@ ion-input :focus { // background: red; // opacity: .3; + contain: strict; } .click-block-active { diff --git a/src/util/click-block.ts b/src/util/click-block.ts index 632db61160..17d9718e0e 100644 --- a/src/util/click-block.ts +++ b/src/util/click-block.ts @@ -4,8 +4,6 @@ import { App } from '../components/app/app'; import { clearNativeTimeout, nativeTimeout } from './dom'; import { Config } from '../config/config'; -const DEFAULT_EXPIRE = 330; - /** * @private @@ -25,22 +23,31 @@ export class ClickBlock { private renderer: Renderer ) { app._clickBlock = this; - this.isEnabled = config.getBoolean('clickBlock', true); - } - - activate(shouldShow: boolean, expire: number) { - if (this.isEnabled) { - clearNativeTimeout(this._tmrId); - - if (shouldShow) { - this._tmrId = nativeTimeout(this.activate.bind(this, false), expire || DEFAULT_EXPIRE); - } - - if (this._showing !== shouldShow) { - this.renderer.setElementClass(this.elementRef.nativeElement, 'click-block-active', shouldShow); - this._showing = shouldShow; - } + let enabled = this.isEnabled = config.getBoolean('clickBlock', true); + if (enabled) { + this.setElementClass('click-block-enabled', true); } } + activate(shouldShow: boolean, expire: number = 100) { + if (this.isEnabled) { + clearNativeTimeout(this._tmrId); + if (shouldShow) { + this._activate(true); + } + this._tmrId = nativeTimeout(this._activate.bind(this, false), expire); + } + } + + _activate(shouldShow: boolean) { + if (this._showing !== shouldShow) { + this.setElementClass('click-block-active', shouldShow); + this._showing = shouldShow; + } + } + + setElementClass(className: string, add: boolean) { + this.renderer.setElementClass(this.elementRef.nativeElement, className, add); + } + }