UNPKG

minsky-kit

Version:
306 lines (240 loc) 8.5 kB
/* eslint no-console: "off" */ // imports import EventDispatcher from './EventDispatcher'; import PluginManager from './PluginManager'; import MQManager from './MQManager'; import InstanceManager from './InstanceManager'; import Ticker from './Ticker'; import Config from '../Config'; import VCookieConsent from '../components/VCookieConsent'; // private static const id = 0; // shared tickers const DEBOUNCE_MS = 125; const debouncers = { resize: initDebouncer(onWindowResizeDebounce), delayedResize: initDebouncer(onWindowResizeDelayedDebounce), scroll: initDebouncer(onWindowScrollDebounce), delayedScroll: initDebouncer(onWindowScrollDelayedDebounce), }; // class export default class MainApp extends EventDispatcher { // constructor constructor(args = {}, objectName = 'Minsky App') { args.autoInit = false; args.debug = args.debug || false; // call super constructor super(args, objectName); // set properties this.id = id + 1; // dev mode check if (Config.globals.mode === 'development') document.querySelector('html').classList.add('env-dev'); // logged in state this.loggedIn = document.body.classList.contains('page--loggedIn'); // add app shortcut to global M variable if (!window.M) window.M = {}; if (!window.M.Apps) window.M.Apps = []; M.Apps.push(this); // init instances this.mqManager = new MQManager({ debounce: Config.mqManager.debounce }); this._im = new InstanceManager(); // https://bitbucket.org/Minsky_WebAgency/minsky-kit/src/master/documentation/InstanceManager.md // add eventlisteners // this.mqManager.on('', this.blm.add('onMqHit', onMqHit)); this.mqManager.on('matchChanges', this.blm.add('onMqMatchChanges', onMqMatchChanges)); // add media queries this.mqManager.add(Config.mqManager.queries); // force-check all media queries this.mqManager.check(); // end init if (Config.app.showReadyMessage) MainApp.showReadyMessage(); // cookie consent if ((!this.loggedIn || Config.vCookieConsent.loggedInUsers) && Config.vCookieConsent.active) { this.vCookieConsent = new (args.VCookieConsent || VCookieConsent)(Config.vCookieConsent); // make adjusting vCookieConsent config possible before initializing this.GDPRSetup(); this.vCookieConsent.init(); // add dispatch events to certain events from vCookieConsent so you get those event trigers on all instances from the instance manager this.vCookieConsent.on('onConsent', this.blm.add('onSetConsent', onSetConsent)); this.vCookieConsent.on('onChange', this.blm.add('onConsentChange', onConsentChange)); } // add extra window listeners window.addEventListener('resize', this.blm.add('onWindowResize', onWindowResize)); window.addEventListener('scroll', this.blm.add('onWindowScroll', onWindowScroll)); } // methods reInitialize() { this.mqManager.resetMatches(); this.mqManager.check(); } GDPRSetup() { super.GDPRSetup(); } refresh() { // run plugins plugins.run('refresh', {}, this); this.log('Refresh'); } resize() { // run plugins plugins.run('resize', {}, this); this.log('resize'); } debouncedResize() { // run plugins plugins.run('debouncedResize', {}, this); this.log('debouncedResize'); } delayedDebouncedResize() { // run plugins plugins.run('delayedDebouncedResize', {}, this); this.log('delayedDebouncedResize'); } scroll() { // run plugins plugins.run('scroll', {}, this); this.log('scroll'); } debouncedScroll() { // run plugins plugins.run('debouncedScroll', {}, this); this.log('debouncedScroll'); } delayedDebouncedScroll() { // run plugins plugins.run('delayedDebouncedScroll', {}, this); this.log('delayedDebouncedScroll'); } debug(key, value = null) { value = value !== null ? value : !Config.logger.activate[key]; this.log('Toggle debug for ', key, 'to', value); Config.logger.activate[key] = value; } destroy() { // run plugins plugins.run('destroy', {}, this); // destroy all instances known to the app // libmgr is a singleton and thus can not be destroyed this.instances.destroy('*'); this.instances.destroy(); this.mqManager.destroy(); // call super super.destroy(); } // statics static showReadyMessage() { console.log(...Config.app.readyMessage); } // statics static get plugins() { return plugins; } get plugins() { return plugins; } } // utils function mqBasedInits(definitions = []) { this.log('Perform MQ definition based inits', definitions); definitions.forEach((definition) => { // get method to run if (definition.matches) { const key = `on${definition.name.substring(0, 1).toUpperCase()}${definition.name.substring(1)}`; const method = this[key]; // run plugin and method if (method) { plugins.run(key, {}, this); method.call(this); } } }); } function initDebouncer(listener) { const ticker = new Ticker({ timeout: DEBOUNCE_MS, data: { instances: [], }, }); ticker.on('timeout', listener); return ticker; } function runDebouncer(debouncer, method, e) { debouncer.data.instances.forEach((instance) => { method.call(instance, e); }); debouncer.data.length = 0; debouncer.reset(); } function addInstanceToDebouncer(debouncer, instance) { if (debouncer.data.instances.indexOf(instance) === -1) { debouncer.data.instances.push(instance); } } // event handelrs function onMqMatchChanges(e) { mqBasedInits.call(this, e.data.definitions); } function onWindowScroll(e) { // run method this.scroll(e); // track instances for debounced triggers addInstanceToDebouncer(debouncers.scroll, this); addInstanceToDebouncer(debouncers.delayedScroll, this); // run tickers for debounced listeners debouncers.scroll.start(); debouncers.delayedScroll.start(true); } function onWindowResize(e) { // run method this.resize(e); // track instances for debounced triggers addInstanceToDebouncer(debouncers.resize, this); addInstanceToDebouncer(debouncers.delayedResize, this); // run tickers for debounced listeners debouncers.resize.start(); debouncers.delayedResize.start(true); } // pass method so that obfuscation won't generate bugs function onWindowScrollDebounce() { runDebouncer(this, this.data.instances[0].debouncedScroll); } function onWindowScrollDelayedDebounce() { runDebouncer(this, this.data.instances[0].delayedDebouncedScroll); } function onWindowResizeDebounce() { runDebouncer(this, this.data.instances[0].debouncedResize); } function onWindowResizeDelayedDebounce() { runDebouncer(this, this.data.instances[0].delayedDebouncedResize); } function onSetConsent(e) { this.log('consent change detected, updating all instances with new consent settings'); const { instances } = this._im; for (const k of Object.keys(instances)) { const instanceList = instances[k]; for (const instance of instanceList) { // only perform action on instances with the "setConsent" method if (instance.setConsent) instance.setConsent(e.data); } } } function onConsentChange(e) { this.log('consent change detected, updating all instances with new consent settings'); const { instances } = this._im; for (const k of Object.keys(instances)) { const instanceList = instances[k]; for (const instance of instanceList) { if (instance.consentChange) instance.consentChange(e.data); } } } export function containsOneOfTheseClasses(el, classes) { for (const c of classes) { if (el.classList.contains(c)) return true; } return false; } // add parent to pluginManager let plugins = new PluginManager({ Target: MainApp, });