| @@ -4,10 +4,6 @@ | |||||
| "assetsFolder": "/assets", | "assetsFolder": "/assets", | ||||
| "designFramework": "bootstrap5", | "designFramework": "bootstrap5", | ||||
| "frameworks": [ | "frameworks": [ | ||||
| { | |||||
| "name": "fontawesome_5", | |||||
| "type": "cdn" | |||||
| }, | |||||
| { | { | ||||
| "name": "bootstrap5", | "name": "bootstrap5", | ||||
| "type": "local" | "type": "local" | ||||
| @@ -15,6 +11,14 @@ | |||||
| { | { | ||||
| "name": "appConnect", | "name": "appConnect", | ||||
| "type": "local" | "type": "local" | ||||
| }, | |||||
| { | |||||
| "name": "bootstrap_icons", | |||||
| "type": "local" | |||||
| }, | |||||
| { | |||||
| "name": "fontawesome_5", | |||||
| "type": "local" | |||||
| } | } | ||||
| ], | ], | ||||
| "projectServerModel": "node", | "projectServerModel": "node", | ||||
| @@ -40,7 +40,21 @@ function processEntries(path) { | |||||
| function exec(action) { | function exec(action) { | ||||
| return async () => { | return async () => { | ||||
| const App = require('../core/app'); | 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); | 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() { | (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": { | "dspec.ejs": { | ||||
| "layoutPage": "smain", | "layoutPage": "smain", | ||||
| "description": "" | "description": "" | ||||
| }, | |||||
| "test.ejs": { | |||||
| "layoutPage": "newmain", | |||||
| "description": "" | |||||
| } | } | ||||
| } | } | ||||