fix: reliably reveal image link fields on selection (1.7.4)
CMS quality / php (8.2) (push) Canceled after 0s
CMS quality / php (8.4) (push) Canceled after 0s
CMS quality / browser (push) Canceled after 0s
CMS quality / mysql (push) Canceled after 0s

This commit is contained in:
kantarci committed 2026-09-14 11:56:40 +02:00
1 parent e18c881db8
commit 25fd388f80
5 files changed
+70 -10

No files matched your search

+22 -9
View File
@@ -179,6 +179,7 @@ function renderProperties() {
if (block && propertyPanel === 'design') { renderDesign(block, panel); return; }
let imagePreview;
const field = (label, key, value, options = {}) => {
const container = options.container || panel;
const id = `property-${key}`;
const labelEl = document.createElement('label'); labelEl.htmlFor = id; labelEl.textContent = label;
let input;
@@ -190,8 +191,13 @@ function renderProperties() {
if (options.number && !options.choices) { input.type = 'number'; input.min = options.min || '1'; input.max = options.max || '8000'; }
if (options.checkbox) { input.type = 'checkbox'; input.checked = Boolean(value); labelEl.className = 'check-label'; labelEl.prepend(input); }
if (options.maxLength) input.maxLength = options.maxLength;
input.addEventListener('input', () => {
let previousChoice = input.value;
const applyValue = () => {
const next = options.number ? Number(input.value) : options.checkbox ? input.checked : input.value;
// Native selects may emit input, change, or both. Apply each selection once and keep
// the control in place while its popup or keyboard navigation is active.
if (options.choices && input.value === previousChoice) return;
previousChoice = input.value;
history.change(doc => {
const current = selected ? locate(doc.blocks, selected)?.block : doc;
if (!current) return;
@@ -206,15 +212,18 @@ function renderProperties() {
if (key === 'click' || key === 'lightbox') upgradeDocument(doc, 19);
if (key === 'newTab') upgradeDocument(doc, 20);
if (current.type === 'image' && key === 'src') { delete current.props.sources; delete current.props.mediaId; }
}, `${selected || 'page'}:${key}`);
}, options.choices ? null : `${selected || 'page'}:${key}`);
if (key === 'src') imagePreview?.update({ src: input.value });
if (['decorative', 'click'].includes(key)) { renderProperties(); document.getElementById(id)?.focus({ preventScroll: true }); }
options.onInput?.(next);
if (key === 'decorative') { renderProperties(); document.getElementById(id)?.focus({ preventScroll: true }); }
renderTree(); controls(); schedulePreview();
});
};
input.addEventListener('input', applyValue);
if (options.choices) input.addEventListener('change', applyValue);
input.addEventListener('blur', () => { history.mergeKey = null; });
if (options.checkbox) panel.append(labelEl); else panel.append(labelEl, input);
if (options.help) { const help = document.createElement('p'); help.className = 'field-help'; help.id = `${id}-help`; help.textContent = options.help; input.setAttribute('aria-describedby', help.id); panel.append(help); }
if (key === 'href') field('In neuem Tab öffnen', 'newTab', block.props.newTab === true, { checkbox: true });
if (options.checkbox) container.append(labelEl); else container.append(labelEl, input);
if (options.help) { const help = document.createElement('p'); help.className = 'field-help'; help.id = `${id}-help`; help.textContent = options.help; input.setAttribute('aria-describedby', help.id); container.append(help); }
if (key === 'href') field('In neuem Tab öffnen', 'newTab', block.props.newTab === true, { checkbox: true, container });
};
if (!block) {
field('Seitentitel', 'title', history.document.title, { maxLength: 160 });
@@ -340,8 +349,12 @@ function renderProperties() {
renderImageWidth(block, panel);
imagePreview = createMediaPreview({ src: block.props.sources?.[0]?.src || block.props.src, label: block.props.alt || block.props.caption });
panel.append(imagePreview.element);
field('Beim Klick', 'click', block.props?.click || (block.props?.href ? 'link' : 'keine'), { choices: { keine: 'Nichts tun', vergroessern: 'Bild vergrößern', link: 'Zu einer Adresse führen' }, help: 'Vergrößern öffnet das Bild über der Seite. Ohne JavaScript öffnet derselbe Klick die große Bilddatei – die Seite bleibt also in jedem Fall benutzbar.' });
if ((block.props?.click || (block.props?.href ? 'link' : 'keine')) === 'link') field('Linkziel', 'href', block.props.href || '', { help: 'Lokaler Pfad (/kontakt), Sprungmarke (#abschnitt) oder HTTPS-Adresse. Für ein Logo im Kopfbereich meist /.' });
const linkOptions = document.createElement('div'); linkOptions.className = 'image-link-options';
const showLinkOptions = value => { linkOptions.hidden = value !== 'link'; };
const clickAction = block.props?.click || (block.props?.href ? 'link' : 'keine');
field('Beim Klick', 'click', clickAction, { choices: { keine: 'Nichts tun', vergroessern: 'Bild vergrößern', link: 'Zu einer Adresse führen' }, onInput: showLinkOptions });
field('Linkziel', 'href', block.props.href || '', { container: linkOptions, help: 'Lokaler Pfad (/kontakt), Sprungmarke (#abschnitt) oder HTTPS-Adresse. Für ein Logo im Kopfbereich meist /.' });
showLinkOptions(clickAction); panel.append(linkOptions);
const picker = document.createElement('button'); picker.className = 'secondary'; picker.textContent = 'Bild aus Mediathek wählen';
picker.addEventListener('click', () => chooseMedia(false)); panel.append(picker);
const remove = document.createElement('button'); remove.type = 'button'; remove.className = 'text-button danger-text'; remove.textContent = 'Bild entfernen';