| @@ -4,10 +4,6 @@ | |||
| "assetsFolder": "/assets", | |||
| "designFramework": "bootstrap5", | |||
| "frameworks": [ | |||
| { | |||
| "name": "fontawesome_5", | |||
| "type": "cdn" | |||
| }, | |||
| { | |||
| "name": "bootstrap5", | |||
| "type": "local" | |||
| @@ -15,6 +11,14 @@ | |||
| { | |||
| "name": "appConnect", | |||
| "type": "local" | |||
| }, | |||
| { | |||
| "name": "bootstrap_icons", | |||
| "type": "local" | |||
| }, | |||
| { | |||
| "name": "fontawesome_5", | |||
| "type": "local" | |||
| } | |||
| ], | |||
| "projectServerModel": "node", | |||
| @@ -40,7 +40,21 @@ function processEntries(path) { | |||
| function exec(action) { | |||
| return async () => { | |||
| const App = require('../core/app'); | |||
| const app = new App({ params: {}, session: {}, cookies: {}, signedCookies: {}, query: {}, headers: {} }); | |||
| const app = new App({ | |||
| params: {}, | |||
| session: {}, | |||
| cookies: {}, | |||
| signedCookies: {}, | |||
| query: {}, | |||
| headers: {} | |||
| }, { | |||
| headersSent: false, | |||
| set() {}, | |||
| status() { return this; }, | |||
| send() { this.headersSent = true; }, | |||
| json() { this.headersSent = true; }, | |||
| redirect() { this.headersSent = true; } | |||
| }); | |||
| return app.define(action, true); | |||
| } | |||
| } | |||
| @@ -1,21 +1,49 @@ | |||
| jQuery(document).ready(function($) { | |||
| $(window).on('popstate pushstate', _update); | |||
| _update(); | |||
| function _update() { | |||
| var url = window.location.href; | |||
| $('a.nav-link:not([data-toggle]), a.dropdown-item').map(function() { | |||
| $(this).toggleClass('active', this.href == url || this.href == url.split("?")[0].split("#")[0]); | |||
| }); | |||
| $('a.dropdown-item.active').map(function() { | |||
| $(this).closest('.nav-item.dropdown').find('.dropdown-toggle').toggleClass('active'); | |||
| }); | |||
| } | |||
| }); | |||
| (function() { | |||
| // ignore if routing is enabled | |||
| if (dmx.routing) return; | |||
| dmx.config.mapping['a.nav-link:not([href^="#"])'] = 'nav-link'; | |||
| dmx.Component('nav-link', { | |||
| init (node) { | |||
| window.addEventListener("popstate", this._stateHandler); | |||
| window.addEventListener("pushstate", this._stateHandler); | |||
| window.addEventListener("replacestate", this._stateHandler); | |||
| window.addEventListener('hashchange', this._stateHandler); | |||
| this._stateHandler(); | |||
| }, | |||
| destroy () { | |||
| window.removeEventListener("popstate", this._stateHandler); | |||
| window.removeEventListener("pushstate", this._stateHandler); | |||
| window.removeEventListener("replacestate", this._stateHandler); | |||
| window.removeEventListener('hashchange', this._stateHandler); | |||
| }, | |||
| _stateHandler () { | |||
| const node = this.$node; | |||
| const active = node.href == window.location.href || node.href == window.location.href.split("?")[0].split("#")[0]; | |||
| node.classList.toggle('active', active); | |||
| if (node.classList.contains('dropdown-item')) { | |||
| const items = node.parentNode.querySelectorAll('.dropdown-item'); | |||
| node.classList.remove('active'); | |||
| for (let i = 0; i < items.length; i++) { | |||
| const match = items[i].href == window.location.href || items[i].href == window.location.href.split("?")[0].split("#")[0]; | |||
| if (match) { | |||
| items[i].classList.add('active'); | |||
| node.classList.add('active'); | |||
| } else { | |||
| items[i].classList.remove('active'); | |||
| } | |||
| } | |||
| } | |||
| }, | |||
| }); | |||
| })() | |||
| @@ -1,40 +1,49 @@ | |||
| (function() { | |||
| // Call init when DOM is ready | |||
| if (document.readyState === 'loading') { // Loading hasn't finished yet | |||
| document.addEventListener('DOMContentLoaded', _init, { once: true }); | |||
| } else { // DOMContentLoaded has already fired | |||
| _init(); | |||
| } | |||
| function _init() { | |||
| // Listen to url changes | |||
| window.addEventListener('popstate', _update); | |||
| window.addEventListener('pushstate', _update); | |||
| // Listen to DOM changes and call update when nodes are added | |||
| new MutationObserver(_update).observe(document.body, { subtree: true, childList: true }); | |||
| // Initial update | |||
| _update(); | |||
| } | |||
| function _update() { | |||
| var url = window.location.href; | |||
| document.querySelectorAll('a.nav-link:not([data-bs-toggle]), a.dropdown-item').forEach(function(elem) { | |||
| elem.classList.toggle('active', elem.href == url || elem.href == url.split("?")[0].split("#")[0]); | |||
| }); | |||
| document.querySelectorAll('a.dropdown-item.active').forEach(function(elem) { | |||
| var theItem = elem.closest('.nav-item.dropdown'); | |||
| if (theItem) { | |||
| var theToggle = theItem.querySelector('.dropdown-toggle'); | |||
| if (theToggle) { | |||
| theToggle.classList.toggle('active'); | |||
| // ignore if routing is enabled | |||
| if (dmx.routing) return; | |||
| dmx.config.mapping['a.nav-link:not([href^="#"])'] = 'nav-link'; | |||
| dmx.Component('nav-link', { | |||
| init (node) { | |||
| window.addEventListener("popstate", this._stateHandler); | |||
| window.addEventListener("pushstate", this._stateHandler); | |||
| window.addEventListener("replacestate", this._stateHandler); | |||
| window.addEventListener('hashchange', this._stateHandler); | |||
| this._stateHandler(); | |||
| }, | |||
| destroy () { | |||
| window.removeEventListener("popstate", this._stateHandler); | |||
| window.removeEventListener("pushstate", this._stateHandler); | |||
| window.removeEventListener("replacestate", this._stateHandler); | |||
| window.removeEventListener('hashchange', this._stateHandler); | |||
| }, | |||
| _stateHandler () { | |||
| const node = this.$node; | |||
| const active = node.href == window.location.href || node.href == window.location.href.split("?")[0].split("#")[0]; | |||
| node.classList.toggle('active', active); | |||
| if (node.classList.contains('dropdown-item')) { | |||
| const items = node.parentNode.querySelectorAll('.dropdown-item'); | |||
| node.classList.remove('active'); | |||
| for (let i = 0; i < items.length; i++) { | |||
| const match = items[i].href == window.location.href || items[i].href == window.location.href.split("?")[0].split("#")[0]; | |||
| if (match) { | |||
| items[i].classList.add('active'); | |||
| node.classList.add('active'); | |||
| } else { | |||
| items[i].classList.remove('active'); | |||
| } | |||
| } | |||
| } | |||
| }); | |||
| } | |||
| }, | |||
| }); | |||
| })() | |||
| @@ -6,5 +6,9 @@ | |||
| "dspec.ejs": { | |||
| "layoutPage": "smain", | |||
| "description": "" | |||
| }, | |||
| "test.ejs": { | |||
| "layoutPage": "newmain", | |||
| "description": "" | |||
| } | |||
| } | |||