UNPKG

framework7

Version:

Full featured mobile HTML framework for building iOS & Android apps

349 lines (328 loc) 9.42 kB
/* eslint-disable no-underscore-dangle */ import { getWindow, getDocument } from 'ssr-window'; import { extend, nextFrame } from '../../shared/utils.js'; import { getDevice } from '../../shared/get-device.js'; import { getSupport } from '../../shared/get-support.js'; import Framework7Class from '../../shared/class.js'; import EventsClass from '../../shared/events-class.js'; import ConstructorMethods from '../../shared/constructor-methods.js'; import ModalMethods from '../../shared/modal-methods.js'; import $ from '../../shared/dom7.js'; import loadModule from './load-module.js'; import $jsx from '../../shared/$jsx.js'; class Framework7 extends Framework7Class { constructor(params) { if (params === void 0) { params = {}; } super(params); // eslint-disable-next-line if (Framework7.instance && typeof window !== 'undefined') { throw new Error("Framework7 is already initialized and can't be initialized more than once"); } const device = getDevice({ userAgent: params.userAgent || undefined }); const support = getSupport(); const passedParams = extend({}, params); // App Instance const app = this; app.device = device; app.support = support; const w = getWindow(); const d = getDocument(); Framework7.instance = app; // Default const defaults = { el: 'body', theme: 'auto', routes: [], name: 'Framework7', lazyModulesPath: null, initOnDeviceReady: true, init: true, darkMode: undefined, iosTranslucentBars: true, iosTranslucentModals: true, component: undefined, componentUrl: undefined, userAgent: null, url: null, colors: { primary: '#007aff', red: '#ff3b30', green: '#4cd964', blue: '#2196f3', pink: '#ff2d55', yellow: '#ffcc00', orange: '#ff9500', purple: '#9c27b0', deeppurple: '#673ab7', lightblue: '#5ac8fa', teal: '#009688', lime: '#cddc39', deeporange: '#ff6b22', white: '#ffffff', black: '#000000' } }; // Extend defaults with modules params app.useModulesParams(defaults); // Extend defaults with passed params app.params = extend(defaults, params); extend(app, { // App Name name: app.params.name, // Routes routes: app.params.routes, // Theme theme: function getTheme() { if (app.params.theme === 'auto') { if (device.ios) return 'ios'; return 'md'; } return app.params.theme; }(), // Initially passed parameters passedParams, online: w.navigator.onLine, colors: app.params.colors, darkMode: app.params.darkMode }); if (params.store) app.params.store = params.store; // Save Root if (app.$el && app.$el[0]) { app.$el[0].f7 = app; } // Install Modules app.useModules(); // Init Store app.initStore(); // Init if (app.params.init) { if (device.cordova && app.params.initOnDeviceReady) { $(d).on('deviceready', () => { app.init(); }); } else { app.init(); } } // Return app instance return app; } setColorTheme(color) { if (!color) return; const app = this; app.colors.primary = color; app.setColors(); } setColors() { const app = this; const document = getDocument(); if (!app.colorsStyleEl) { app.colorsStyleEl = document.createElement('style'); document.head.prepend(app.colorsStyleEl); } app.colorsStyleEl.textContent = app.utils.colorThemeCSSStyles(app.colors); } mount(rootEl) { const app = this; const window = getWindow(); const document = getDocument(); const $rootEl = $(rootEl || app.params.el).eq(0); app.$el = $rootEl; if (app.$el && app.$el[0]) { app.el = app.$el[0]; app.el.f7 = app; app.rtl = $rootEl.css('direction') === 'rtl'; } // Auto Dark Mode const DARK = '(prefers-color-scheme: dark)'; const LIGHT = '(prefers-color-scheme: light)'; app.mq = {}; if (window.matchMedia) { app.mq.dark = window.matchMedia(DARK); app.mq.light = window.matchMedia(LIGHT); } app.colorSchemeListener = function colorSchemeListener(_ref) { let { matches, media } = _ref; if (!matches) { return; } const html = document.querySelector('html'); if (media === DARK) { html.classList.add('dark'); app.darkMode = true; app.emit('darkModeChange', true); } else if (media === LIGHT) { html.classList.remove('dark'); app.darkMode = false; app.emit('darkModeChange', false); } }; app.emit('mount'); } initStore() { const app = this; if (typeof app.params.store !== 'undefined' && app.params.store.__store) { app.store = app.params.store; } else { app.store = app.createStore(app.params.store); } } enableAutoDarkMode() { const window = getWindow(); const document = getDocument(); if (!window.matchMedia) return; const app = this; const html = document.querySelector('html'); if (app.mq.dark && app.mq.light) { app.mq.dark.addEventListener('change', app.colorSchemeListener); app.mq.light.addEventListener('change', app.colorSchemeListener); } if (app.mq.dark && app.mq.dark.matches) { html.classList.add('dark'); app.darkMode = true; app.emit('darkModeChange', true); } else if (app.mq.light && app.mq.light.matches) { html.classList.remove('dark'); app.darkMode = false; app.emit('darkModeChange', false); } } disableAutoDarkMode() { const window = getWindow(); if (!window.matchMedia) return; const app = this; if (app.mq.dark) app.mq.dark.removeEventListener('change', app.colorSchemeListener); if (app.mq.light) app.mq.light.removeEventListener('change', app.colorSchemeListener); } setDarkMode(mode) { const app = this; if (mode === 'auto') { app.enableAutoDarkMode(); } else { app.disableAutoDarkMode(); $('html')[mode ? 'addClass' : 'removeClass']('dark'); app.darkMode = mode; } } initAppComponent(callback) { const app = this; app.router.componentLoader(app.params.component, app.params.componentUrl, { componentOptions: { el: app.$el[0] } }, el => { app.$el = $(el); app.$el[0].f7 = app; app.$elComponent = el.f7Component; app.el = app.$el[0]; if (callback) callback(); }, () => {}); } init(rootEl) { const app = this; app.setColors(); app.mount(rootEl); const init = () => { if (app.initialized) return; app.$el.addClass('framework7-initializing'); // RTL attr if (app.rtl) { $('html').attr('dir', 'rtl'); } // Auto Dark Mode if (typeof app.params.darkMode === 'undefined') { app.darkMode = $('html').hasClass('dark'); } else { app.setDarkMode(app.params.darkMode); } // Watch for online/offline state const window = getWindow(); window.addEventListener('offline', () => { app.online = false; app.emit('offline'); app.emit('connection', false); }); window.addEventListener('online', () => { app.online = true; app.emit('online'); app.emit('connection', true); }); // Root class app.$el.addClass('framework7-root'); // Theme class $('html').removeClass('ios md').addClass(app.theme); // iOS Translucent if (app.params.iosTranslucentBars && app.theme === 'ios') { $('html').addClass('ios-translucent-bars'); } if (app.params.iosTranslucentModals && app.theme === 'ios') { $('html').addClass('ios-translucent-modals'); } // Init class nextFrame(() => { app.$el.removeClass('framework7-initializing'); }); // Emit, init other modules app.initialized = true; app.emit('init'); }; if (app.params.component || app.params.componentUrl) { app.initAppComponent(() => { init(); }); } else { init(); } return app; } // eslint-disable-next-line loadModule() { return Framework7.loadModule(...arguments); } // eslint-disable-next-line loadModules() { return Framework7.loadModules(...arguments); } getVnodeHooks(hook, id) { const app = this; if (!app.vnodeHooks || !app.vnodeHooks[hook]) return []; return app.vnodeHooks[hook][id] || []; } // eslint-disable-next-line get $() { return $; } static get Dom7() { return $; } static get $() { return $; } static get device() { return getDevice(); } static get support() { return getSupport(); } static get Class() { return Framework7Class; } static get Events() { return EventsClass; } } Framework7.$jsx = $jsx; Framework7.ModalMethods = ModalMethods; Framework7.ConstructorMethods = ConstructorMethods; Framework7.loadModule = loadModule; Framework7.loadModules = function loadModules(modules) { return Promise.all(modules.map(module => Framework7.loadModule(module))); }; export default Framework7;