UNPKG

framework7

Version:

Full featured mobile HTML framework for building iOS & Android apps

223 lines (215 loc) 6.69 kB
import { extend, nextTick } from '../../shared/utils.js'; import History from '../../shared/history.js'; import asyncComponent from './async-component.js'; function modalLoad(modalType, route, loadOptions, direction) { if (loadOptions === void 0) { loadOptions = {}; } const router = this; const app = router.app; const isPanel = modalType === 'panel'; const modalOrPanel = isPanel ? 'panel' : 'modal'; const options = extend({ animate: router.params.animate, browserHistory: true, history: true, on: {}, once: {} }, loadOptions); const modalParams = extend({}, route.route[modalType]); const modalRoute = route.route; const routeCallback = (modal, name) => { const { on, once } = options; let callback; if (name === 'open') { callback = on.modalOpen || once.modalOpen || on.panelOpen || once.panelOpen; } if (name === 'close') { callback = on.modalClose || once.modalClose || on.panelClose || once.panelClose; } if (name === 'closed') { callback = on.modalClosed || once.modalClosed || on.panelClosed || once.panelClosed; } if (callback) callback(modal); }; function onModalLoaded() { // Create Modal const modal = app[modalType].create(modalParams); modalRoute.modalInstance = modal; const hasEl = modal.el; function closeOnSwipeBack() { modal.close(); } modal.on(`${modalOrPanel}Open`, () => { if (!hasEl) { // Remove theme elements router.removeThemeElements(modal.el); // Emit events modal.$el.trigger(`${modalType.toLowerCase()}:init ${modalType.toLowerCase()}:mounted`, route, modal); router.emit(`${!isPanel ? 'modalInit' : ''} ${modalType}Init ${modalType}Mounted`, modal.el, route, modal); } router.once('swipeBackMove', closeOnSwipeBack); routeCallback(modal, 'open'); }); modal.on(`${modalOrPanel}Close`, () => { router.off('swipeBackMove', closeOnSwipeBack); if (!modal.closeByRouter) { router.back(); } routeCallback(modal, 'close'); }); modal.on(`${modalOrPanel}Closed`, () => { modal.$el.trigger(`${modalType.toLowerCase()}:beforeremove`, route, modal); modal.emit(`${!isPanel ? 'modalBeforeRemove ' : ''}${modalType}BeforeRemove`, modal.el, route, modal); const modalComponent = modal.el.f7Component; routeCallback(modal, 'closed'); if (modalComponent) { modalComponent.destroy(); } nextTick(() => { if (modalComponent || modalParams.component || modalParams.asyncComponent || modalParams.async) { router.removeModal(modal.el); } modal.destroy(); delete modal.route; delete modalRoute.modalInstance; }); }); if (options.route) { // Update Browser History if (router.params.browserHistory && options.browserHistory) { History.push(router.view.id, { url: options.route.url, modal: modalType }, (router.params.browserHistoryRoot || '') + router.params.browserHistorySeparator + options.route.url); } // Set Route if (options.route !== router.currentRoute) { modal.route = extend(options.route, { modal }); router.currentRoute = modal.route; } // Update Router History if (options.history && !options.reloadCurrent) { router.history.push(options.route.url); router.saveHistory(); } } if (hasEl) { // Remove theme elements router.removeThemeElements(modal.el); // Emit events modal.$el.trigger(`${modalType.toLowerCase()}:init ${modalType.toLowerCase()}:mounted`, route, modal); router.emit(`${modalOrPanel}Init ${modalType}Init ${modalType}Mounted`, modal.el, route, modal); } // Open modal.open(options.animate === false || options.animate === true ? options.animate : undefined); } // Load Modal Content function loadModal(loadModalParams, loadModalOptions) { // Load Modal Props const { url, content, component, componentUrl } = loadModalParams; // Component/Template Callbacks function resolve(contentEl) { if (contentEl) { if (typeof contentEl === 'string') { modalParams.content = contentEl; } else if (contentEl.f7Component) { contentEl.f7Component.mount(componentEl => { modalParams.el = componentEl; app.$el.append(componentEl); }); } else { modalParams.el = contentEl; } onModalLoaded(); } } function reject() { router.allowPageChange = true; return router; } if (content) { resolve(content); } else if (component || componentUrl) { // Load from component (F7/Vue/React/...) try { router.modalComponentLoader({ rootEl: app.el, component, componentUrl, options: loadModalOptions, 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, loadModalOptions).then(modalContent => { modalParams.content = modalContent; onModalLoaded(); }).catch(() => { router.allowPageChange = true; }); } else { onModalLoaded(); } } let foundLoadProp; 'url content component el componentUrl template'.split(' ').forEach(modalLoadProp => { if (modalParams[modalLoadProp] && !foundLoadProp) { foundLoadProp = true; loadModal({ [modalLoadProp]: modalParams[modalLoadProp] }, options); } }); if (!foundLoadProp && modalType === 'actions') { onModalLoaded(); } // Async function asyncResolve(resolveParams, resolveOptions) { loadModal(resolveParams, extend(options, resolveOptions)); } function asyncReject() { router.allowPageChange = true; } if (modalParams.async) { modalParams.async.call(router, { router, to: options.route, from: router.currentRoute, resolve: asyncResolve, reject: asyncReject, direction, app }); } if (modalParams.asyncComponent) { asyncComponent(router, modalParams.asyncComponent, asyncResolve, asyncReject); } return router; } function modalRemove(modal) { extend(modal, { closeByRouter: true }); modal.close(); } export { modalLoad, modalRemove };