class Page { /** * @param {string} property * @return {*} */ static _get(property) { return this.hasOwnProperty(property) ? this[property] : null; } /** * @param {string} property * @param {*} value */ static _set(property, value) { this[property] = value; } /** * @return {Page.Meta} */ static get meta() { return this._get('_meta'); } /** * Get most forward context for loaders, messages, etc. * @return {jQuery} */ static getContext() { if (Core.UI.Sidebar && Core.UI.Sidebar.isOpen()) { return Core.UI.Sidebar.getElement(); } let $activeModal = $('.ui.modals.dimmer:not(.fade.out)').children('.ui.front.modal, .ui.animating.in.modal'); if ($activeModal.exists()) { return $activeModal; } return $('body > .pusher'); } /** * Get page content segment. * @return {jQuery} */ static getPageSegment() { let $page = $('body > .pusher > .ui.basic.segment > .ui.page.segment'); if ($page.exists()) { return $page; } return $('body > .pusher > .ui.page.segment'); } /** * Set page HTML and bind it. * @param {string} html * @param {object} object */ static setPageContents(html, object) { this.getPageSegment().html(html); Core.UI.Bind.get( this.getPageSegment(), { instance: object } ); } /** * Open page. * @param {Page.Structure} pageStructure * @param {Object} pageObject * @param {Object} parameters */ static open(pageStructure, pageObject, parameters) { document.title = pageStructure.title; this.activePage = pageObject; Core.UI.MainMenu.uri = pageStructure.uri; Core.UI.MainMenu.setMenu(pageStructure); Core.UI.MainMenu.setTitle(pageStructure.title); this.getPageSegment().html(pageStructure.page_html); if (typeof parameters === 'undefined') { parameters = Page.getParameters(); } Page.setURL(pageStructure.title, parameters); Core.UI.Bind.get(this.getPageSegment()); } /** * Initialize page. */ static init() { Page.Meta.read(); if (Core.UI.MainMenu.getElement().parent().hasClass('sticky')) { // @todo: this is causing the page to jump when you scroll to the very bottom. // Core.UI.MainMenu.getElement().parent().sticky({ // observeChanges: true, // pushing: true, // onStick: function () { // Core.UI.MainMenu.outerHeight = $(this).outerHeight(true); // $('body > .pusher > .ui.basic.segment').css('padding-top', Core.UI.MainMenu.outerHeight + 'px'); // }, // onUnstick: function () { // $('body > .pusher > .ui.basic.segment').css('padding-top', '0'); // } // }); Core.UI.MainMenu.outerHeight = Core.UI.MainMenu.getElement().parent().outerHeight(true); } let page = eval(Page.getParameters().page); page.open(Page.getParameters({}, true)); } /** * Get page parameters * @param {Object} parameters * @param {boolean} includeExisting * * @return {Object} */ static getParameters(parameters, includeExisting) { if (!parameters) { parameters = {}; } if (includeExisting !== false) { window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi, function (m, key, value) { if (!parameters[key]) { parameters[key] = decodeURIComponent(value); } }); } if (Page.activePage) { parameters.page = Page.activePage.getClassName(); } else if (!parameters.page) { parameters.page = 'Page.Home'; } return parameters; } /** * Set URL parameter. * @param {string} name * @param {string} value * @param {string} title */ static setParameter(name, value, title) { let parameters = Page.getParameters(); if (value === undefined || value === null) { delete parameters[name]; } else { parameters[name] = value; } Page.setURL(title || document.title, parameters); } /** * Get form on page. Optionally, pass the specified form name to get that one. * * @param {string} formName * * @return {jQuery} */ static getForm(formName) { if (formName) { return Page.getContext().find(`.form.${formName}`); } return Page.getContext().find('.form').first(); } /** * Set URL parameters. * @param {string} title * @param {object} parameters */ static setURL(title, parameters) { if (this.lastHistoryState != parameters) { window.history.pushState( { parameters: parameters }, title, '?' + $.param(parameters) ); this.lastHistoryState = parameters; } Core.UI.MainMenu.setTitle(title); Core.UI.MainMenu.refresh(); } } window.onpopstate = function (e) { if (e.state) { Page.getContext().fade('show'); let params = e.state.parameters; let query = '/?' + Object.keys(params).map(key => key + '=' + params[key]).join('&'); window.open(query, '_self'); } }; Page.keys = {}; window.onbeforeunload = function () { Page.getContext().fade('show'); }; $(document).ready(function () { Page.init(); Core.UI.Notifications.poll(); Mqtt.connect(); setInterval( () => { $('time.localtime').each(function () { let $time = $(this); let date = new Date().toLocaleTimeString( 'en-US', { timeZone: $time.data('timezone') } ); $time.html(date); }); $('time.timeago').timeago(); }, 1000 ); });