import { registerModules, activeModules } from "../modules/index.js";
import { Logger } from './logger.js';
import {useEvent} from "./useEvent";
/*import { createTrigger, destroyTrigger, destroyAllTriggers } from './scrollfx/index.js';
createTrigger({
element: 'section',
target: '.fade',
start: 'top 80%',
end: 'bottom 30%',
scrub: true,
onUpdate: (() => {
const progressMap = new WeakMap();
return (el, progress) => {
if (!el) return;
let current = progressMap.get(el) || 0;
current += (progress - current) * 0.1;
progressMap.set(el, current);
el.style.opacity = current;
el.style.transform = `translateY(${30 - 30 * current}px)`;
};
})(),
onEnter: el => el.classList.add('entered'),
onLeave: el => {
el.classList.remove('entered');
el.style.opacity = 0;
el.style.transform = 'translateY(30px)';
}
});*/
/*
let lastScrollY = window.scrollY;
const fadeElements = document.querySelectorAll('.fade-in-on-scroll');
// Observer 1: Einblenden beim Runterscrollen
const fadeInObserver = new IntersectionObserver((entries) => {
const scrollingDown = window.scrollY > lastScrollY;
lastScrollY = window.scrollY;
entries.forEach(entry => {
if (entry.isIntersecting && scrollingDown) {
entry.target.classList.add('visible');
}
});
}, {
threshold: 0.4,
rootMargin: '0px 0px -10% 0px'
});
// Observer 2: Ausblenden beim Hochscrollen
const fadeOutObserver = new IntersectionObserver((entries) => {
const scrollingUp = window.scrollY < lastScrollY;
lastScrollY = window.scrollY;
entries.forEach(entry => {
if (!entry.isIntersecting && scrollingUp) {
entry.target.classList.remove('visible');
}
});
}, {
threshold: 0.5,
rootMargin: '0% 0px 50% 0px' // früher triggern beim Hochscrollen
});
// Alle Elemente mit beiden Observern beobachten
fadeElements.forEach(el => {
fadeInObserver.observe(el);
fadeOutObserver.observe(el);
});
*/
/*
const newContent = '
Neue Seite
'; // dein AJAX-Inhalt z. B.
const container = document.querySelector('main');
document.startViewTransition(() => {
container.innerHTML = newContent;
});*/
import {autoLoadResponsiveVideos} from "../utils/autoLoadResponsiveVideo";
/**
* Initialize DOM elements with data-module attributes
*/
function initDataModuleElements() {
const elements = document.querySelectorAll('[data-module]');
Logger.info(`[DOMInit] Found ${elements.length} elements with data-module attributes`);
elements.forEach(element => {
const moduleName = element.dataset.module;
const moduleData = activeModules.get(moduleName);
if (!moduleData || !moduleData.mod) {
Logger.warn(`[DOMInit] Module "${moduleName}" not found or failed to initialize`);
return;
}
// Parse options from data-options attribute
let options = {};
try {
if (element.dataset.options) {
options = JSON.parse(element.dataset.options);
}
} catch (error) {
Logger.warn(`[DOMInit] Invalid JSON in data-options for ${moduleName}:`, error);
}
// Initialize the module on this element
try {
const moduleInstance = moduleData.mod;
// Check for element-specific init method first, then fallback to general init
if (typeof moduleInstance.initElement === 'function') {
const result = moduleInstance.initElement(element, options);
Logger.info(`[DOMInit] Initialized ${moduleName} on element:`, element);
// Store reference for cleanup
element._moduleInstance = result;
element._moduleName = moduleName;
} else if (typeof moduleInstance.init === 'function') {
const result = moduleInstance.init(element, options);
Logger.info(`[DOMInit] Initialized ${moduleName} on element:`, element);
// Store reference for cleanup
element._moduleInstance = result;
element._moduleName = moduleName;
} else {
Logger.warn(`[DOMInit] Module ${moduleName} has no init method for DOM elements`);
}
} catch (error) {
Logger.error(`[DOMInit] Failed to initialize ${moduleName} on element:`, error, element);
}
});
}
/**
* Initialize SPA Router for seamless navigation
*/
function initSPARouter() {
const spaRouterModule = activeModules.get('spa-router');
if (!spaRouterModule || !spaRouterModule.mod) {
Logger.info('[Init] SPA Router module not available, skipping');
return;
}
try {
// Initialize SPA Router with default configuration
const router = spaRouterModule.mod.init({
containerSelector: 'main',
enableTransitions: true,
transitionDuration: 300
});
// Make functions globally available for re-initialization
window.initAutoFormHandling = initAutoFormHandling;
window.initDataModuleElements = initDataModuleElements;
Logger.info('[Init] SPA Router initialized successfully');
} catch (error) {
Logger.error('[Init] Failed to initialize SPA Router:', error);
}
}
/**
* Auto-initialize all forms with form-handling (opt-out approach)
*/
function initAutoFormHandling() {
// Find all forms except those explicitly opting out and those already enhanced
const forms = document.querySelectorAll('form:not([data-form-handling="false"]):not([data-auto-enhanced])');
Logger.info(`[AutoForms] Found ${forms.length} forms for auto-enhancement`);
if (forms.length === 0) return;
// Check if form-handling module is available
const formHandlingModule = activeModules.get('form-handling');
if (!formHandlingModule || !formHandlingModule.mod) {
Logger.warn('[AutoForms] form-handling module not available, skipping auto-init');
return;
}
forms.forEach(form => {
// Skip forms that already have explicit data-module
if (form.hasAttribute('data-module')) {
Logger.info(`[AutoForms] Skipping form with explicit data-module:`, form);
return;
}
// Skip forms that are already enhanced (double-check)
if (form.hasAttribute('data-auto-enhanced')) {
return;
}
// Parse options from data-form-options attribute
let options = {};
try {
if (form.dataset.formOptions) {
options = JSON.parse(form.dataset.formOptions);
}
} catch (error) {
Logger.warn('[AutoForms] Invalid JSON in data-form-options:', error);
}
// Set default options for auto-enhanced forms
const autoOptions = {
validateOnSubmit: true,
validateOnBlur: false,
validateOnInput: false,
showInlineErrors: true,
ajaxSubmit: true,
enableStateTracking: false, // Conservative default
...options
};
// Initialize form handling
try {
// Use initElement for DOM-specific initialization
const result = formHandlingModule.mod.initElement ?
formHandlingModule.mod.initElement(form, autoOptions) :
formHandlingModule.mod.init(form, autoOptions);
Logger.info('[AutoForms] Auto-enhanced form:', {
id: form.id || 'unnamed',
action: form.action || 'none',
method: form.method || 'get',
elements: form.elements.length
});
// Mark as auto-enhanced
form.setAttribute('data-auto-enhanced', 'true');
form._moduleInstance = result;
form._moduleName = 'form-handling';
} catch (error) {
Logger.error('[AutoForms] Failed to auto-enhance form:', error, form);
}
});
}
/**
* Initialize the application
* Sets up all modules and core functionality
* @async
* @function initApp
* @returns {Promise}
*/
export async function initApp() {
await registerModules();
// Initialize DOM elements after modules are registered
initDataModuleElements();
// Auto-enhance all forms with form-handling
initAutoFormHandling();
// Initialize SPA Router for seamless navigation
initSPARouter();
autoLoadResponsiveVideos();
/*initNoiseToggle({
selector: '.noise-overlay',
toggleKey: 'g', // Taste zum Umschalten
className: 'grainy', // Klasse auf
enableTransition: true // Smooth fade
});
fadeScrollTrigger('.fade');
zoomScrollTrigger('.zoomed');
fixedZoomScrollTrigger('h1');*/
}