Update from Git Manager GUI
This commit is contained in:
1
Minecraft-Modern-Theme/js/assistant-widget.js
Normal file
1
Minecraft-Modern-Theme/js/assistant-widget.js
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// header-scroll.js – ergänzt um Header-Suche Toggle
|
||||
// header-scroll.js – kompakter Header beim Scrollen + Suche Toggle
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// ── Customizer Guard ──────────────────────────────────────────────────
|
||||
@@ -9,12 +9,79 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
return;
|
||||
}
|
||||
|
||||
// ── Scroll-Effekt ─────────────────────────────────────────────────────
|
||||
// ── Scroll-Effekt + kompakter Header ─────────────────────────────────
|
||||
const header = document.querySelector('.site-header');
|
||||
const brandingRow = header ? header.querySelector('.header-row-branding') : null;
|
||||
|
||||
if (header) {
|
||||
window.addEventListener('scroll', function () {
|
||||
header.classList.toggle('scrolled', window.scrollY > 50);
|
||||
}, { passive: true });
|
||||
let lastScrollY = Math.max(window.scrollY, 0);
|
||||
let directionAnchorY = lastScrollY;
|
||||
let isCompact = header.classList.contains('header-compact');
|
||||
let lastStateChangeAt = 0;
|
||||
let ticking = false;
|
||||
|
||||
const compactEnterThreshold = 110;
|
||||
const compactExitThreshold = 24;
|
||||
const directionThreshold = 10;
|
||||
const expandDelta = 120;
|
||||
const stateChangeCooldown = 260;
|
||||
|
||||
const setCompactState = function (nextCompact, now) {
|
||||
if (isCompact === nextCompact) {
|
||||
return;
|
||||
}
|
||||
|
||||
isCompact = nextCompact;
|
||||
lastStateChangeAt = now;
|
||||
directionAnchorY = Math.max(window.scrollY, 0);
|
||||
|
||||
header.classList.toggle('header-compact', nextCompact);
|
||||
|
||||
if (brandingRow) {
|
||||
brandingRow.classList.toggle('branding-hidden', nextCompact);
|
||||
}
|
||||
};
|
||||
|
||||
const updateHeaderState = function () {
|
||||
ticking = false;
|
||||
|
||||
const now = window.performance && typeof window.performance.now === 'function'
|
||||
? window.performance.now()
|
||||
: Date.now();
|
||||
const currentScrollY = Math.max(window.scrollY, 0);
|
||||
const delta = currentScrollY - lastScrollY;
|
||||
const canChangeState = now - lastStateChangeAt >= stateChangeCooldown;
|
||||
|
||||
header.classList.toggle('scrolled', currentScrollY > 50);
|
||||
|
||||
if (currentScrollY <= compactExitThreshold) {
|
||||
setCompactState(false, now);
|
||||
} else if (canChangeState && delta > directionThreshold) {
|
||||
directionAnchorY = currentScrollY;
|
||||
|
||||
if (currentScrollY > compactEnterThreshold) {
|
||||
setCompactState(true, now);
|
||||
}
|
||||
} else if (canChangeState && delta < -directionThreshold) {
|
||||
if (directionAnchorY - currentScrollY >= expandDelta) {
|
||||
setCompactState(false, now);
|
||||
}
|
||||
}
|
||||
|
||||
lastScrollY = currentScrollY;
|
||||
};
|
||||
|
||||
const onScroll = function () {
|
||||
if (ticking) {
|
||||
return;
|
||||
}
|
||||
|
||||
ticking = true;
|
||||
window.requestAnimationFrame(updateHeaderState);
|
||||
};
|
||||
|
||||
updateHeaderState();
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
}
|
||||
|
||||
// ── Suche Toggle ──────────────────────────────────────────────────────
|
||||
|
||||
63
Minecraft-Modern-Theme/js/minecraft-avatar-skinview.js
Normal file
63
Minecraft-Modern-Theme/js/minecraft-avatar-skinview.js
Normal file
@@ -0,0 +1,63 @@
|
||||
// Lädt skinview3d von CDN
|
||||
(function(){
|
||||
if(document.getElementById('skinview3d-cdn')) return;
|
||||
var s = document.createElement('script');
|
||||
s.id = 'skinview3d-cdn';
|
||||
s.src = 'https://unpkg.com/skinview3d@4.1.1/bundles/skinview3d.min.js';
|
||||
s.onload = function() {
|
||||
window.skinview3dReady = true;
|
||||
};
|
||||
document.head.appendChild(s);
|
||||
})();
|
||||
|
||||
window.showMinecraftSkinModal = function(uuid) {
|
||||
if(document.getElementById('minecraft-skin-modal')) return;
|
||||
var modal = document.createElement('div');
|
||||
modal.id = 'minecraft-skin-modal';
|
||||
modal.innerHTML = `
|
||||
<div class="sv3d-modal-bg"></div>
|
||||
<div class="sv3d-modal-content">
|
||||
<button class="sv3d-modal-close" aria-label="Schließen">×</button>
|
||||
<div id="sv3d-canvas-wrap" style="width:320px;height:320px;"></div>
|
||||
</div>
|
||||
`;
|
||||
document.body.appendChild(modal);
|
||||
document.querySelector('.sv3d-modal-close').onclick = function(){ modal.remove(); };
|
||||
document.querySelector('.sv3d-modal-bg').onclick = function(){ modal.remove(); };
|
||||
|
||||
function renderSkin() {
|
||||
var skinUrl = `https://crafatar.com/skins/${uuid}`;
|
||||
var canvas = document.createElement('canvas');
|
||||
canvas.width = 320; canvas.height = 320;
|
||||
document.getElementById('sv3d-canvas-wrap').appendChild(canvas);
|
||||
var viewer = new skinview3d.SkinViewer({
|
||||
canvas: canvas,
|
||||
width: 320,
|
||||
height: 320,
|
||||
skin: skinUrl
|
||||
});
|
||||
viewer.controls.enableZoom = false;
|
||||
viewer.animation = new skinview3d.WalkingAnimation();
|
||||
viewer.animation.speed = 1.2;
|
||||
viewer.animation.play();
|
||||
}
|
||||
if(window.skinview3dReady) renderSkin();
|
||||
else {
|
||||
var check = setInterval(function(){
|
||||
if(window.skinview3dReady) { clearInterval(check); renderSkin(); }
|
||||
}, 100);
|
||||
}
|
||||
};
|
||||
|
||||
// Avatar-Widget-Click-Handler
|
||||
window.addEventListener('DOMContentLoaded', function(){
|
||||
var widget = document.getElementById('minecraft-avatar-widget');
|
||||
if(widget) {
|
||||
widget.style.cursor = 'pointer';
|
||||
widget.title = 'Klicke für 3D Skin-Ansicht';
|
||||
widget.onclick = function(){
|
||||
var uuid = widget.getAttribute('data-uuid');
|
||||
if(uuid) window.showMinecraftSkinModal(uuid);
|
||||
};
|
||||
}
|
||||
});
|
||||
@@ -1,29 +1,135 @@
|
||||
( function () {
|
||||
// FIX: Null-Check – Script bricht auf Login-Seite & Seiten ohne Nav nicht mehr ab
|
||||
const siteNavigation = document.getElementById( 'site-navigation' );
|
||||
if ( ! siteNavigation ) {
|
||||
return;
|
||||
'use strict';
|
||||
|
||||
var isSidebarLayout = document.querySelector( '.site-header--sidebar' ) !== null;
|
||||
|
||||
if ( isSidebarLayout ) {
|
||||
|
||||
// --- Panel öffnen / schließen ---
|
||||
var panel = document.getElementById( 'header-sidebar' );
|
||||
var overlay = document.getElementById( 'sidebar-overlay' );
|
||||
var openBtn = document.querySelector( '.sidebar-menu-toggle' );
|
||||
var closeBtn = document.querySelector( '.sidebar-menu-close' );
|
||||
|
||||
function openPanel() {
|
||||
if ( ! panel ) return;
|
||||
panel.classList.add( 'is-open' );
|
||||
panel.setAttribute( 'aria-hidden', 'false' );
|
||||
if ( openBtn ) openBtn.setAttribute( 'aria-expanded', 'true' );
|
||||
if ( overlay ) overlay.classList.add( 'is-visible' );
|
||||
document.body.classList.add( 'sidebar-nav-open' );
|
||||
}
|
||||
|
||||
const menuToggle = siteNavigation.querySelector( '.menu-toggle' );
|
||||
if ( ! menuToggle ) {
|
||||
return;
|
||||
function closePanel() {
|
||||
if ( ! panel ) return;
|
||||
panel.classList.remove( 'is-open' );
|
||||
panel.setAttribute( 'aria-hidden', 'true' );
|
||||
if ( openBtn ) openBtn.setAttribute( 'aria-expanded', 'false' );
|
||||
if ( overlay ) overlay.classList.remove( 'is-visible' );
|
||||
document.body.classList.remove( 'sidebar-nav-open' );
|
||||
}
|
||||
|
||||
// Toggle Klassen hinzufügen (Menü öffnen/schließen)
|
||||
menuToggle.addEventListener( 'click', function() {
|
||||
siteNavigation.classList.toggle( 'toggled' );
|
||||
|
||||
if ( menuToggle.getAttribute( 'aria-expanded' ) === 'true' ) {
|
||||
menuToggle.setAttribute( 'aria-expanded', 'false' );
|
||||
menuToggle.innerHTML = '<i class="fas fa-bars"></i>';
|
||||
} else {
|
||||
menuToggle.setAttribute( 'aria-expanded', 'true' );
|
||||
menuToggle.innerHTML = '<i class="fas fa-times"></i>';
|
||||
}
|
||||
if ( openBtn ) openBtn.addEventListener( 'click', openPanel );
|
||||
if ( closeBtn ) closeBtn.addEventListener( 'click', closePanel );
|
||||
if ( overlay ) overlay.addEventListener( 'click', closePanel );
|
||||
document.addEventListener( 'keydown', function ( e ) {
|
||||
if ( e.key === 'Escape' ) closePanel();
|
||||
} );
|
||||
|
||||
// FIX: Menü bei Klick außerhalb schließen
|
||||
// --- Submenu Flyout ---
|
||||
var sidebarNav = document.getElementById( 'site-navigation' );
|
||||
if ( sidebarNav ) {
|
||||
sidebarNav.querySelectorAll( '.menu-item-has-children' ).forEach( function ( item ) {
|
||||
var subMenu = item.querySelector( ':scope > .sub-menu' );
|
||||
if ( ! subMenu ) return;
|
||||
|
||||
var isOpen = false;
|
||||
var moveHdlr = null;
|
||||
|
||||
function showFlyout() {
|
||||
if ( isOpen ) return;
|
||||
isOpen = true;
|
||||
subMenu.style.top = item.getBoundingClientRect().top + 'px';
|
||||
item.classList.add( 'flyout-open' );
|
||||
|
||||
// Erkennungszone berechnen:
|
||||
// - vertikal: Höhe des li-Elements
|
||||
// - horizontal: von linkem Rand der Sidebar (0) bis
|
||||
// rechtem Rand des Flyout-Panels
|
||||
// → voller horizontaler Streifen für diesen Menüpunkt
|
||||
moveHdlr = function ( e ) {
|
||||
var ir = item.getBoundingClientRect();
|
||||
var sr = subMenu.getBoundingClientRect();
|
||||
|
||||
var zoneLeft = 0; // Bildschirmrand links
|
||||
var zoneRight = Math.max( ir.right, sr.right ); // bis Ende Flyout
|
||||
var zoneTop = ir.top; // oberer Rand des li
|
||||
var zoneBottom = ir.bottom; // unterer Rand des li
|
||||
|
||||
var inZone = e.clientX >= zoneLeft &&
|
||||
e.clientX <= zoneRight &&
|
||||
e.clientY >= zoneTop &&
|
||||
e.clientY <= zoneBottom;
|
||||
|
||||
if ( ! inZone ) hideFlyout();
|
||||
};
|
||||
|
||||
document.addEventListener( 'mousemove', moveHdlr );
|
||||
}
|
||||
|
||||
function hideFlyout() {
|
||||
if ( ! isOpen ) return;
|
||||
isOpen = false;
|
||||
item.classList.remove( 'flyout-open' );
|
||||
if ( moveHdlr ) {
|
||||
document.removeEventListener( 'mousemove', moveHdlr );
|
||||
moveHdlr = null;
|
||||
}
|
||||
}
|
||||
|
||||
item.addEventListener( 'mouseenter', showFlyout );
|
||||
|
||||
// Klick-Toggle für Touch / Tastatur
|
||||
var btn = document.createElement( 'button' );
|
||||
btn.className = 'submenu-toggle';
|
||||
btn.setAttribute( 'aria-expanded', 'false' );
|
||||
btn.innerHTML = '<i class="fas fa-chevron-down"></i>';
|
||||
var link = item.querySelector( ':scope > a' );
|
||||
if ( link ) link.insertAdjacentElement( 'afterend', btn );
|
||||
|
||||
btn.addEventListener( 'click', function ( e ) {
|
||||
e.stopPropagation();
|
||||
var open = item.classList.toggle( 'active' );
|
||||
btn.setAttribute( 'aria-expanded', open ? 'true' : 'false' );
|
||||
if ( open ) {
|
||||
subMenu.style.top = item.getBoundingClientRect().top + 'px';
|
||||
item.classList.add( 'flyout-open' );
|
||||
isOpen = true;
|
||||
} else {
|
||||
hideFlyout();
|
||||
}
|
||||
} );
|
||||
} );
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// =========================================================================
|
||||
// CLASSIC / CENTERED / MEGA
|
||||
// =========================================================================
|
||||
var siteNavigation = document.getElementById( 'site-navigation' );
|
||||
if ( ! siteNavigation ) return;
|
||||
|
||||
var menuToggle = siteNavigation.querySelector( '.menu-toggle' );
|
||||
var subMenuParents = siteNavigation.querySelectorAll( '.menu-item-has-children' );
|
||||
|
||||
if ( menuToggle ) {
|
||||
menuToggle.addEventListener( 'click', function () {
|
||||
var expanded = siteNavigation.classList.toggle( 'toggled' );
|
||||
this.setAttribute( 'aria-expanded', String( expanded ) );
|
||||
this.innerHTML = expanded ? '<i class="fas fa-times"></i>' : '<i class="fas fa-bars"></i>';
|
||||
} );
|
||||
document.addEventListener( 'click', function ( e ) {
|
||||
if ( siteNavigation.classList.contains( 'toggled' ) && ! siteNavigation.contains( e.target ) ) {
|
||||
siteNavigation.classList.remove( 'toggled' );
|
||||
@@ -31,31 +137,38 @@
|
||||
menuToggle.innerHTML = '<i class="fas fa-bars"></i>';
|
||||
}
|
||||
} );
|
||||
|
||||
// Mobile Submenu Toggle
|
||||
const subMenuParents = siteNavigation.querySelectorAll( '.menu-item-has-children' );
|
||||
|
||||
subMenuParents.forEach( function( subMenuParent ) {
|
||||
// FIX: Eigenen Toggle-Button erzeugen statt gesamtes <li> klickbar zu machen
|
||||
const toggleBtn = document.createElement( 'button' );
|
||||
toggleBtn.classList.add( 'submenu-toggle' );
|
||||
toggleBtn.setAttribute( 'aria-expanded', 'false' );
|
||||
toggleBtn.innerHTML = '<i class="fas fa-chevron-down"></i>';
|
||||
|
||||
const parentLink = subMenuParent.querySelector( 'a' );
|
||||
if ( parentLink ) {
|
||||
parentLink.insertAdjacentElement( 'afterend', toggleBtn );
|
||||
}
|
||||
|
||||
toggleBtn.addEventListener( 'click', function( e ) {
|
||||
e.stopPropagation();
|
||||
if ( window.innerWidth <= 992 ) {
|
||||
const isOpen = subMenuParent.classList.toggle( 'active' );
|
||||
toggleBtn.setAttribute( 'aria-expanded', isOpen ? 'true' : 'false' );
|
||||
// Icon drehen
|
||||
toggleBtn.querySelector('i').style.transform = isOpen ? 'rotate(180deg)' : 'rotate(0deg)';
|
||||
window.addEventListener( 'resize', function () {
|
||||
if ( window.innerWidth > 992 ) {
|
||||
siteNavigation.classList.remove( 'toggled' );
|
||||
menuToggle.setAttribute( 'aria-expanded', 'false' );
|
||||
menuToggle.innerHTML = '<i class="fas fa-bars"></i>';
|
||||
subMenuParents.forEach( function ( i ) { i.classList.remove( 'active' ); } );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
subMenuParents.forEach( function ( item ) {
|
||||
var btn = document.createElement( 'button' );
|
||||
btn.className = 'submenu-toggle';
|
||||
btn.setAttribute( 'aria-expanded', 'false' );
|
||||
btn.innerHTML = '<i class="fas fa-chevron-down"></i>';
|
||||
var link = item.querySelector( ':scope > a' );
|
||||
if ( link ) link.insertAdjacentElement( 'afterend', btn );
|
||||
btn.addEventListener( 'click', function ( e ) {
|
||||
e.stopPropagation();
|
||||
var open = item.classList.toggle( 'active' );
|
||||
btn.setAttribute( 'aria-expanded', open ? 'true' : 'false' );
|
||||
} );
|
||||
} );
|
||||
|
||||
document.addEventListener( 'click', function ( e ) {
|
||||
if ( ! e.target.closest( '.menu-item-has-children' ) ) {
|
||||
subMenuParents.forEach( function ( item ) {
|
||||
item.classList.remove( 'active' );
|
||||
var b = item.querySelector( '.submenu-toggle' );
|
||||
if ( b ) b.setAttribute( 'aria-expanded', 'false' );
|
||||
} );
|
||||
}
|
||||
} );
|
||||
|
||||
} )();
|
||||
@@ -1,24 +1,25 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
// Hole den Slider-Container
|
||||
const heroSlider = document.querySelector('.hero-slider');
|
||||
|
||||
// Stelle sicher, dass der Slider auf der Seite existiert
|
||||
if (!heroSlider) {
|
||||
const heroSlider = document.querySelector('.hero-slider');
|
||||
if (!heroSlider) return;
|
||||
|
||||
// BUG-FIX: sliderSettings wird via wp_localize_script gesetzt. Fehlt es
|
||||
// (z.B. wegen Caching oder falschem Enqueue), würde ein ReferenceError
|
||||
// den gesamten Slider-Init abschießen.
|
||||
if (typeof sliderSettings === 'undefined') {
|
||||
console.warn('Minecraft Modern Theme: sliderSettings nicht gefunden. Slider wird nicht initialisiert.');
|
||||
heroSlider.classList.add('swiper-initialized'); // Opacity-Fix trotzdem aufheben
|
||||
return;
|
||||
}
|
||||
|
||||
// Konfiguration für den Slider vorbereiten
|
||||
const swiperConfig = {
|
||||
// Der Effekt ist jetzt fest auf "Überblenden" eingestellt
|
||||
effect: 'fade',
|
||||
fadeEffect: {
|
||||
crossFade: true
|
||||
},
|
||||
|
||||
// Loop-Einstellung ist jetzt DYNAMISCH
|
||||
loop: sliderSettings.loop === '1',
|
||||
|
||||
// Autoplay
|
||||
autoplay: {
|
||||
delay: 5000,
|
||||
disableOnInteraction: false,
|
||||
@@ -26,13 +27,11 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
pauseOnMouseEnter: true,
|
||||
|
||||
// Prüfe, ob die Pfeile NICHT ausgeblendet werden sollen
|
||||
navigation: sliderSettings.hideArrows !== '1' ? {
|
||||
nextEl: '.swiper-button-next',
|
||||
prevEl: '.swiper-button-prev',
|
||||
} : false,
|
||||
|
||||
// Prüfe, ob die Paginierung NICHT ausgeblendet werden soll
|
||||
pagination: sliderSettings.hidePagination !== '1' ? {
|
||||
el: '.swiper-pagination',
|
||||
clickable: true,
|
||||
@@ -40,13 +39,12 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
|
||||
on: {
|
||||
init: function () {
|
||||
setTimeout(() => {
|
||||
setTimeout(function() {
|
||||
heroSlider.classList.add('swiper-initialized');
|
||||
}, 50);
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
// Initialisiere den Slider mit der konfigurierten Optionen
|
||||
new Swiper('.hero-slider', swiperConfig);
|
||||
});
|
||||
@@ -1,25 +1,21 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
// FIX: Null-Check – Login-Seite hat keinen Toggle-Button
|
||||
const toggle = document.querySelector('.theme-toggle');
|
||||
if ( ! toggle ) {
|
||||
return;
|
||||
}
|
||||
if ( ! toggle ) return;
|
||||
|
||||
const html = document.documentElement;
|
||||
const iconMoon = toggle.querySelector('.icon-moon');
|
||||
const iconSun = toggle.querySelector('.icon-sun');
|
||||
|
||||
const defaultMode = typeof sliderSettings !== 'undefined' ? sliderSettings.defaultMode : 'dark';
|
||||
const defaultMode = typeof sliderSettings !== 'undefined' && sliderSettings.defaultMode
|
||||
? sliderSettings.defaultMode
|
||||
: 'dark';
|
||||
|
||||
// FIX: Systemschema respektieren wenn kein gespeicherter Wert vorhanden
|
||||
// Gespeicherten Wert laden oder OS-Schema/Theme-Default als Fallback
|
||||
let saved = localStorage.getItem('themeMode');
|
||||
if ( ! saved ) {
|
||||
// Prüfe OS-Einstellung, falle sonst auf Theme-Default zurück
|
||||
if ( window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches ) {
|
||||
saved = 'light';
|
||||
} else {
|
||||
saved = defaultMode;
|
||||
}
|
||||
saved = ( window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches )
|
||||
? 'light'
|
||||
: defaultMode;
|
||||
}
|
||||
|
||||
function applyMode( mode ) {
|
||||
@@ -36,17 +32,19 @@ document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
applyMode( saved );
|
||||
|
||||
// BUG-FIX: Vorher wurde html.classList.toggle() aufgerufen und danach
|
||||
// applyMode() – das hat die Klasse doppelt manipuliert. Jetzt lesen wir
|
||||
// den aktuellen Zustand aus und rufen nur applyMode() auf.
|
||||
toggle.addEventListener('click', function () {
|
||||
const isLight = html.classList.toggle('light-mode');
|
||||
const newMode = isLight ? 'light' : 'dark';
|
||||
const isCurrentlyLight = html.classList.contains('light-mode');
|
||||
const newMode = isCurrentlyLight ? 'dark' : 'light';
|
||||
applyMode( newMode );
|
||||
localStorage.setItem('themeMode', newMode);
|
||||
});
|
||||
|
||||
// Live-Reaktion auf OS-Umschalten (optional aber nice-to-have)
|
||||
// Live-Reaktion auf OS-Umschalten (nur wenn keine manuelle Auswahl)
|
||||
if ( window.matchMedia ) {
|
||||
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', function( e ) {
|
||||
// Nur reagieren wenn der User noch keine manuelle Auswahl getroffen hat
|
||||
if ( ! localStorage.getItem('themeMode') ) {
|
||||
applyMode( e.matches ? 'light' : 'dark' );
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user