Zwischenstand vom 29.05.2026
This commit is contained in:
1 parent
b6d2142214
commit
dba154e572
36 files changed
+5113
-649
No files matched your search
@@ -0,0 +1,173 @@
|
||||
/**
|
||||
* OG Image Backend Module – live preview via AJAX
|
||||
* EXT:vitec/Resources/Public/Javascript/og-image-preview.js
|
||||
*/
|
||||
(function () {
|
||||
'use strict';
|
||||
|
||||
/** Debounce helper */
|
||||
function debounce(fn, ms) {
|
||||
let t;
|
||||
return function (...args) {
|
||||
clearTimeout(t);
|
||||
t = setTimeout(() => fn.apply(this, args), ms);
|
||||
};
|
||||
}
|
||||
|
||||
/** Collect all form values into a FormData-compatible plain object */
|
||||
function collectFormData() {
|
||||
const form = document.getElementById('vitecOgForm');
|
||||
if (!form) return {};
|
||||
const fd = new FormData(form);
|
||||
const out = {};
|
||||
for (const [key, val] of fd.entries()) {
|
||||
// key looks like "ogimage[something]"
|
||||
const match = key.match(/^ogimage\[(.+)]$/);
|
||||
if (match) {
|
||||
out[key] = val;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
/** POST to the preview endpoint, update the <img> */
|
||||
async function requestPreview() {
|
||||
const form = document.getElementById('vitecOgForm');
|
||||
const spinner = document.getElementById('previewSpinner');
|
||||
const img = document.getElementById('ogPreviewImg');
|
||||
const placeholder = document.getElementById('ogPreviewPlaceholder');
|
||||
const dl = document.getElementById('previewDownload');
|
||||
|
||||
if (!form) return;
|
||||
|
||||
if (spinner) spinner.classList.remove('d-none');
|
||||
|
||||
try {
|
||||
const body = new URLSearchParams(collectFormData());
|
||||
const previewUrl = form.dataset.previewUrl || window.location.href;
|
||||
|
||||
const resp = await fetch(previewUrl, {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
|
||||
body: body.toString(),
|
||||
});
|
||||
|
||||
if (!resp.ok) throw new Error('Server error ' + resp.status);
|
||||
|
||||
const json = await resp.json();
|
||||
|
||||
if (json.success && json.dataUri) {
|
||||
img.src = json.dataUri;
|
||||
img.style.display = 'block';
|
||||
if (placeholder) placeholder.style.display = 'none';
|
||||
|
||||
if (dl) {
|
||||
dl.href = json.dataUri;
|
||||
dl.classList.remove('d-none');
|
||||
}
|
||||
} else {
|
||||
console.warn('[OG Preview]', json.message);
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('[OG Preview] fetch failed:', e);
|
||||
} finally {
|
||||
if (spinner) spinner.classList.add('d-none');
|
||||
}
|
||||
}
|
||||
|
||||
const debouncedPreview = debounce(requestPreview, 600);
|
||||
|
||||
// ── Wire up events once DOM is ready ──────────────────────────────
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
|
||||
// Manual preview button
|
||||
const btn = document.getElementById('btnPreview');
|
||||
if (btn) {
|
||||
btn.addEventListener('click', requestPreview);
|
||||
}
|
||||
|
||||
// Auto-preview on any .js-live input change
|
||||
document.querySelectorAll('.js-live').forEach(function (el) {
|
||||
el.addEventListener('input', debouncedPreview);
|
||||
el.addEventListener('change', debouncedPreview);
|
||||
});
|
||||
|
||||
// Background type toggle (show colour vs image picker)
|
||||
function syncBgType() {
|
||||
const colorWrap = document.getElementById('bg-color-wrap');
|
||||
const imageWrap = document.getElementById('bg-image-wrap');
|
||||
const selected = document.querySelector('input.js-bg-type:checked');
|
||||
if (!selected) return;
|
||||
if (selected.value === 'image') {
|
||||
colorWrap && (colorWrap.style.display = 'none');
|
||||
imageWrap && (imageWrap.style.display = 'block');
|
||||
} else {
|
||||
colorWrap && (colorWrap.style.display = 'block');
|
||||
imageWrap && (imageWrap.style.display = 'none');
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('input.js-bg-type').forEach(function (el) {
|
||||
el.addEventListener('change', function () {
|
||||
syncBgType();
|
||||
debouncedPreview();
|
||||
});
|
||||
});
|
||||
|
||||
const bgImageSelect = document.querySelector('select[name="ogimage[bg_image]"]');
|
||||
if (bgImageSelect) {
|
||||
bgImageSelect.addEventListener('change', function () {
|
||||
const imageTypeRadio = document.querySelector('input.js-bg-type[value="image"]');
|
||||
if (imageTypeRadio) {
|
||||
imageTypeRadio.checked = true;
|
||||
}
|
||||
syncBgType();
|
||||
requestPreview();
|
||||
});
|
||||
}
|
||||
|
||||
syncBgType(); // initialise on load
|
||||
|
||||
// Hex text ↔ colour picker sync
|
||||
document.querySelectorAll('.js-hex-sync').forEach(function (hexInput) {
|
||||
const targetId = hexInput.dataset.target;
|
||||
const picker = document.getElementById(targetId);
|
||||
if (!picker) return;
|
||||
|
||||
picker.addEventListener('input', function () {
|
||||
hexInput.value = picker.value;
|
||||
});
|
||||
|
||||
hexInput.addEventListener('input', function () {
|
||||
const val = hexInput.value.trim();
|
||||
if (/^#[0-9a-fA-F]{6}$/.test(val)) {
|
||||
picker.value = val;
|
||||
picker.dispatchEvent(new Event('input', { bubbles: true }));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Preset buttons
|
||||
document.querySelectorAll('.js-preset').forEach(function (btn) {
|
||||
btn.addEventListener('click', function () {
|
||||
const bg = btn.dataset.bg;
|
||||
const tc = btn.dataset.titleColor;
|
||||
const sc = btn.dataset.subtitleColor;
|
||||
|
||||
const bgInput = document.getElementById('bgColor');
|
||||
if (bgInput && bg) { bgInput.value = bg; bgInput.dispatchEvent(new Event('input', {bubbles:true})); }
|
||||
|
||||
const tInput = document.getElementById('titleColor');
|
||||
if (tInput && tc) { tInput.value = tc; tInput.dispatchEvent(new Event('input', {bubbles:true})); }
|
||||
|
||||
const sInput = document.getElementById('subtitleColor');
|
||||
if (sInput && sc) { sInput.value = sc; sInput.dispatchEvent(new Event('input', {bubbles:true})); }
|
||||
|
||||
debouncedPreview();
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
})();
|
||||
Reference in new issue
Block a user