UNPKG

framework7

Version:

Full featured mobile HTML framework for building iOS & Android apps

864 lines (806 loc) 30.2 kB
import $ from 'dom7'; import { document } from 'ssr-window'; import Utils from '../../utils/utils'; import History from '../../utils/history'; import redirect from './redirect'; import processRouteQueue from './process-route-queue'; import appRouterCheck from './app-router-check'; function refreshPage() { const router = this; appRouterCheck(router, 'refreshPage'); return router.navigate(router.currentRoute.url, { ignoreCache: true, reloadCurrent: true, }); } function forward(el, forwardOptions = {}) { const router = this; const $el = $(el); const app = router.app; const view = router.view; const options = Utils.extend(false, { animate: router.params.animate, pushState: true, replaceState: false, history: true, reloadCurrent: router.params.reloadPages, reloadPrevious: false, reloadAll: false, clearPreviousHistory: false, reloadDetail: router.params.reloadDetail, on: {}, }, forwardOptions); const masterDetailEnabled = router.params.masterDetailBreakpoint > 0; const isMaster = masterDetailEnabled && options.route && options.route.route && options.route.route.master === true; let masterPageEl; let otherDetailPageEl; let currentRouteIsModal = router.currentRoute.modal; let modalType; if (!currentRouteIsModal) { ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach((modalLoadProp) => { if (router.currentRoute && router.currentRoute.route && router.currentRoute.route[modalLoadProp]) { currentRouteIsModal = true; modalType = modalLoadProp; } }); } if (currentRouteIsModal) { const modalToClose = router.currentRoute.modal || router.currentRoute.route.modalInstance || app[modalType].get(); const previousUrl = router.history[router.history.length - 2]; let previousRoute = router.findMatchingRoute(previousUrl); if (!previousRoute && previousUrl) { previousRoute = { url: previousUrl, path: previousUrl.split('?')[0], query: Utils.parseUrlQuery(previousUrl), route: { path: previousUrl.split('?')[0], url: previousUrl, }, }; } router.modalRemove(modalToClose); } const dynamicNavbar = router.dynamicNavbar; const separateNavbar = router.separateNavbar; const $viewEl = router.$el; const $newPage = $el; const reload = options.reloadPrevious || options.reloadCurrent || options.reloadAll; let $oldPage; let $navbarEl; let $newNavbarInner; let $oldNavbarInner; router.allowPageChange = false; if ($newPage.length === 0) { router.allowPageChange = true; return router; } if ($newPage.length) { // Remove theme elements router.removeThemeElements($newPage); } if (dynamicNavbar) { $newNavbarInner = $newPage.children('.navbar').children('.navbar-inner'); if (separateNavbar) { $navbarEl = router.$navbarEl; if ($newNavbarInner.length > 0) { $newPage.children('.navbar').remove(); } if ($newNavbarInner.length === 0 && $newPage[0] && $newPage[0].f7Page) { // Try from pageData $newNavbarInner = $newPage[0].f7Page.$navbarEl; } } } // Save Keep Alive Cache if (options.route && options.route.route && options.route.route.keepAlive && !options.route.route.keepAliveData) { options.route.route.keepAliveData = { pageEl: $el[0], }; } // Pages In View const $pagesInView = $viewEl .children('.page:not(.stacked)') .filter((index, pageInView) => pageInView !== $newPage[0]); // Navbars In View let $navbarsInView; if (separateNavbar) { $navbarsInView = $navbarEl .children('.navbar-inner:not(.stacked)') .filter((index, navbarInView) => navbarInView !== $newNavbarInner[0]); } // Exit when reload previous and only 1 page in view so nothing ro reload if (options.reloadPrevious && $pagesInView.length < 2) { router.allowPageChange = true; return router; } // Find Detail' master page let isDetail; let reloadDetail; if (masterDetailEnabled && !options.reloadAll) { for (let i = 0; i < $pagesInView.length; i += 1) { if (!masterPageEl && $pagesInView[i].classList.contains('page-master') ) { masterPageEl = $pagesInView[i]; continue; // eslint-disable-line } } isDetail = !isMaster && masterPageEl; if (isDetail) { // Find Other Detail if (masterPageEl) { for (let i = 0; i < $pagesInView.length; i += 1) { if ($pagesInView[i].classList.contains('page-master-detail') ) { otherDetailPageEl = $pagesInView[i]; continue; // eslint-disable-line } } } } reloadDetail = isDetail && options.reloadDetail && app.width >= router.params.masterDetailBreakpoint && masterPageEl; } // New Page let newPagePosition = 'next'; if (options.reloadCurrent || options.reloadAll || reloadDetail) { newPagePosition = 'current'; } else if (options.reloadPrevious) { newPagePosition = 'previous'; } $newPage .removeClass('page-previous page-current page-next') .addClass(`page-${newPagePosition}${isMaster ? ' page-master' : ''}${isDetail ? ' page-master-detail' : ''}`) .removeClass('stacked') .trigger('page:unstack') .trigger('page:position', { position: newPagePosition }); router.emit('pageUnstack', $newPage[0]); router.emit('pagePosition', $newPage[0], newPagePosition); if (isMaster || isDetail) { $newPage.trigger('page:role', { role: isMaster ? 'master' : 'detail' }); } if (dynamicNavbar && $newNavbarInner.length) { $newNavbarInner .removeClass('navbar-previous navbar-current navbar-next') .addClass(`navbar-${newPagePosition}${isMaster ? ' navbar-master' : ''}${isDetail ? ' navbar-master-detail' : ''}`) .removeClass('stacked'); } // Find Old Page if (options.reloadCurrent || reloadDetail) { $oldPage = $pagesInView.eq($pagesInView.length - 1); if (separateNavbar) { // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 1); $oldNavbarInner = $(app.navbar.getElByPage($oldPage)); } } else if (options.reloadPrevious) { $oldPage = $pagesInView.eq($pagesInView.length - 2); if (separateNavbar) { // $oldNavbarInner = $navbarsInView.eq($pagesInView.length - 2); $oldNavbarInner = $(app.navbar.getElByPage($oldPage)); } } else if (options.reloadAll) { $oldPage = $pagesInView.filter((index, pageEl) => pageEl !== $newPage[0]); if (separateNavbar) { $oldNavbarInner = $navbarsInView.filter((index, navbarEl) => navbarEl !== $newNavbarInner[0]); } } else { if ($pagesInView.length > 1) { let i = 0; for (i = 0; i < $pagesInView.length - 1; i += 1) { if (masterPageEl && $pagesInView[i] === masterPageEl ) { $pagesInView.eq(i).addClass('page-master-stacked'); $pagesInView.eq(i).trigger('page:masterstack'); router.emit('pageMasterStack', $pagesInView[i]); if (separateNavbar) { $(app.navbar.getElByPage(masterPageEl)).addClass('navbar-master-stacked'); } continue; // eslint-disable-line } const oldNavbarInnerEl = app.navbar.getElByPage($pagesInView.eq(i)); if (router.params.stackPages) { $pagesInView.eq(i).addClass('stacked'); $pagesInView.eq(i).trigger('page:stack'); router.emit('pageStack', $pagesInView[i]); if (separateNavbar) { $(oldNavbarInnerEl).addClass('stacked'); } } else { // Page remove event router.pageCallback('beforeRemove', $pagesInView[i], $navbarsInView && $navbarsInView[i], 'previous', undefined, options); router.removePage($pagesInView[i]); if (separateNavbar && oldNavbarInnerEl) { router.removeNavbar(oldNavbarInnerEl); } } } } $oldPage = $viewEl .children('.page:not(.stacked)') .filter((index, page) => page !== $newPage[0]); if (separateNavbar) { $oldNavbarInner = $navbarEl .children('.navbar-inner:not(.stacked)') .filter((index, navbarInner) => navbarInner !== $newNavbarInner[0]); } } if (dynamicNavbar && !separateNavbar) { $oldNavbarInner = $oldPage.children('.navbar').children('.navbar-inner'); } if (isDetail && !options.reloadAll) { if ($oldPage.length > 1 || reloadDetail) { $oldPage = $oldPage.filter((pageIndex, pageEl) => !pageEl.classList.contains('page-master')); } if ($oldNavbarInner && ($oldNavbarInner.length > 1 || reloadDetail)) { $oldNavbarInner = $oldNavbarInner.filter((navbarIndex, navbarEl) => !navbarEl.classList.contains('navbar-master')); } } // Push State if (router.params.pushState && (options.pushState || options.replaceState) && !options.reloadPrevious) { const pushStateRoot = router.params.pushStateRoot || ''; History[options.reloadCurrent || (reloadDetail && otherDetailPageEl) || options.reloadAll || options.replaceState ? 'replace' : 'push']( view.id, { url: options.route.url, }, pushStateRoot + router.params.pushStateSeparator + options.route.url ); } if (!options.reloadPrevious) { // Current Page & Navbar router.currentPageEl = $newPage[0]; if (dynamicNavbar && $newNavbarInner.length) { router.currentNavbarEl = $newNavbarInner[0]; } else { delete router.currentNavbarEl; } // Current Route router.currentRoute = options.route; } // Update router history const url = options.route.url; if (options.history) { if (((options.reloadCurrent || (reloadDetail && otherDetailPageEl)) && router.history.length) > 0 || options.replaceState) { router.history[router.history.length - (options.reloadPrevious ? 2 : 1)] = url; } else if (options.reloadPrevious) { router.history[router.history.length - 2] = url; } else if (options.reloadAll) { router.history = [url]; } else { router.history.push(url); } } router.saveHistory(); // Insert new page and navbar const newPageInDom = $newPage.parents(document).length > 0; const f7Component = $newPage[0].f7Component; if (options.reloadPrevious) { if (f7Component && !newPageInDom) { f7Component.$mount((componentEl) => { $(componentEl).insertBefore($oldPage); }); } else { $newPage.insertBefore($oldPage); } if (separateNavbar && $newNavbarInner.length) { if ($newNavbarInner.children('.title-large').length) { $newNavbarInner.addClass('navbar-inner-large'); } if ($oldNavbarInner.length) { $newNavbarInner.insertBefore($oldNavbarInner); } else { if (!router.$navbarEl.parents(document).length) { router.$el.prepend(router.$navbarEl); } $navbarEl.append($newNavbarInner); } } } else { if ($oldPage.next('.page')[0] !== $newPage[0]) { if (f7Component && !newPageInDom) { f7Component.$mount((componentEl) => { $viewEl.append(componentEl); }); } else { $viewEl.append($newPage[0]); } } if (separateNavbar && $newNavbarInner.length) { if ($newNavbarInner.children('.title-large').length) { $newNavbarInner.addClass('navbar-inner-large'); } if (!router.$navbarEl.parents(document).length) { router.$el.prepend(router.$navbarEl); } $navbarEl.append($newNavbarInner[0]); } } if (!newPageInDom) { router.pageCallback('mounted', $newPage, $newNavbarInner, newPagePosition, reload ? newPagePosition : 'current', options, $oldPage); } else if (options.route && options.route.route && options.route.route.keepAlive && !$newPage[0].f7PageMounted) { $newPage[0].f7PageMounted = true; router.pageCallback('mounted', $newPage, $newNavbarInner, newPagePosition, reload ? newPagePosition : 'current', options, $oldPage); } // Remove old page if ((options.reloadCurrent || reloadDetail) && $oldPage.length > 0) { if (router.params.stackPages && router.initialPages.indexOf($oldPage[0]) >= 0) { $oldPage.addClass('stacked'); $oldPage.trigger('page:stack'); router.emit('pageStack', $oldPage[0]); if (separateNavbar) { $oldNavbarInner.addClass('stacked'); } } else { // Page remove event router.pageCallback('beforeOut', $oldPage, $oldNavbarInner, 'current', undefined, options); router.pageCallback('afterOut', $oldPage, $oldNavbarInner, 'current', undefined, options); router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'current', undefined, options); router.removePage($oldPage); if (separateNavbar && $oldNavbarInner && $oldNavbarInner.length) { router.removeNavbar($oldNavbarInner); } } } else if (options.reloadAll) { $oldPage.each((index, pageEl) => { const $oldPageEl = $(pageEl); const $oldNavbarInnerEl = $(app.navbar.getElByPage($oldPageEl)); if (router.params.stackPages && router.initialPages.indexOf($oldPageEl[0]) >= 0) { $oldPageEl.addClass('stacked'); $oldPageEl.trigger('page:stack'); router.emit('pageStack', $oldPageEl[0]); if (separateNavbar) { $oldNavbarInnerEl.addClass('stacked'); } } else { // Page remove event if ($oldPageEl.hasClass('page-current')) { router.pageCallback('beforeOut', $oldPage, $oldNavbarInner, 'current', undefined, options); router.pageCallback('afterOut', $oldPage, $oldNavbarInner, 'current', undefined, options); } router.pageCallback('beforeRemove', $oldPageEl, $oldNavbarInner && $oldNavbarInner.eq(index), 'previous', undefined, options); router.removePage($oldPageEl); if (separateNavbar && $oldNavbarInnerEl.length) { router.removeNavbar($oldNavbarInnerEl); } } }); } else if (options.reloadPrevious) { if (router.params.stackPages && router.initialPages.indexOf($oldPage[0]) >= 0) { $oldPage.addClass('stacked'); $oldPage.trigger('page:stack'); router.emit('pageStack', $oldPage[0]); if (separateNavbar) { $oldNavbarInner.addClass('stacked'); } } else { // Page remove event router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'previous', undefined, options); router.removePage($oldPage); if (separateNavbar && $oldNavbarInner && $oldNavbarInner.length) { router.removeNavbar($oldNavbarInner); } } } // Load Tab if (options.route.route.tab) { router.tabLoad(options.route.route.tab, Utils.extend({}, options, { history: false, pushState: false, })); } // Page init and before init events router.pageCallback('init', $newPage, $newNavbarInner, newPagePosition, reload ? newPagePosition : 'current', options, $oldPage); if (options.reloadCurrent || options.reloadAll || reloadDetail) { router.allowPageChange = true; router.pageCallback('beforeIn', $newPage, $newNavbarInner, newPagePosition, 'current', options); $newPage.removeAttr('aria-hidden'); if (dynamicNavbar && $newNavbarInner) { $newNavbarInner.removeAttr('aria-hidden'); } router.pageCallback('afterIn', $newPage, $newNavbarInner, newPagePosition, 'current', options); if (options.reloadCurrent && options.clearPreviousHistory) router.clearPreviousHistory(); if (reloadDetail) { masterPageEl.classList.add('page-previous'); masterPageEl.classList.remove('page-current'); $(masterPageEl).trigger('page:position', { position: 'previous' }); router.emit('pagePosition', masterPageEl, 'previous'); if (masterPageEl.f7Page && masterPageEl.f7Page.navbarEl) { masterPageEl.f7Page.navbarEl.classList.add('navbar-previous'); masterPageEl.f7Page.navbarEl.classList.remove('navbar-current'); } } return router; } if (options.reloadPrevious) { router.allowPageChange = true; return router; } // Before animation event router.pageCallback('beforeOut', $oldPage, $oldNavbarInner, 'current', 'previous', options); router.pageCallback('beforeIn', $newPage, $newNavbarInner, 'next', 'current', options); // Animation function afterAnimation() { const pageClasses = 'page-previous page-current page-next'; const navbarClasses = 'navbar-previous navbar-current navbar-next'; $newPage.removeClass(pageClasses).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position: 'current' }); router.emit('pagePosition', $newPage[0], 'current'); $oldPage.removeClass(pageClasses).addClass('page-previous').trigger('page:position', { position: 'previous' }); router.emit('pagePosition', $oldPage[0], 'previous'); if (!$oldPage.hasClass('page-master')) { $oldPage.attr('aria-hidden', 'true'); } if (dynamicNavbar) { $newNavbarInner.removeClass(navbarClasses).addClass('navbar-current').removeAttr('aria-hidden'); $oldNavbarInner.removeClass(navbarClasses).addClass('navbar-previous'); if (!$oldNavbarInner.hasClass('navbar-master')) { $oldNavbarInner.attr('aria-hidden', 'true'); } } // After animation event router.allowPageChange = true; router.pageCallback('afterOut', $oldPage, $oldNavbarInner, 'current', 'previous', options); router.pageCallback('afterIn', $newPage, $newNavbarInner, 'next', 'current', options); let keepOldPage = (router.params.preloadPreviousPage || router.params[`${app.theme}SwipeBack`]) && !isMaster; if (!keepOldPage) { if ($newPage.hasClass('smart-select-page') || $newPage.hasClass('photo-browser-page') || $newPage.hasClass('autocomplete-page') || $newPage.hasClass('color-picker-page')) { keepOldPage = true; } } if (!keepOldPage) { if (router.params.stackPages) { $oldPage.addClass('stacked'); $oldPage.trigger('page:stack'); router.emit('pageStack', $oldPage[0]); if (separateNavbar) { $oldNavbarInner.addClass('stacked'); } } else if (!($newPage.attr('data-name') && $newPage.attr('data-name') === 'smart-select-page')) { // Remove event router.pageCallback('beforeRemove', $oldPage, $oldNavbarInner, 'previous', undefined, options); router.removePage($oldPage); if (separateNavbar && $oldNavbarInner.length) { router.removeNavbar($oldNavbarInner); } } } if (options.clearPreviousHistory) router.clearPreviousHistory(); router.emit('routeChanged', router.currentRoute, router.previousRoute, router); if (router.params.pushState) { History.clearRouterQueue(); } } function setPositionClasses() { const pageClasses = 'page-previous page-current page-next'; const navbarClasses = 'navbar-previous navbar-current navbar-next'; $oldPage.removeClass(pageClasses).addClass('page-current').removeAttr('aria-hidden').trigger('page:position', { position: 'current' }); router.emit('pagePosition', $oldPage[0], 'current'); $newPage.removeClass(pageClasses).addClass('page-next').removeAttr('aria-hidden').trigger('page:position', { position: 'next' }); router.emit('pagePosition', $newPage[0], 'next'); if (dynamicNavbar) { $oldNavbarInner.removeClass(navbarClasses).addClass('navbar-current').removeAttr('aria-hidden'); $newNavbarInner.removeClass(navbarClasses).addClass('navbar-next').removeAttr('aria-hidden'); } } if (options.animate && !(isMaster && app.width >= router.params.masterDetailBreakpoint)) { const delay = router.params[`${router.app.theme}PageLoadDelay`]; if (delay) { setTimeout(() => { setPositionClasses(); router.animate($oldPage, $newPage, $oldNavbarInner, $newNavbarInner, 'forward', () => { afterAnimation(); }); }, delay); } else { setPositionClasses(); router.animate($oldPage, $newPage, $oldNavbarInner, $newNavbarInner, 'forward', () => { afterAnimation(); }); } } else { afterAnimation(); } return router; } function load(loadParams = {}, loadOptions = {}, ignorePageChange) { const router = this; if (!router.allowPageChange && !ignorePageChange) return router; const params = loadParams; const options = loadOptions; const { url, content, el, pageName, template, templateUrl, component, componentUrl } = params; if (!options.reloadCurrent && options.route && options.route.route && options.route.route.parentPath && router.currentRoute.route && router.currentRoute.route.parentPath === options.route.route.parentPath) { // Do something nested if (options.route.url === router.url) { router.allowPageChange = true; return false; } // Check for same params let sameParams = Object.keys(options.route.params).length === Object.keys(router.currentRoute.params).length; if (sameParams) { // Check for equal params name Object.keys(options.route.params).forEach((paramName) => { if ( !(paramName in router.currentRoute.params) || (router.currentRoute.params[paramName] !== options.route.params[paramName]) ) { sameParams = false; } }); } if (sameParams) { if (options.route.route.tab) { return router.tabLoad(options.route.route.tab, options); } return false; } if (!sameParams && options.route.route.tab && router.currentRoute.route.tab && router.currentRoute.parentPath === options.route.parentPath ) { return router.tabLoad(options.route.route.tab, options); } } if ( options.route && options.route.url && router.url === options.route.url && !(options.reloadCurrent || options.reloadPrevious) && !router.params.allowDuplicateUrls ) { router.allowPageChange = true; return false; } if (!options.route && url) { options.route = router.parseRouteUrl(url); Utils.extend(options.route, { route: { url, path: url } }); } // Component Callbacks function resolve(pageEl, newOptions) { return router.forward(pageEl, Utils.extend(options, newOptions)); } function reject() { router.allowPageChange = true; return router; } if (url || templateUrl || componentUrl) { router.allowPageChange = false; } // Proceed if (content) { router.forward(router.getPageEl(content), options); } else if (template || templateUrl) { // Parse template and send page element try { router.pageTemplateLoader(template, templateUrl, options, resolve, reject); } catch (err) { router.allowPageChange = true; throw err; } } else if (el) { // Load page from specified HTMLElement or by page name in pages container router.forward(router.getPageEl(el), options); } else if (pageName) { // Load page by page name in pages container router.forward(router.$el.children(`.page[data-name="${pageName}"]`).eq(0), options); } else if (component || componentUrl) { // Load from component (F7/Vue/React/...) try { router.pageComponentLoader(router.el, component, componentUrl, options, resolve, reject); } catch (err) { router.allowPageChange = true; throw err; } } else if (url) { // Load using XHR if (router.xhr) { router.xhr.abort(); router.xhr = false; } router.xhrRequest(url, options) .then((pageContent) => { router.forward(router.getPageEl(pageContent), options); }) .catch(() => { router.allowPageChange = true; }); } return router; } function navigate(navigateParams, navigateOptions = {}) { const router = this; if (router.swipeBackActive) return router; let url; let createRoute; let name; let query; let params; let route; if (typeof navigateParams === 'string') { url = navigateParams; } else { url = navigateParams.url; createRoute = navigateParams.route; name = navigateParams.name; query = navigateParams.query; params = navigateParams.params; } if (name) { // find route by name route = router.findRouteByKey('name', name); if (!route) { throw new Error(`Framework7: route with name "${name}" not found`); } url = router.constructRouteUrl(route, { params, query }); if (url) { return router.navigate(url, navigateOptions); } throw new Error(`Framework7: can't construct URL for route with name "${name}"`); } const app = router.app; appRouterCheck(router, 'navigate'); if (url === '#' || url === '') { return router; } let navigateUrl = url.replace('./', ''); if (navigateUrl[0] !== '/' && navigateUrl.indexOf('#') !== 0) { const currentPath = router.currentRoute.parentPath || router.currentRoute.path; navigateUrl = ((currentPath ? `${currentPath}/` : '/') + navigateUrl) .replace('///', '/') .replace('//', '/'); } if (createRoute) { route = Utils.extend(router.parseRouteUrl(navigateUrl), { route: Utils.extend({}, createRoute), }); } else { route = router.findMatchingRoute(navigateUrl); } if (!route) { return router; } if (route.route.redirect) { return redirect.call(router, 'navigate', route, navigateOptions); } const options = {}; if (route.route.options) { Utils.extend(options, route.route.options, navigateOptions); } else { Utils.extend(options, navigateOptions); } options.route = route; if (options && options.context) { route.context = options.context; options.route.context = options.context; } function resolve() { let routerLoaded = false; ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach((modalLoadProp) => { if (route.route[modalLoadProp] && !routerLoaded) { routerLoaded = true; router.modalLoad(modalLoadProp, route, options); } }); if (route.route.keepAlive && route.route.keepAliveData) { router.load({ el: route.route.keepAliveData.pageEl }, options, false); routerLoaded = true; } ('url content component pageName el componentUrl template templateUrl').split(' ').forEach((pageLoadProp) => { if (route.route[pageLoadProp] && !routerLoaded) { routerLoaded = true; router.load({ [pageLoadProp]: route.route[pageLoadProp] }, options, false); } }); if (routerLoaded) return; // Async function asyncResolve(resolveParams, resolveOptions) { router.allowPageChange = false; let resolvedAsModal = false; if (resolveOptions && resolveOptions.context) { if (!route.context) route.context = resolveOptions.context; else route.context = Utils.extend({}, route.context, resolveOptions.context); options.route.context = route.context; } ('popup popover sheet loginScreen actions customModal panel').split(' ').forEach((modalLoadProp) => { if (resolveParams[modalLoadProp]) { resolvedAsModal = true; const modalRoute = Utils.extend({}, route, { route: resolveParams }); router.allowPageChange = true; router.modalLoad(modalLoadProp, modalRoute, Utils.extend(options, resolveOptions)); } }); if (resolvedAsModal) return; router.load(resolveParams, Utils.extend(options, resolveOptions), true); } function asyncReject() { router.allowPageChange = true; } if (route.route.async) { router.allowPageChange = false; route.route.async.call(router, options.route, router.currentRoute, asyncResolve, asyncReject); } } function reject() { router.allowPageChange = true; } if (router.params.masterDetailBreakpoint > 0 && route.route.masterRoute) { // load detail route let preloadMaster = true; let masterLoaded = false; if (router.currentRoute && router.currentRoute.route) { if ( router.currentRoute.route.master && ( router.currentRoute.route === route.route.masterRoute || router.currentRoute.route.path === route.route.masterRoute.path ) ) { preloadMaster = false; } if ( router.currentRoute.route.masterRoute && (router.currentRoute.route.masterRoute === route.route.masterRoute || router.currentRoute.route.masterRoute.path === route.route.masterRoute.path ) ) { preloadMaster = false; masterLoaded = true; } } if (preloadMaster || (masterLoaded && navigateOptions.reloadAll)) { router.navigate(route.route.masterRoute.path, { animate: false, reloadAll: navigateOptions.reloadAll, reloadCurrent: navigateOptions.reloadCurrent, reloadPrevious: navigateOptions.reloadPrevious, pushState: !navigateOptions.initial, history: !navigateOptions.initial, once: { pageAfterIn() { router.navigate(navigateParams, Utils.extend({}, navigateOptions, { animate: false, reloadAll: false, reloadCurrent: false, reloadPrevious: false, history: !navigateOptions.initial, pushState: !navigateOptions.initial, })); }, }, }); return router; } } processRouteQueue.call( router, route, router.currentRoute, () => { if (route.route.modules) { app .loadModules(Array.isArray(route.route.modules) ? route.route.modules : [route.route.modules]) .then(() => { resolve(); }) .catch(() => { reject(); }); } else { resolve(); } }, () => { reject(); }, ); // Return Router return router; } export { refreshPage, forward, load, navigate };