UNPKG

framework7

Version:

Full featured mobile HTML framework for building iOS & Android apps

230 lines (224 loc) 6.84 kB
import $ from '../../shared/dom7.js'; import { extend } from '../../shared/utils.js'; import History from '../../shared/history.js'; import asyncComponent from './async-component.js'; function tabLoad(tabRoute, loadOptions) { if (loadOptions === void 0) { loadOptions = {}; } const router = this; const options = extend({ animate: router.params.animate, browserHistory: true, history: true, parentPageEl: null, preload: false, on: {} }, loadOptions); let currentRoute; let previousRoute; if (options.route) { // Set Route if (!options.preload && options.route !== router.currentRoute) { previousRoute = router.previousRoute; router.currentRoute = options.route; } if (options.preload) { currentRoute = options.route; previousRoute = router.currentRoute; } else { currentRoute = router.currentRoute; if (!previousRoute) previousRoute = router.previousRoute; } // Update Browser History if (router.params.browserHistory && options.browserHistory && !options.reloadPrevious) { History[router.params.browserHistoryTabs](router.view.id, { url: options.route.url }, (router.params.browserHistoryRoot || '') + router.params.browserHistorySeparator + options.route.url); } // Update Router History if (options.history) { router.history[Math.max(router.history.length - 1, 0)] = options.route.url; router.saveHistory(); } } // Show Tab const $parentPageEl = $(options.parentPageEl || router.currentPageEl); let tabEl; if ($parentPageEl.length && $parentPageEl.find(`#${tabRoute.id}`).length) { tabEl = $parentPageEl.find(`#${tabRoute.id}`).eq(0); } else if (router.view.selector) { tabEl = `${router.view.selector} #${tabRoute.id}`; } else { tabEl = `#${tabRoute.id}`; } const tabShowResult = router.app.tab.show({ tabEl, animate: options.animate, tabRoute: options.route }); const { $newTabEl, $oldTabEl, animated, onTabsChanged } = tabShowResult; if ($newTabEl && $newTabEl.parents('.page').length > 0 && options.route) { const tabParentPageData = $newTabEl.parents('.page')[0].f7Page; if (tabParentPageData && options.route) { tabParentPageData.route = options.route; } } // Tab Content Loaded function onTabLoaded(contentEl) { // Remove theme elements router.removeThemeElements($newTabEl); let tabEventTarget = $newTabEl; if (typeof contentEl !== 'string') tabEventTarget = $(contentEl); tabEventTarget.trigger('tab:init tab:mounted', tabRoute); router.emit('tabInit tabMounted', $newTabEl[0], tabRoute); if ($oldTabEl && $oldTabEl.length) { if (animated) { onTabsChanged(() => { router.emit('routeChanged', router.currentRoute, router.previousRoute, router); if (router.params.unloadTabContent) { router.tabRemove($oldTabEl, $newTabEl, tabRoute); } }); } else { router.emit('routeChanged', router.currentRoute, router.previousRoute, router); if (router.params.unloadTabContent) { router.tabRemove($oldTabEl, $newTabEl, tabRoute); } } } } if ($newTabEl[0].f7RouterTabLoaded) { if (!$oldTabEl || !$oldTabEl.length) return router; if (animated) { onTabsChanged(() => { router.emit('routeChanged', router.currentRoute, router.previousRoute, router); }); } else { router.emit('routeChanged', router.currentRoute, router.previousRoute, router); } return router; } // Load Tab Content function loadTab(loadTabParams, loadTabOptions) { // Load Tab Props const { url, content, el, component, componentUrl } = loadTabParams; // Component/Template Callbacks function resolve(contentEl) { router.allowPageChange = true; if (!contentEl) return; if (typeof contentEl === 'string') { $newTabEl.html(contentEl); } else { $newTabEl.html(''); if (contentEl.f7Component) { contentEl.f7Component.mount(componentEl => { $newTabEl.append(componentEl); }); } else { $newTabEl.append(contentEl); } } $newTabEl[0].f7RouterTabLoaded = true; onTabLoaded(contentEl); } function reject() { router.allowPageChange = true; return router; } if (content) { resolve(content); } else if (el) { resolve(el); } else if (component || componentUrl) { // Load from component (F7/Vue/React/...) try { router.tabComponentLoader({ tabEl: $newTabEl[0], component, componentUrl, options: loadTabOptions, resolve, reject }); } catch (err) { router.allowPageChange = true; throw err; } } else if (url) { // Load using XHR if (router.xhrAbortController) { router.xhrAbortController.abort(); router.xhrAbortController = false; } router.xhrRequest(url, loadTabOptions).then(tabContent => { resolve(tabContent); }).catch(() => { router.allowPageChange = true; }); } } let hasContentLoadProp; 'url content component el componentUrl'.split(' ').forEach(tabLoadProp => { if (tabRoute[tabLoadProp]) { hasContentLoadProp = true; loadTab({ [tabLoadProp]: tabRoute[tabLoadProp] }, options); } }); // Async function asyncResolve(resolveParams, resolveOptions) { loadTab(resolveParams, extend(options, resolveOptions)); } function asyncReject() { router.allowPageChange = true; } if (tabRoute.async) { tabRoute.async.call(router, { router, to: currentRoute, from: previousRoute, resolve: asyncResolve, reject: asyncReject, app: router.app }); } else if (tabRoute.asyncComponent) { asyncComponent(router, tabRoute.asyncComponent, asyncResolve, asyncReject); } else if (!hasContentLoadProp) { router.allowPageChange = true; } return router; } function tabRemove($oldTabEl, $newTabEl, tabRoute) { const router = this; let hasTabComponentChild; if ($oldTabEl[0]) { $oldTabEl[0].f7RouterTabLoaded = false; delete $oldTabEl[0].f7RouterTabLoaded; } $oldTabEl.children().each(tabChild => { if (tabChild.f7Component) { hasTabComponentChild = true; $(tabChild).trigger('tab:beforeremove', tabRoute); tabChild.f7Component.destroy(); } }); if (!hasTabComponentChild) { $oldTabEl.trigger('tab:beforeremove', tabRoute); } router.emit('tabBeforeRemove', $oldTabEl[0], $newTabEl[0], tabRoute); router.removeTabContent($oldTabEl[0], tabRoute); } export { tabLoad, tabRemove };