mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-19 03:32:21 +08:00
@ -39,6 +39,7 @@ export class IonicApp {
|
|||||||
*/
|
*/
|
||||||
constructor() {
|
constructor() {
|
||||||
this.overlays = [];
|
this.overlays = [];
|
||||||
|
this._isTransitioning = false;
|
||||||
|
|
||||||
// Our component registry map
|
// Our component registry map
|
||||||
this.components = {};
|
this.components = {};
|
||||||
@ -74,6 +75,24 @@ export class IonicApp {
|
|||||||
document.title = val;
|
document.title = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets if the app is currently transitioning or not. For example
|
||||||
|
* this is set to `true` while views transition, a modal slides up, an action-menu
|
||||||
|
* slides up, etc. After the transition completes it is set back to `false`.
|
||||||
|
* @param {bool} isTransitioning
|
||||||
|
*/
|
||||||
|
setTransitioning(isTransitioning) {
|
||||||
|
this._isTransitioning = !!isTransitioning;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Boolean if the app is actively transitioning or not.
|
||||||
|
* @return {bool}
|
||||||
|
*/
|
||||||
|
isTransitioning() {
|
||||||
|
return this._isTransitioning;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO
|
* TODO
|
||||||
* @param {TODO=} val TODO
|
* @param {TODO=} val TODO
|
||||||
|
@ -128,6 +128,7 @@ export class OverlayRef {
|
|||||||
animation.before.addClass('show-overlay');
|
animation.before.addClass('show-overlay');
|
||||||
|
|
||||||
ClickBlock(true, animation.duration() + 200);
|
ClickBlock(true, animation.duration() + 200);
|
||||||
|
this.app.setTransitioning(true);
|
||||||
|
|
||||||
this.app.zoneRunOutside(() => {
|
this.app.zoneRunOutside(() => {
|
||||||
|
|
||||||
@ -135,6 +136,7 @@ export class OverlayRef {
|
|||||||
|
|
||||||
this.app.zoneRun(() => {
|
this.app.zoneRun(() => {
|
||||||
ClickBlock(false);
|
ClickBlock(false);
|
||||||
|
this.app.setTransitioning(false);
|
||||||
animation.dispose();
|
animation.dispose();
|
||||||
instance.viewDidEnter && instance.viewDidEnter();
|
instance.viewDidEnter && instance.viewDidEnter();
|
||||||
resolve();
|
resolve();
|
||||||
@ -160,6 +162,7 @@ export class OverlayRef {
|
|||||||
|
|
||||||
animation.after.removeClass('show-overlay');
|
animation.after.removeClass('show-overlay');
|
||||||
ClickBlock(true, animation.duration() + 200);
|
ClickBlock(true, animation.duration() + 200);
|
||||||
|
this.app.setTransitioning(true);
|
||||||
|
|
||||||
animation.play().then(() => {
|
animation.play().then(() => {
|
||||||
instance.viewDidLeave && instance.viewDidLeave();
|
instance.viewDidLeave && instance.viewDidLeave();
|
||||||
@ -168,6 +171,7 @@ export class OverlayRef {
|
|||||||
this._dispose();
|
this._dispose();
|
||||||
|
|
||||||
ClickBlock(false);
|
ClickBlock(false);
|
||||||
|
this.app.setTransitioning(false);
|
||||||
animation.dispose();
|
animation.dispose();
|
||||||
|
|
||||||
resolve();
|
resolve();
|
||||||
|
@ -228,6 +228,7 @@ export class TextInput extends Ion {
|
|||||||
// manually scroll the text input to the top
|
// manually scroll the text input to the top
|
||||||
// do not allow any clicks while it's scrolling
|
// do not allow any clicks while it's scrolling
|
||||||
ClickBlock(true, SCROLL_INTO_VIEW_DURATION + 100);
|
ClickBlock(true, SCROLL_INTO_VIEW_DURATION + 100);
|
||||||
|
this.app.setTransitioning(true);
|
||||||
|
|
||||||
// temporarily move the focus to the focus holder so the browser
|
// temporarily move the focus to the focus holder so the browser
|
||||||
// doesn't freak out while it's trying to get the input in place
|
// doesn't freak out while it's trying to get the input in place
|
||||||
@ -242,6 +243,7 @@ export class TextInput extends Ion {
|
|||||||
|
|
||||||
// all good, allow clicks again
|
// all good, allow clicks again
|
||||||
ClickBlock(false);
|
ClickBlock(false);
|
||||||
|
this.app.setTransitioning(false);
|
||||||
});
|
});
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
@ -279,6 +279,7 @@ export class ViewController extends Ion {
|
|||||||
// block any clicks during the transition and provide a
|
// block any clicks during the transition and provide a
|
||||||
// fallback to remove the clickblock if something goes wrong
|
// fallback to remove the clickblock if something goes wrong
|
||||||
ClickBlock(true, duration + 200);
|
ClickBlock(true, duration + 200);
|
||||||
|
this.app.setTransitioning(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// start the transition
|
// start the transition
|
||||||
@ -396,6 +397,7 @@ export class ViewController extends Ion {
|
|||||||
swipeBackProgress(progress) {
|
swipeBackProgress(progress) {
|
||||||
if (this.sbTransition) {
|
if (this.sbTransition) {
|
||||||
ClickBlock(true, 4000);
|
ClickBlock(true, 4000);
|
||||||
|
this.app.setTransitioning(true);
|
||||||
this.sbTransition.progress( Math.min(1, Math.max(0, progress)) );
|
this.sbTransition.progress( Math.min(1, Math.max(0, progress)) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -481,6 +483,7 @@ export class ViewController extends Ion {
|
|||||||
|
|
||||||
// allow clicks again
|
// allow clicks again
|
||||||
ClickBlock(false);
|
ClickBlock(false);
|
||||||
|
this.app.setTransitioning(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,6 +15,7 @@ export class Activator {
|
|||||||
self.active = {};
|
self.active = {};
|
||||||
self.activatedClass = 'activated';
|
self.activatedClass = 'activated';
|
||||||
self.deactivateTimeout = 180;
|
self.deactivateTimeout = 180;
|
||||||
|
this.deactivateAttempt = 0;
|
||||||
self.pointerTolerance = 4;
|
self.pointerTolerance = 4;
|
||||||
self.isTouch = false;
|
self.isTouch = false;
|
||||||
self.disableClick = 0;
|
self.disableClick = 0;
|
||||||
@ -109,7 +110,8 @@ export class Activator {
|
|||||||
mouseDown(ev) {
|
mouseDown(ev) {
|
||||||
if (this.isDisabledClick()) {
|
if (this.isDisabledClick()) {
|
||||||
console.debug('mouseDown prevent');
|
console.debug('mouseDown prevent');
|
||||||
preventEvent(ev);
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
|
|
||||||
} else if (!self.isTouch) {
|
} else if (!self.isTouch) {
|
||||||
this.pointerStart(ev);
|
this.pointerStart(ev);
|
||||||
@ -123,7 +125,8 @@ export class Activator {
|
|||||||
mouseUp(ev) {
|
mouseUp(ev) {
|
||||||
if (this.isDisabledClick()) {
|
if (this.isDisabledClick()) {
|
||||||
console.debug('mouseUp prevent');
|
console.debug('mouseUp prevent');
|
||||||
preventEvent(ev);
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!self.isTouch) {
|
if (!self.isTouch) {
|
||||||
@ -153,7 +156,7 @@ export class Activator {
|
|||||||
* TODO
|
* TODO
|
||||||
*/
|
*/
|
||||||
pointerEnd(ev) {
|
pointerEnd(ev) {
|
||||||
this.endActive();
|
this.queueDeactivate();
|
||||||
this.moveListeners(false);
|
this.moveListeners(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -162,7 +165,7 @@ export class Activator {
|
|||||||
*/
|
*/
|
||||||
pointerCancel() {
|
pointerCancel() {
|
||||||
console.debug('pointerCancel')
|
console.debug('pointerCancel')
|
||||||
this.clearActive();
|
this.deactivate();
|
||||||
this.moveListeners(false);
|
this.moveListeners(false);
|
||||||
this.disableClick = Date.now();
|
this.disableClick = Date.now();
|
||||||
}
|
}
|
||||||
@ -192,7 +195,8 @@ export class Activator {
|
|||||||
click(ev) {
|
click(ev) {
|
||||||
if (!this.allowClick(ev)) {
|
if (!this.allowClick(ev)) {
|
||||||
console.debug('click prevent');
|
console.debug('click prevent');
|
||||||
preventEvent(ev);
|
ev.preventDefault();
|
||||||
|
ev.stopPropagation();
|
||||||
}
|
}
|
||||||
this.isTouch = false;
|
this.isTouch = false;
|
||||||
}
|
}
|
||||||
@ -240,17 +244,27 @@ export class Activator {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
endActive() {
|
queueDeactivate() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
setTimeout(function() {
|
setTimeout(function() {
|
||||||
self.clearActive();
|
self.deactivate();
|
||||||
}, this.deactivateTimeout);
|
}, this.deactivateTimeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
clearActive() {
|
deactivate() {
|
||||||
const self = this;
|
const self = this;
|
||||||
|
|
||||||
|
if (this.app.isTransitioning() && this.deactivateAttempt < 10) {
|
||||||
|
// the app is actively transitioning, don't bother deactivating
|
||||||
|
// anything this makes it easier on the GPU so it doesn't
|
||||||
|
// have to redraw any buttons during a transition
|
||||||
|
// retry
|
||||||
|
++this.deactivateAttempt;
|
||||||
|
this.queueDeactivate();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// not actively transitioning, good to deactivate any elements
|
||||||
// clear out any elements that are queued to be set to active
|
// clear out any elements that are queued to be set to active
|
||||||
self.queue = {};
|
self.queue = {};
|
||||||
|
|
||||||
@ -263,27 +277,10 @@ export class Activator {
|
|||||||
delete self.active[key];
|
delete self.active[key];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
this.deactivateAttempt = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
clickBlock(enable) {
|
|
||||||
console.log('clickBlock', enable);
|
|
||||||
|
|
||||||
this.doc.removeEventListener('click', preventEvent, true);
|
|
||||||
this.doc.removeEventListener('touchmove', preventEvent, true);
|
|
||||||
this.doc.removeEventListener('touchstart', preventEvent, true);
|
|
||||||
this.doc.removeEventListener('touchend', preventEvent, true);
|
|
||||||
|
|
||||||
if (enable) {
|
|
||||||
this.doc.addEventListener('click', preventEvent, true);
|
|
||||||
this.doc.addEventListener('touchmove', preventEvent, true);
|
|
||||||
this.doc.addEventListener('touchstart', preventEvent, true);
|
|
||||||
this.doc.addEventListener('touchend', preventEvent, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function preventEvent(ev) {
|
|
||||||
ev.preventDefault();
|
|
||||||
ev.stopPropagation();
|
|
||||||
}
|
|
||||||
|
Reference in New Issue
Block a user