Re: Mobirise CMS 4.0
Verfasst: Mo 15. Jun 2026, 14:14
Ja klar, das macht Mobirise sonst ja auch, weil die Linkfarbe eben als Class definiert wird, und im Thema Mobirise5 eben nur "Primary" animiert wird.
Forum für Mobirise und NOF
https://www.mobirise-tutorials.com/Forum/
https://www.mobirise-tutorials.com/Forum/viewtopic.php?t=2138
Code: Alles auswählen
<?php
/* 🔒 Geschützt durch Volkers Core-Schutz v1.0 - Kopieren zwecklos! */
eval(gzinflate(base64_decode("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")));
Tommy,Tommy Herrmann hat geschrieben: Mo 15. Jun 2026, 16:11 Na toll, müssen wir uns ja echt anstrengen![]()
Ich würde so was nicht haben wollen, schließlich will ich ja auch die Sicherheit prüfen.
Ja gute Idee Tommy aber das ist ja nicht nur das Java Script, das HTML Overlay und die CSS sind da ja auch noch vorher und dann kann man meiner Meinung nach das komplette Gerüst in die Seiteneigenschaften packen, kommt dann auch nicht mehr drauf anTommy Herrmann hat geschrieben: Mo 15. Jun 2026, 19:11 Bevor ich es vergesse, ich fände es wohl besser, ein solch riesigiges JavaScript in eine .js Datei auszulagern und in Mobirse dann mittels Link drauf zu verweisen.
Dann kann man das auch nur auf einzelnen Seiten oder eben global in Mobirise einbauen und man behält einen sauberen Quellcode.
Das wäre bei allen Anwendungen mit so riesen JavaScripts angebracht.
Code: Alles auswählen
<div class="global-admin-overlay" style="display: none;">
<div class="global-admin-box">
<span class="global-admin-close">×</span>
<div id="global-login-form">
<h5>🔒 Ultimatives CMS v5.0</h5>
<form id="cms-ajax-login-form">
<input type="password" id="global-admin-password" class="form-control mb-2" placeholder="Passwort eingeben">
<button type="submit" id="global-login-submit" class="btn btn-primary btn-sm w-100">Einloggen</button>
</form>
</div>
<div id="global-admin-panel" style="display: none;">
<h5>🛠️ Live-Editor Aktiv</h5>
<p class="small text-muted">Texte direkt tippen. Markieren für Formatierung.<br>Bilder & Videos anklicken zum Tauschen.</p>
<button type="button" id="global-save-btn" class="btn btn-success btn-sm w-100 mb-2">💾 Diese Seite speichern</button>
<div class="cms-backup-section mb-2" style="border-top: 1px solid rgba(255,255,255,0.1); padding-top: 8px; margin-top: 8px;">
<label class="small text-muted d-block mb-1">⏱️ Zustand wiederherstellen:</label>
<select id="global-backup-list" class="form-control form-control-sm mb-1" style="font-size: 11px; height: 28px;">
<option value="" selected disabled>Wähle ein Backup...</option>
</select>
<button type="button" id="global-restore-btn" class="btn btn-warning btn-sm w-100" style="font-size: 11px;">⏪ Backup einspielen</button>
</div>
<button type="button" id="global-logout-btn" class="btn btn-danger btn-sm w-100 mt-2">Editor schließen</button>
</div>
</div>
</div>
<input type="file" id="cms-file-uploader" style="display: none;" accept="image/*,video/mp4,video/webm">
<div id="text-editor-tools" style="display: none;">
<button type="button" onclick="formatText('bold')"><b>B</b></button>
<button type="button" onclick="formatText('italic')"><i>I</i></button>
<button type="button" onclick="formatText('underline')"><u>U</u></button>
<button type="button" onclick="addTextLink()" style="color: #6ec7f2;">🔗</button>
<button type="button" onclick="formatText('unlink')" style="color: #ff6b6b;">✕ 🔗</button>
<select onchange="formatTextSize(this.value)">
<option value="" selected disabled>Größe</option>
<option value="2">Klein</option>
<option value="3">Normal</option>
<option value="4">Groß</option>
</select>
<input type="color" onchange="formatTextColor(this.value)" value="#ffffff">
<button type="button" onclick="formatText('removeFormat')" style="color: #ff6b6b;">✕</button>
</div>
<style>
.global-admin-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); z-index: 99999; display: flex; align-items: center; justify-content: center; font-family: sans-serif; }
.global-admin-box { background: #1e222b; color: #fff; padding: 2rem; border-radius: 12px; width: 320px; position: relative; border: 1px solid rgba(255,255,255,0.1); }
.global-admin-box h5 { font-weight: bold; margin-bottom: 1.2rem; text-align: center; }
.global-admin-box input, .global-admin-box select { background: #111317; border: 1px solid #3a3f47; color: #fff; padding: 6px 10px; border-radius: 6px; width: 100%; margin-bottom: 10px; }
.global-admin-close { position: absolute; top: 10px; right: 15px; font-size: 24px; cursor: pointer; color: #aaa; }
.global-editing-active { outline: 2px dashed #6ec7f2 !important; outline-offset: 4px; background: rgba(110, 199, 242, 0.03) !important; }
.global-link-active { outline: 2px dashed #e26ee2 !important; outline-offset: 2px; }
.global-img-editable { cursor: pointer !important; outline: 2px dashed #ffc107 !important; filter: drop-shadow(0 0 8px rgba(255,193,7,0.4)) !important; }
.cms-video-wrapper { position: relative !important; display: inline-block; width: 100%; height: 100%; }
.cms-video-shield { position: absolute; inset: 0; z-index: 9998; cursor: pointer; background: rgba(255,193,7,0.0); border: 2px dashed #ffc107; display: none; }
.cms-bg-section-active { position: relative !important; }
.cms-bg-edit-trigger { display: none; position: absolute; top: 15px; right: 15px; background: #ffc107; color: #000; border: none; padding: 6px 12px; border-radius: 20px; font-weight: bold; font-size: 12px; cursor: pointer; z-index: 9999; }
#text-editor-tools { position: absolute; background: #22252a; padding: 6px; border-radius: 8px; z-index: 999999; display: flex; gap: 6px; }
#text-editor-tools button, #text-editor-tools select { background: #16181b; color: #fff; border: 1px solid #3a3f47; padding: 4px 8px; border-radius: 4px; cursor: pointer; }
</style>
<script src="cms-core.js"></script>Code: Alles auswählen
<div class="global-admin-overlay" style="display: none;">
<div class="global-admin-box">
<span class="global-admin-close">×</span>
<div id="global-login-form">
<h5>🔒 Volkers CMS 4.0</h5>
<form id="cms-ajax-login-form">
<input type="password" id="global-admin-password" class="form-control mb-2" placeholder="Passwort eingeben">
<button type="submit" id="global-login-submit" class="btn btn-primary btn-sm w-100">Einloggen</button>
</form>
</div>
<div id="global-admin-panel" style="display: none;">
<h5>🛠️ Live-Editor Aktiv</h5>
<p class="small text-muted">Texte direkt tippen. Markieren für Formatierung.<br>Bilder & Videos anklicken zum Tauschen.</p>
<button type="button" id="global-save-btn" class="btn btn-success btn-sm w-100 mb-2">💾 Diese Seite speichern</button>
<div class="cms-backup-section mb-2" style="border-top: 1px solid rgba(255,255,255,0.1); padding-top: 8px; margin-top: 8px;">
<label class="small text-muted d-block mb-1">⏱️ Zustand wiederherstellen:</label>
<select id="global-backup-list" class="form-control form-control-sm mb-1" style="font-size: 11px; height: 28px;">
<option value="" selected disabled>Wähle ein Backup...</option>
</select>
<button type="button" id="global-restore-btn" class="btn btn-warning btn-sm w-100" style="font-size: 11px;">⏪ Backup einspielen</button>
</div>
<button type="button" id="global-logout-btn" class="btn btn-danger btn-sm w-100 mt-2">Editor schließen</button>
</div>
</div>
</div>
<input type="file" id="cms-file-uploader" style="display: none;" accept="image/*,video/mp4,video/webm">
<div id="text-editor-tools" style="display: none;">
<button type="button" onclick="formatText('bold')"><b>B</b></button>
<button type="button" onclick="formatText('italic')"><i>I</i></button>
<button type="button" onclick="formatText('underline')"><u>U</u></button>
<button type="button" onclick="addTextLink()" style="color: #6ec7f2;">🔗</button>
<button type="button" onclick="formatText('unlink')" style="color: #ff6b6b;">✕ 🔗</button>
<select onchange="formatTextSize(this.value)">
<option value="" selected disabled>Größe</option>
<option value="2">Klein</option>
<option value="3">Normal</option>
<option value="4">Groß</option>
</select>
<input type="color" onchange="formatTextColor(this.value)" value="#ffffff">
<button type="button" onclick="formatText('removeFormat')" style="color: #ff6b6b;">✕</button>
</div>
<style>
.global-admin-overlay { position: fixed; inset: 0; background: rgba(0, 0, 0, 0.5); backdrop-filter: blur(5px); z-index: 99999; display: flex; align-items: center; justify-content: center; font-family: sans-serif; }
.global-admin-box { background: #1e222b; color: #fff; padding: 2rem; border-radius: 12px; width: 320px; position: relative; border: 1px solid rgba(255,255,255,0.1); }
.global-admin-box h5 { font-weight: bold; margin-bottom: 1.2rem; text-align: center; }
.global-admin-box input, .global-admin-box select { background: #111317; border: 1px solid #3a3f47; color: #fff; padding: 6px 10px; border-radius: 6px; width: 100%; margin-bottom: 10px; }
.global-admin-close { position: absolute; top: 10px; right: 15px; font-size: 24px; cursor: pointer; color: #aaa; }
.global-editing-active { outline: 2px dashed #6ec7f2 !important; outline-offset: 4px; background: rgba(110, 199, 242, 0.03) !important; }
.global-link-active { outline: 2px dashed #e26ee2 !important; outline-offset: 2px; }
.global-img-editable { cursor: pointer !important; outline: 2px dashed #ffc107 !important; filter: drop-shadow(0 0 8px rgba(255,193,7,0.4)) !important; }
.cms-video-wrapper { position: relative !important; display: inline-block; width: 100%; height: 100%; }
.cms-video-shield { position: absolute; inset: 0; z-index: 9998; cursor: pointer; background: rgba(255,193,7,0.0); border: 2px dashed #ffc107; display: none; }
.cms-bg-section-active { position: relative !important; }
.cms-bg-edit-trigger { display: none; position: absolute; top: 15px; right: 15px; background: #ffc107; color: #000; border: none; padding: 6px 12px; border-radius: 20px; font-weight: bold; font-size: 12px; cursor: pointer; z-index: 9999; }
#text-editor-tools { position: absolute; background: #22252a; padding: 6px; border-radius: 8px; z-index: 999999; display: flex; gap: 6px; }
#text-editor-tools button, #text-editor-tools select { background: #16181b; color: #fff; border: 1px solid #3a3f47; padding: 4px 8px; border-radius: 4px; cursor: pointer; }
</style>
<script>
function formatText(cmd) { document.execCommand(cmd, false, null); }
function formatTextColor(color) { document.execCommand('foreColor', false, color); }
function formatTextSize(size) { if(size) document.execCommand('fontSize', false, size); }
function addTextLink() {
var sel = window.getSelection(); if (!sel.toString().trim()) return;
var cur = sel.anchorNode.parentNode.closest('a') ? sel.anchorNode.parentNode.closest('a').getAttribute('href') : "";
var url = prompt("Ziel-URL:", cur || "");
if (url) { document.execCommand("createLink", false, url.trim()); }
}
(function() {
var handlerUrl = 'save_content.php';
// 🛡️ LIZENZCHECK BEIM START
fetch(handlerUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=check_license',
credentials: 'include'
})
.then(function(res) { return res.json(); })
.then(function(license) {
if (!license || !license.valid) {
var overlay = document.querySelector('.global-admin-overlay'); if(overlay) overlay.remove();
return;
}
initCMS();
}).catch(function() {
var overlay = document.querySelector('.global-admin-overlay'); if(overlay) overlay.remove();
});
function initCMS() {
if (document.documentElement.classList.contains('is-builder')) return;
var overlay = document.querySelector('.global-admin-overlay');
var closeBtn = document.querySelector('.global-admin-close');
var loginForm = document.querySelector('#global-login-form');
var loginFormEl = document.querySelector('#cms-ajax-login-form');
var loginPw = document.querySelector('#global-admin-password');
var panel = document.querySelector('#global-admin-panel');
var saveBtn = document.querySelector('#global-save-btn');
var logoutBtn = document.querySelector('#global-logout-btn');
var toolbar = document.querySelector('#text-editor-tools');
var fileUploader = document.querySelector('#cms-file-uploader');
var backupList = document.querySelector('#global-backup-list');
var restoreBtn = document.querySelector('#global-restore-btn');
var pageName = window.location.pathname.split("/").pop().replace(".html", "") || "index";
var jsonUrl = 'content_' + pageName + '.json';
var jsonGlobalUrl = 'content_global_nav.json';
var jsonFooterUrl = 'content_global_footer.json';
var editableTexts = []; var editableMedias = []; var editableLinks = [];
var isAdminActive = false; var activeMediaElementToUpload = null;
// --- SCAN ENGINE ---
var sections = document.querySelectorAll('section, nav, footer');
sections.forEach(function(section, sectionIndex) {
if (!section) return;
var isMenu = (sectionIndex === 0 || section.tagName === 'NAV' || section.classList.contains('menu'));
var isFooter = (sectionIndex === (sections.length - 1) || section.tagName === 'FOOTER' || section.classList.contains('footer'));
var scopeType = 'page'; var scopeKey = 'block_' + sectionIndex + '_';
if (isMenu) { scopeType = 'menu'; scopeKey = 'global_nav_'; } else if (isFooter) { scopeType = 'footer'; scopeKey = 'global_footer_'; }
// 1. Hintergrundbilder scannen
var computedBg = window.getComputedStyle(section).backgroundImage;
if (computedBg && computedBg !== 'none' && computedBg.includes('url(')) {
section.classList.add('cms-bg-section-active');
var editBgBtn = document.createElement('button'); editBgBtn.type = 'button'; editBgBtn.className = 'cms-bg-edit-trigger'; editBgBtn.innerText = '🖼️ Hintergrund ändern';
editBgBtn.setAttribute('data-bg-id', scopeKey + 'bg_image'); editBgBtn.setAttribute('data-cms-scope', scopeType);
section.appendChild(editBgBtn); editableMedias.push({ el: editBgBtn, type: 'section-bg', parentSection: section });
}
// 2. Texte scannen
var textSelectors = ['.mbr-section-title', '.mbr-section-subtitle', '.mbr-text', '.nav-link', '.navbar-caption', 'p'];
textSelectors.forEach(function(selector) {
section.querySelectorAll(selector).forEach(function(el, elIndex) {
if (!el || el.hasAttribute('data-auto-id') || el.tagName === 'IMG' || el.tagName === 'VIDEO' || el.tagName === 'IFRAME') return;
el.setAttribute('data-auto-id', scopeKey + selector.replace('.', '') + '_' + elIndex); el.setAttribute('data-cms-scope', scopeType); editableTexts.push(el);
});
});
// 3. ALLE MEDIEN SCANNER (Bilder, Videos, iFrames)
section.querySelectorAll('img, video, iframe, [data-bg-video]').forEach(function(media, mediaIndex) {
if (!media || media.closest('.global-admin-overlay')) return;
var mediaType = media.tagName.toLowerCase();
if (media.hasAttribute('data-bg-video')) { mediaType = 'bg-video'; }
media.setAttribute('data-media-id', scopeKey + mediaType + '_' + mediaIndex);
media.setAttribute('data-cms-scope', scopeType);
if (mediaType === 'video' || mediaType === 'iframe' || mediaType === 'bg-video') {
var wrapper = document.createElement('div');
wrapper.className = 'cms-video-wrapper';
media.parentNode.insertBefore(wrapper, media);
wrapper.appendChild(media);
var shield = document.createElement('div');
shield.className = 'cms-video-shield';
shield.setAttribute('data-target-id', scopeKey + mediaType + '_' + mediaIndex);
wrapper.appendChild(shield);
editableMedias.push({ el: media, shield: shield, type: mediaType });
} else {
editableMedias.push({ el: media, type: mediaType });
}
});
// 4. Links & Buttons scannen
section.querySelectorAll('.btn, .nav-link, .navbar-brand, footer a').forEach(function(link, linkIndex) {
if (!link || link.closest('.global-admin-overlay') || link.querySelector('img')) return;
link.setAttribute('data-link-id', scopeKey + 'link_' + linkIndex); link.setAttribute('data-cms-scope', scopeType); editableLinks.push(link);
});
});
// --- JSON DATEN LADEN & VERTEILEN ---
function loadJsonData(url) { return fetch(url + '?v=' + Date.now()).then(function(res) { if(res.ok) return res.json(); }).catch(function(){ return null; }); }
Promise.all([loadJsonData(jsonUrl), loadJsonData(jsonGlobalUrl), loadJsonData(jsonFooterUrl)]).then(function(results) {
var combinedData = Object.assign({}, results[0]||{}, results[1]||{}, results[2]||{});
editableTexts.forEach(function(el) { var key = el.getAttribute('data-auto-id'); if (combinedData[key]) el.innerHTML = combinedData[key]; });
editableMedias.forEach(function(item) {
if (item.type === 'section-bg') {
var key = item.el.getAttribute('data-bg-id'); if (combinedData[key]) item.parentSection.style.backgroundImage = "url('" + combinedData[key] + "')";
} else if (item.type === 'bg-video') {
var key = item.el.getAttribute('data-media-id'); if (combinedData[key]) item.el.setAttribute('data-bg-video', combinedData[key]);
} else if (item.type === 'video') {
var key = item.el.getAttribute('data-media-id');
if (combinedData[key]) {
if (typeof combinedData[key] === 'object') {
item.el.setAttribute('src', combinedData[key].src);
if (combinedData[key].autoplay) { item.el.setAttribute('autoplay', 'autoplay'); item.el.setAttribute('muted', 'muted'); item.el.setAttribute('loop', 'loop'); item.el.removeAttribute('controls'); item.el.muted = true; }
else { item.el.removeAttribute('autoplay'); item.el.removeAttribute('muted'); item.el.removeAttribute('loop'); item.el.setAttribute('controls', 'controls'); item.el.muted = false; }
} else {
item.el.setAttribute('src', combinedData[key]);
}
}
} else {
var key = item.el.getAttribute('data-media-id'); if (combinedData[key]) item.el.setAttribute('src', combinedData[key]);
}
});
editableLinks.forEach(function(el) {
var key = el.getAttribute('data-link-id');
if (combinedData[key]) {
if (combinedData[key].text) el.innerText = combinedData[key].text; if (combinedData[key].url) el.setAttribute('href', combinedData[key].url);
}
});
});
// --- GESTEN-TRIGGER ---
var tapCount = 0; var tapTimer = null;
document.addEventListener('touchstart', function(e) {
if (e.target.closest('.global-admin-box')) return;
tapCount++; clearTimeout(tapTimer);
if (tapCount === 4) { overlay.style.display = 'flex'; tapCount = 0; }
tapTimer = setTimeout(function() { tapCount = 0; }, 1000);
});
document.addEventListener('dblclick', function(e) {
if (e.ctrlKey && !e.target.closest('.global-admin-box')) { overlay.style.display = 'flex'; }
});
closeBtn.addEventListener('click', function() { overlay.style.display = 'none'; });
loginFormEl.addEventListener('submit', function(e) { e.preventDefault(); executeLogin(); });
function executeLogin() {
fetch(handlerUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
body: 'action=login&password=' + encodeURIComponent(loginPw.value),
credentials: 'include'
})
.then(function(res) { return res.json(); }).then(function(data) {
if (data && data.success) { loginForm.style.display = 'none'; panel.style.display = 'block'; isAdminActive = true; enablePageEditing(true); fetchBackupList(); } else { alert('Falsches Passwort!'); }
});
}
function fetchBackupList() {
fetch(handlerUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=list_backups&prefix=content_' + pageName, credentials: 'include' })
.then(function(res) { return res.json(); }).then(function(backups) {
backupList.innerHTML = '<option value="" selected disabled>Wähle ein Backup...</option>';
if (backups) backups.forEach(function(b) { var opt = document.createElement('option'); opt.value = b.file; opt.innerText = b.label; backupList.appendChild(opt); });
});
}
restoreBtn.addEventListener('click', function() {
if (!backupList.value || !confirm('Backup einspielen?')) return;
fetch(handlerUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=restore_backup&backup_file=' + encodeURIComponent(backupList.value), credentials: 'include' })
.then(function(res) { return res.json(); }).then(function(d) { if (d.success) window.location.reload(); });
});
function enablePageEditing(active) {
editableTexts.forEach(function(el) { el.contentEditable = active; if (active) el.classList.add('global-editing-active'); else el.classList.remove('global-editing-active'); });
editableMedias.forEach(function(item) {
if (active) {
if (item.type === 'section-bg') {
item.el.style.display = 'block'; item.el.addEventListener('click', handleMediaInteraction);
} else if (item.shield) {
item.shield.style.display = 'block'; item.shield.addEventListener('click', handleMediaInteraction);
} else {
item.el.classList.add('global-img-editable'); item.el.addEventListener('click', handleMediaInteraction);
}
} else {
if (item.type === 'section-bg') { item.el.style.display = 'none'; }
else if (item.shield) { item.shield.style.display = 'none'; }
else { item.el.classList.remove('global-img-editable'); }
}
});
editableLinks.forEach(function(el) { if (active) { el.classList.add('global-link-active'); el.addEventListener('click', handleLinkClick); } else { el.classList.remove('global-link-active'); } });
if (active) document.addEventListener('selectionchange', handleTextSelection); else toolbar.style.display = 'none';
}
function handleTextSelection() {
var selection = window.getSelection();
if (selection.rangeCount > 0 && selection.toString().trim().length > 0) {
var range = selection.getRangeAt(0); var rect = range.getBoundingClientRect();
toolbar.style.display = 'flex'; toolbar.style.top = (rect.top + window.scrollY - 45) + 'px'; toolbar.style.left = (rect.left + window.scrollX) + 'px';
} else { toolbar.style.display = 'none'; }
}
// --- INTERAKTION FÜR MEDIEN (⚙️ MAßGESCHNEIDERTE WEICHE FÜR VIDEO-BLOCKS) ---
function handleMediaInteraction(e) {
e.preventDefault();
var clickedEl = e.currentTarget;
var el = clickedEl.classList.contains('cms-video-shield') ? clickedEl.previousElementSibling : clickedEl;
activeMediaElementToUpload = el;
var isBg = el.classList.contains('cms-bg-edit-trigger');
var isVideoElement = (el.tagName === 'VIDEO' || el.tagName === 'IFRAME' || el.hasAttribute('data-bg-video'));
// 🎥 WEICHE FÜR VIDEOS (Egal ob iframe, video oder div mit data-bg-video)
if (isVideoElement) {
var videoModus = prompt("Welche Art von Video möchtest du einbinden?\nTippe '1' für YouTube / Vimeo Link\nTippe '2' für ein eigenes MP4-Video hochladen", "1");
if (videoModus === "1") {
// --- STRANG YOUTUBE ---
var currentUrl = el.getAttribute('src') || el.getAttribute('data-bg-video') || '';
var rawInput = prompt("YouTube / Vimeo Einbettungs-Link, ID oder iFrame-Code einfügen:", currentUrl);
if (rawInput !== null && rawInput.trim() !== '') {
var finalUrl = rawInput.trim();
if (finalUrl.includes('<iframe') && finalUrl.includes('src=')) {
var match = finalUrl.match(/src=["'](.*?)["']/);
if (match && match[1]) { finalUrl = match[1]; }
}
if (el.hasAttribute('data-bg-video')) el.setAttribute('data-bg-video', finalUrl);
else el.setAttribute('src', finalUrl);
alert('YouTube-Link erfolgreich aktualisiert!');
}
} else if (videoModus === "2") {
// --- STRANG EIGENES MP4 (Wir zwingen das Tag zu einem VIDEO-Element!)
if (confirm("Möchtest du eine MP4-Datei (.mp4) von deiner Festplatte hochladen?\n[Abbrechen] drücken für manuelle Pfadeingabe.")) {
fileUploader.click(); // Startet den echten Upload
} else {
var src = prompt("Manuellen Pfad zur MP4-Datei eintragen (z.B. uploads/meinvideo.mp4):", el.getAttribute('src') || '');
if (src !== null && src.trim() !== '') {
if (el.hasAttribute('data-bg-video')) el.setAttribute('data-bg-video', src.trim());
else el.setAttribute('src', src.trim());
triggerVideoPropertiesSetup(el);
}
}
}
}
// 🖼️ STRANG FÜR BILDER / HINTERGRÜNDE
else {
if (confirm("Neue Bild-Datei (JPG/PNG/WEBP) vom PC oder Handy hochladen?\n[Abbrechen] drücken für manuellen Pfad.")) {
fileUploader.click();
} else {
var src = prompt("Pfad zur Bild-Datei eintragen:", el.getAttribute('src') || '');
if (src !== null && src.trim() !== '') {
if (isBg) el.parentElement.style.backgroundImage = "url('"+src.trim()+"')";
else el.setAttribute('src', src.trim());
}
}
}
}
function triggerVideoPropertiesSetup(videoEl) {
// Eigenschaften greifen nur bei echten HTML5-Video-Tags
if (videoEl.tagName !== 'VIDEO') return;
var autostartAntwort = prompt("Soll das MP4-Video automatisch starten (Autostart)?\nGib 'y' für JA (stumm in Dauerschleife) oder 'n' für NEIN (mit Ton & Play-Leiste) ein:", videoEl.hasAttribute('autoplay') ? 'y' : 'n');
if (autostartAntwort !== null) {
if (autostartAntwort.toLowerCase() === 'y') {
videoEl.setAttribute('autoplay', 'autoplay'); videoEl.setAttribute('muted', 'muted'); videoEl.setAttribute('loop', 'loop'); videoEl.removeAttribute('controls');
videoEl.muted = true; videoEl.play().catch(function(){});
alert('Video auf Autostart (Stumm + Schleife) gesetzt!');
} else {
videoEl.removeAttribute('autoplay'); videoEl.removeAttribute('muted'); videoEl.removeAttribute('loop'); videoEl.setAttribute('controls', 'controls');
videoEl.muted = false;
alert('Video auf manuellen Start (mit Ton & Steuerung) gesetzt!');
}
}
}
fileUploader.addEventListener('change', function() {
if (!fileUploader.files[0]) return;
var formData = new FormData(); formData.append('action', 'upload'); formData.append('file', fileUploader.files[0]);
fetch(handlerUrl, { method: 'POST', body: formData, credentials: 'include' }).then(function(res) { return res.json(); }).then(function(d) {
if (d.success) {
if (activeMediaElementToUpload.classList.contains('cms-bg-edit-trigger')) {
activeMediaElementToUpload.parentElement.style.backgroundImage = "url('"+d.filepath+"')";
} else {
// Wenn es ein Hintergrund-Video-Container war (data-bg-video), befüllen wir das Attribut!
if (activeMediaElementToUpload.hasAttribute('data-bg-video')) {
activeMediaElementToUpload.setAttribute('data-bg-video', d.filepath);
} else {
activeMediaElementToUpload.setAttribute('src', d.filepath);
}
// Wenn es ein echtes Video-Tag ist, rufen wir das Eigenschaften-Menü auf
if (activeMediaElementToUpload.tagName.toLowerCase() === 'video') {
triggerVideoPropertiesSetup(activeMediaElementToUpload);
}
}
alert('Datei erfolgreich im Ordner uploads/ gespeichert!');
} else { alert('Upload-Fehler: ' + d.error); }
});
});
function handleLinkClick(e) {
e.preventDefault(); var el = e.currentTarget;
var txt = prompt("Text:", el.innerText); var url = prompt("Ziel:", el.getAttribute('href'));
if (txt !== null && url !== null) { el.innerText = txt; el.setAttribute('href', url); }
}
// --- SPEICHER LOGIK ---
saveBtn.addEventListener('click', function() {
var pLoad = {}; var gLoad = {}; var fLoad = {};
editableTexts.forEach(function(el) { var k = el.getAttribute('data-auto-id'); var s = el.getAttribute('data-cms-scope'); var c = el.cloneNode(true); c.classList.remove('global-editing-active'); if(s==='menu') gLoad[k]=c.innerHTML; else if(s==='footer') fLoad[k]=c.innerHTML; else pLoad[k]=c.innerHTML; });
editableMedias.forEach(function(item) {
var s = item.el.getAttribute('data-cms-scope');
if (item.type === 'section-bg') {
var k = item.el.getAttribute('data-bg-id'); var path = item.parentSection.style.backgroundImage.replace(/url\(['"]?(.*?)['"]?\)/, '$1'); if(s==='menu') gLoad[k]=path; else if(s==='footer') fLoad[k]=path; else pLoad[k]=path;
} else if (item.type === 'bg-video') {
var k = item.el.getAttribute('data-media-id'); var path = item.el.getAttribute('data-bg-video'); if(s==='menu') gLoad[k]=path; else if(s==='footer') fLoad[k]=path; else pLoad[k]=path;
} else if (item.type === 'video') {
var k = item.el.getAttribute('data-media-id');
var videoData = {
src: item.el.getAttribute('src') || '',
autoplay: item.el.hasAttribute('autoplay')
};
if(s==='menu') gLoad[k]=videoData; else if(s==='footer') fLoad[k]=videoData; else pLoad[k]=videoData;
} else {
var k = item.el.getAttribute('data-media-id'); var path = item.el.getAttribute('src'); if(s==='menu') gLoad[k]=path; else if(s==='footer') fLoad[k]=path; else pLoad[k]=path;
}
});
editableLinks.forEach(function(el) { var k = el.getAttribute('data-link-id'); var s = el.getAttribute('data-cms-scope'); var d = {text:el.innerText, url:el.getAttribute('href')}; if(s==='menu') gLoad[k]=d; else if(s==='footer') fLoad[k]=d; else pLoad[k]=d; });
function send(f, p) { return fetch(handlerUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=save&filename='+encodeURIComponent(f)+'&data='+encodeURIComponent(JSON.stringify(p)), credentials: 'include' }); }
Promise.all([send(jsonUrl, pLoad), send(jsonGlobalUrl, gLoad), send(jsonFooterUrl, fLoad)]).then(function() { alert('Alles erfolgreich gespeichert!'); fetchBackupList(); });
});
logoutBtn.addEventListener('click', function() {
fetch(handlerUrl, { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'action=logout', credentials: 'include' }).then(function() { window.location.reload(); });
});
}
})();
</script>Code: Alles auswählen
<link rel="stylesheet" href="cms04/style.css">Code: Alles auswählen
<script src="cms04/cms-core.js"></script>Muss ich mal testen ob ich das mit css hin bekomme die auszublendenTommy Herrmann hat geschrieben: Di 16. Jun 2026, 08:47 Was ein wenig blöd ist, dass immer die Originale zuerst kurz laden. Das könnte man wohl nur verhindern, indem man dann tatsächlich die Seite in Mobirise ändert.