refactor(router): remove getContainerEl()

This commit is contained in:
Manu Mtz.-Almeida
2018-03-21 15:48:41 +01:00
parent 4693229c84
commit 17a3001af5
8 changed files with 79 additions and 97 deletions

View File

@ -11,7 +11,7 @@ const OFF_OPACITY = 0.8;
export default function iosTransitionAnimation(Animation: Animation, navEl: HTMLElement, opts: AnimationOptions): Promise<Animation> {
const isRTL = opts.isRTL;
const isRTL = document.dir === 'rtl';
const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
const OFF_LEFT = isRTL ? '31%' : '-31%';

View File

@ -14,11 +14,11 @@ import {
import { ViewController, isViewController } from './view-controller';
import { Animation, Config, DomController, FrameworkDelegate, GestureDetail, NavOutlet } from '../..';
import { RouteID, RouteWrite } from '../router/utils/interfaces';
import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition';
import { assert } from '../../utils/helpers';
import iosTransitionAnimation from './animations/ios.transition';
import mdTransitionAnimation from './animations/md.transition';
import { AnimationOptions, ViewLifecycle, lifecycle, transition } from '../../utils/transition';
@Component({
tag: 'ion-nav',
@ -202,7 +202,7 @@ export class NavControllerBase implements NavOutlet {
setRouteId(id: string, params: any = {}, direction: number): Promise<RouteWrite> {
const active = this.getActive();
if (active && active.component === id) {
return Promise.resolve({changed: false});
return Promise.resolve({changed: false, element: active.element});
}
const viewController = this._views.find(v => v.component === id) || id;
@ -215,6 +215,7 @@ export class NavControllerBase implements NavOutlet {
const p = new Promise(r => markVisible = r);
resolve({
changed: true,
element: this.getActive().element,
markVisible
});
return p;
@ -238,22 +239,11 @@ export class NavControllerBase implements NavOutlet {
@Method()
getRouteId(): RouteID|undefined {
const active = this.getActive();
if (active) {
return {
id: active.element.tagName,
params: active.data
};
}
return undefined;
}
@Method()
getContainerEl(): HTMLElement|undefined {
const active = this.getActive();
if (active) {
return active.element;
}
return undefined;
return active ? {
id: active.element.tagName,
params: active.data,
element: active.element
} : undefined;
}
@Method()
@ -641,7 +631,6 @@ export class NavControllerBase implements NavOutlet {
viewIsReady: opts.viewIsReady,
showGoBack: this.canGoBack(enteringView),
isRTL: document.dir === 'rtl',
progressAnimation,
baseEl: this.el,
enteringEl,

View File

@ -78,9 +78,6 @@ boolean
#### getByIndex()
#### getContainerEl()
#### getPrevious()

View File

@ -1,33 +1,33 @@
import { NavOutlet, NavOutletElement, RouteChain, RouteID } from './interfaces';
export function writeNavState(root: HTMLElement, chain: RouteChain|null, index: number, direction: number): Promise<boolean> {
if (!chain || index >= chain.length) {
return Promise.resolve(direction === 0);
}
const route = chain[index];
const node = searchNavNode(root);
if (!node) {
return Promise.resolve(direction === 0);
}
return node.componentOnReady()
.then(() => node.setRouteId(route.id, route.params, direction))
.catch(() => ({changed: false, markVisible: undefined}))
.then(result => {
if (result.changed) {
direction = 0;
}
const nextEl = node.getContainerEl();
const promise = (nextEl)
? writeNavState(nextEl, chain, index + 1, direction)
: Promise.resolve(direction === 0);
export async function writeNavState(root: HTMLElement|undefined, chain: RouteChain|null, index: number, direction: number): Promise<boolean> {
// find next navigation outlet in the DOM
const outlet = searchNavNode(root);
return promise.then((c) => {
if (result.markVisible) {
result.markVisible();
}
return c;
});
});
// make sure we can continue interating the DOM, otherwise abort
if (!chain || index >= chain.length || !outlet) {
return direction === 0;
}
await outlet.componentOnReady();
const route = chain[index];
const result = await outlet.setRouteId(route.id, route.params, direction);
// if the outlet changed the page, reset navigation to neutral (no direction)
// this means nested outlets will not animate
if (result.changed) {
direction = 0;
}
// recursivelly set nested outlets
const changed = await writeNavState(result.element, chain, index + 1, direction);
// once all nested outlets are visible let's make the parent visible too,
// using markVisible prevents flickering
if (result.markVisible) {
await result.markVisible();
}
return changed;
}
export function readNavState(root: HTMLElement) {
@ -39,7 +39,8 @@ export function readNavState(root: HTMLElement) {
if (pivot) {
const id = pivot.getRouteId();
if (id) {
node = pivot.getContainerEl();
node = id.element;
id.element = undefined;
ids.push(id);
} else {
break;
@ -51,7 +52,7 @@ export function readNavState(root: HTMLElement) {
return {ids, pivot};
}
const QUERY = ':not([no-router]) ion-nav,:not([no-router]) ion-tabs';
const QUERY = ':not([no-router]) ion-nav,:not([no-router]) ion-tabs, :not([no-router]) ion-router-outlet';
function searchNavNode(root: HTMLElement|undefined): NavOutletElement|null {
if (!root) {

View File

@ -2,8 +2,6 @@
export interface NavOutlet {
setRouteId(id: string, data: any, direction: number): Promise<RouteWrite>;
getRouteId(): RouteID|undefined;
getContainerEl(): HTMLElement | undefined;
}
export interface RouterEventDetail {
@ -19,11 +17,13 @@ export interface RouteRedirect {
export interface RouteWrite {
changed: boolean;
element: HTMLElement | undefined;
markVisible?: () => void|Promise<void>;
}
export interface RouteID {
id: string;
element: HTMLElement|undefined;
params?: any;
}

View File

@ -222,9 +222,6 @@ Emitted when the tab changes.
## Methods
#### getContainerEl()
#### getRouteId()

View File

@ -78,8 +78,9 @@ export class Tabs implements NavOutlet {
this.loadConfig('tabsHighlight', true);
}
componentDidLoad() {
return this.initTabs().then(() => this.initSelect());
async componentDidLoad() {
await this.initTabs();
await this.initSelect();
}
componentDidUnload() {
@ -97,26 +98,35 @@ export class Tabs implements NavOutlet {
* @param {number|Tab} tabOrIndex Index, or the Tab instance, of the tab to select.
*/
@Method()
select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
async select(tabOrIndex: number | HTMLIonTabElement): Promise<boolean> {
const selectedTab = this.getTab(tabOrIndex);
if (!this.shouldSwitch(selectedTab)) {
return Promise.resolve(false);
return false;
}
return this.setActive(selectedTab)
.then(() => this.notifyRouter())
.then(() => this.tabSwitch());
await this.setActive(selectedTab);
await this.notifyRouter();
return this.tabSwitch();
}
@Method()
setRouteId(id: string): Promise<RouteWrite> {
async setRouteId(id: string): Promise<RouteWrite> {
const selectedTab = this.getTab(id);
if (!this.shouldSwitch(selectedTab)) {
return Promise.resolve({changed: false});
return {changed: false, element: this.selectedTab};
}
return this.setActive(selectedTab).then(() => ({
await this.setActive(selectedTab);
return {
changed: true,
element: this.selectedTab,
markVisible: () => { this.tabSwitch(); }
}));
};
}
@Method()
getRouteId(): RouteID|undefined {
const id = this.selectedTab && this.selectedTab.getTabId();
return id ? {id, element: this.selectedTab} : undefined;
}
@Method()
@ -138,17 +148,6 @@ export class Tabs implements NavOutlet {
return this.selectedTab;
}
@Method()
getRouteId(): RouteID|undefined {
const id = this.selectedTab && this.selectedTab.getTabId();
return id ? {id} : undefined;
}
@Method()
getContainerEl(): HTMLElement|undefined {
return this.selectedTab;
}
private initTabs() {
const tabs = this.tabs = Array.from(this.el.querySelectorAll('ion-tab'));
const tabPromises = tabs.map(tab => {
@ -161,7 +160,7 @@ export class Tabs implements NavOutlet {
return Promise.all(tabPromises);
}
private initSelect(): Promise<void> {
private async initSelect(): Promise<void> {
if (this.useRouter) {
if (Build.isDev) {
const selectedTab = this.tabs.find(t => t.selected);
@ -170,7 +169,7 @@ export class Tabs implements NavOutlet {
'Define routes properly the define which tab is selected');
}
}
return Promise.resolve();
return;
}
// find pre-selected tabs
const selectedTab = this.tabs.find(t => t.selected) ||
@ -182,14 +181,14 @@ export class Tabs implements NavOutlet {
tab.selected = false;
}
}
const promise = selectedTab ? selectedTab.setActive() : Promise.resolve(null);
return promise.then(() => {
this.selectedTab = selectedTab;
if (selectedTab) {
selectedTab.selected = true;
selectedTab.active = true;
}
});
if (selectedTab) {
await selectedTab.setActive();
}
this.selectedTab = selectedTab;
if (selectedTab) {
selectedTab.selected = true;
selectedTab.active = true;
}
}
private loadConfig(attrKey: string, fallback: any) {

View File

@ -9,7 +9,7 @@ export async function transition(opts: AnimationOptions): Promise<Animation|void
setZIndex(enteringEl, leavingEl, opts.direction);
showPages(enteringEl, leavingEl);
showGoBack(enteringEl, opts.showGoBack);
showGoBack(enteringEl, !!opts.showGoBack);
// fast path for no animation
if (!opts.animationBuilder && !opts.animation) {
@ -173,13 +173,12 @@ export const enum ViewLifecycle {
export interface AnimationOptions {
animationCtrl: HTMLIonAnimationControllerElement;
animationBuilder: AnimationBuilder;
animation: Animation|undefined;
direction: NavDirection;
duration: number|undefined;
easing: string|undefined;
isRTL: boolean;
showGoBack: boolean;
viewIsReady: undefined | (() => Promise<any>);
animation?: Animation;
direction?: NavDirection;
duration?: number;
easing?: string;
viewIsReady?: () => Promise<any>;
showGoBack?: boolean;
progressAnimation?: Function;
enteringEl: HTMLElement;
leavingEl: HTMLElement;