Skip to content

Commit 88f2981

Browse files
committed
fix(router): flickering 2
1 parent f2ac6e3 commit 88f2981

File tree

9 files changed

+75
-54
lines changed

9 files changed

+75
-54
lines changed

packages/core/src/components/nav/animations/ios.transition.ts

+10-10
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ export default function iosTransitionAnimation(Animation: Animation, _: HTMLElem
3535
const backDirection = (opts.direction === 'back');
3636
// setting up enter view
3737
if (enteringEl) {
38-
const contentEl = enteringEl.querySelector('ion-content');
39-
const headerEls = enteringEl.querySelectorAll('ion-header > *:not(ion-toolbar),ion-footer > *');
40-
const enteringToolBarEle = enteringEl.querySelector('ion-toolbar');
38+
const contentEl = enteringEl.querySelector(':scope > ion-content');
39+
const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
40+
const enteringToolBarEle = enteringEl.querySelector(':scope > ion-header > ion-toolbar');
4141
const enteringContent = new Animation();
4242

4343
if (!contentEl && !enteringToolBarEle && headerEls.length === 0) {
44-
enteringContent.addElement(enteringEl.querySelector('ion-page,ion-nav,ion-tabs'));
44+
enteringContent.addElement(enteringEl.querySelector(':scope > ion-page, :scope > ion-nav, :scope > ion-tabs'));
4545
} else {
4646
enteringContent.addElement(contentEl);
4747
enteringContent.addElement(headerEls);
@@ -110,7 +110,7 @@ export default function iosTransitionAnimation(Animation: Animation, _: HTMLElem
110110

111111

112112
const enteringBackBtnText = new Animation();
113-
enteringBackBtnText.addElement(enteringToolBarEle.querySelector('.back-button .button-text'));
113+
enteringBackBtnText.addElement(enteringToolBarEle.querySelector('ion-back-button .button-text'));
114114

115115
enteringBackBtnText.fromTo(TRANSLATEX, (isRTL ? '-100px' : '100px'), '0px');
116116
enteringToolBar.add(enteringBackBtnText);
@@ -125,8 +125,8 @@ export default function iosTransitionAnimation(Animation: Animation, _: HTMLElem
125125
if (leavingEl) {
126126

127127
const leavingContent = new Animation();
128-
leavingContent.addElement(leavingEl.querySelector('ion-content'));
129-
leavingContent.addElement(leavingEl.querySelectorAll('ion-header > *:not(ion-toolbar),ion-footer > *'));
128+
leavingContent.addElement(leavingEl.querySelector(':scope > ion-content'));
129+
leavingContent.addElement(leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *'));
130130
rootTransition.add(leavingContent);
131131

132132
if (backDirection) {
@@ -143,7 +143,7 @@ export default function iosTransitionAnimation(Animation: Animation, _: HTMLElem
143143
.fromTo(OPACITY, 1, OFF_OPACITY, true);
144144
}
145145

146-
const leavingToolBarEle = leavingEl.querySelector('ion-toolbar');
146+
const leavingToolBarEle = leavingEl.querySelector(':scope > ion-header > ion-toolbar');
147147
if (leavingToolBarEle) {
148148
const leavingToolBar = new Animation();
149149
leavingToolBar.addElement(leavingToolBarEle);
@@ -158,7 +158,7 @@ export default function iosTransitionAnimation(Animation: Animation, _: HTMLElem
158158
leavingToolBarBg.addElement(leavingToolBarEle.querySelector('.toolbar-background'));
159159

160160
const leavingBackButton = new Animation();
161-
leavingBackButton.addElement(leavingToolBarEle.querySelector('.back-button'));
161+
leavingBackButton.addElement(leavingToolBarEle.querySelector('ion-back-button'));
162162

163163
leavingToolBar
164164
.add(leavingTitle)
@@ -184,7 +184,7 @@ export default function iosTransitionAnimation(Animation: Animation, _: HTMLElem
184184
.fromTo(OPACITY, 1, 0.01, true);
185185

186186
const leavingBackBtnText = new Animation();
187-
leavingBackBtnText.addElement(leavingToolBarEle.querySelector('.back-button .button-text'));
187+
leavingBackBtnText.addElement(leavingToolBarEle.querySelector('ion-back-button .button-text'));
188188
leavingBackBtnText.fromTo(TRANSLATEX, CENTER, (isRTL ? -115 : 115) + 'px');
189189
leavingToolBar.add(leavingBackBtnText);
190190

packages/core/src/components/nav/animations/md.transition.ts

+1-10
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,10 @@ function getIonPageElement(element: HTMLElement) {
6565
if (element.classList.contains('ion-page')) {
6666
return element;
6767
}
68-
const ionPage = element.querySelector('.ion-page');
68+
const ionPage = element.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs');
6969
if (ionPage) {
7070
return ionPage;
7171
}
72-
const ionNav = element.querySelector('ion-nav');
73-
if (ionNav) {
74-
return ionNav;
75-
}
76-
const ionTabs = element.querySelector('ion-tabs');
77-
if (ionTabs) {
78-
return ionTabs;
79-
}
80-
8172
// idk, return the original element so at least something animates and we don't have a null pointer
8273
return element;
8374
}

packages/core/src/components/nav/nav-util.ts

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export interface NavOptions {
144144
ev?: any;
145145
updateUrl?: boolean;
146146
isNavRoot?: boolean;
147+
viewIsReady?: () => Promise<any>;
147148
}
148149

149150
export function isPresent(val: any): val is any { return val !== undefined && val !== null; }

packages/core/src/components/nav/nav.tsx

+45-13
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import { Transition } from './transition';
2626

2727
import iosTransitionAnimation from './animations/ios.transition';
2828
import mdTransitionAnimation from './animations/md.transition';
29-
import { RouteID } from '../router/utils/interfaces';
29+
import { RouteID, RouteWrite } from '../router/utils/interfaces';
3030

3131
const TrnsCtrl = new TransitionController();
3232

@@ -203,17 +203,41 @@ export class NavControllerBase implements NavOutlet {
203203
}
204204

205205
@Method()
206-
setRouteId(id: string, params: any = {}, direction: number): Promise<boolean> {
206+
setRouteId(id: string, params: any = {}, direction: number): Promise<RouteWrite> {
207207
const active = this.getActive();
208208
if (active && active.component === id) {
209-
return Promise.resolve(false);
209+
return Promise.resolve({changed: false});
210210
}
211+
212+
let resolve: (result: RouteWrite) => void;
213+
const promise = new Promise<RouteWrite>((r) => resolve = r);
214+
215+
const commonOpts: NavOptions = {
216+
viewIsReady: () => {
217+
let markVisible;
218+
const p = new Promise((r) => markVisible = r);
219+
resolve({
220+
changed: true,
221+
markVisible
222+
});
223+
return p;
224+
}
225+
};
226+
211227
if (direction === 1) {
212-
return this.push(id, params).then(() => true);
213-
} else if (direction === -1 && this.canGoBack()) {
214-
return this.pop().then(() => true);
228+
this.push(id, params, commonOpts);
229+
} else if (direction === -1) {
230+
this.canGoBack()
231+
? this.pop(commonOpts)
232+
: this.setRoot(id, params, {
233+
...commonOpts,
234+
direction: DIRECTION_BACK,
235+
animate: true
236+
});
237+
} else {
238+
this.setRoot(id, params, commonOpts);
215239
}
216-
return this.setRoot(id, params).then(() => true);
240+
return promise;
217241
}
218242

219243
@Method()
@@ -340,9 +364,13 @@ export class NavControllerBase implements NavOutlet {
340364
this.isTransitioning = false;
341365
// let's see if there's another to kick off
342366
this._nextTrns();
343-
this.ionNavChanged.emit({
344-
isPop: result.direction === 'back'
345-
});
367+
const router = document.querySelector('ion-router');
368+
const isPop = result.direction === DIRECTION_BACK;
369+
if (router) {
370+
router.navChanged(isPop);
371+
}
372+
373+
this.ionNavChanged.emit({isPop});
346374

347375
if (ti.done) {
348376
ti.done(
@@ -425,15 +453,19 @@ export class NavControllerBase implements NavOutlet {
425453
return true;
426454
}
427455

428-
private _waitUntilReady(enteringView: ViewController, leavingView: ViewController) {
456+
private _waitUntilReady(enteringView: ViewController, leavingView: ViewController, ti: TransitionInstruction) {
429457
const promises = [];
430458
if (enteringView) {
431459
promises.push(isReady(enteringView.element));
432460
}
433461
if (leavingView) {
434462
promises.push(isReady(leavingView.element));
435463
}
436-
return Promise.all(promises);
464+
const promise = Promise.all(promises);
465+
if (ti.opts.viewIsReady) {
466+
return promise.then(ti.opts.viewIsReady);
467+
}
468+
return promise;
437469
}
438470

439471
private _startTI(ti: TransitionInstruction): Promise<void> {
@@ -690,7 +722,7 @@ export class NavControllerBase implements NavOutlet {
690722

691723
// transition start has to be registered before attaching the view to the DOM!
692724
const promise = new Promise<void>(resolve => transition.registerStart(resolve))
693-
.then(() => this._waitUntilReady(enteringView, leavingView))
725+
.then(() => this._waitUntilReady(enteringView, leavingView, ti))
694726
.then(() => this._transitionInit(transition, enteringView, leavingView, opts))
695727
.then(() => this._transitionStart(transition, enteringView, leavingView, opts));
696728

packages/core/src/components/router/utils/dom.ts

+4-4
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ export function writeNavState(root: HTMLElement, chain: RouteChain|null, index:
1111
}
1212
return node.componentOnReady()
1313
.then(() => node.setRouteId(route.id, route.params, direction))
14-
.then(changed => {
15-
if (changed) {
14+
.then(result => {
15+
if (result.changed) {
1616
direction = 0;
1717
}
1818
const nextEl = node.getContainerEl();
1919
const promise = (nextEl)
2020
? writeNavState(nextEl, chain, index + 1, direction)
2121
: Promise.resolve();
2222

23-
if (node.markVisible) {
24-
return promise.then(() => node.markVisible());
23+
if (result.markVisible) {
24+
return promise.then(() => result.markVisible());
2525
}
2626
return promise;
2727
});

packages/core/src/components/router/utils/interfaces.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11

22
export interface NavOutlet {
3-
setRouteId(id: string, data: any, direction: number): Promise<boolean>;
4-
markVisible?(): Promise<void>;
3+
setRouteId(id: string, data: any, direction: number): Promise<RouteWrite>;
54
getRouteId(): RouteID|null;
65

76
getContainerEl(): HTMLElement | null;
87
}
98

9+
export interface RouteWrite {
10+
changed: boolean;
11+
markVisible?: () => void|Promise<void>;
12+
}
13+
1014
export interface RouteID {
1115
id: string;
1216
params?: any;

packages/core/src/components/tabs/readme.md

-3
Original file line numberDiff line numberDiff line change
@@ -234,9 +234,6 @@ Emitted when the tab changes.
234234
#### getTab()
235235

236236

237-
#### markVisible()
238-
239-
240237
#### select()
241238

242239

packages/core/src/components/tabs/tabs.tsx

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { Build, Component, Element, Event, EventEmitter, Listen, Method, Prop, State } from '@stencil/core';
22
import { Config, NavOutlet } from '../../index';
3-
import { RouteID } from '../router/utils/interfaces';
3+
import { RouteID, RouteWrite } from '../router/utils/interfaces';
44

55

66
@Component({
@@ -105,12 +105,15 @@ export class Tabs implements NavOutlet {
105105
}
106106

107107
@Method()
108-
setRouteId(id: string): Promise<boolean> {
108+
setRouteId(id: string): Promise<RouteWrite> {
109109
const selectedTab = this.getTab(id);
110110
if (!this.shouldSwitch(selectedTab)) {
111-
return Promise.resolve(false);
111+
return Promise.resolve({changed: false});
112112
}
113-
return this.setActive(selectedTab).then(() => true);
113+
return this.setActive(selectedTab).then(() => ({
114+
changed: true,
115+
markVisible: () => { this.tabSwitch(); }
116+
}));
114117
}
115118

116119
@Method()
@@ -132,13 +135,6 @@ export class Tabs implements NavOutlet {
132135
return this.selectedTab;
133136
}
134137

135-
136-
@Method()
137-
markVisible(): Promise<void> {
138-
this.tabSwitch();
139-
return Promise.resolve();
140-
}
141-
142138
@Method()
143139
getRouteId(): RouteID|null {
144140
const id = this.selectedTab && this.selectedTab.getTabId();

packages/core/src/components/tap-click/tap-click.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ export class TapClick {
8585

8686
private pointerUp(ev: UIEvent) {
8787
this.setActivatedElement(null, ev);
88-
if (this.cancelled) {
88+
if (this.cancelled && ev.cancelable) {
8989
ev.preventDefault();
9090
}
9191
}

0 commit comments

Comments
 (0)