Release v1.5.12

This commit is contained in:
2026-07-26 16:22:28 +01:00
parent ef9cdd2986
commit 4afaeaafb1
20 changed files with 563 additions and 1602 deletions
@@ -36,10 +36,26 @@
var regionCardTemplate = document.getElementById('region-card-template');
var regionsJsonInput = document.getElementById('regions-json');
var templateForm = document.getElementById('template-form');
var templateRegionUsageElement = document.getElementById('template-region-usage');
var regionUsageSet = new Set();
var draft = null;
var selectedIndex = -1;
var overlayRenderFrame = 0;
try {
var regionUsageData = JSON.parse((templateRegionUsageElement && templateRegionUsageElement.textContent) || '[]');
if (Array.isArray(regionUsageData)) {
regionUsageData.forEach(function (regionKey) {
var normalized = String(regionKey || '').trim();
if (normalized) {
regionUsageSet.add(normalized);
}
});
}
} catch (_error) {
regionUsageSet = new Set();
}
function escapeHtml(value) {
return utils.escapeHtml ? utils.escapeHtml(value) : String(value === undefined || value === null ? '' : value);
}
@@ -357,6 +373,21 @@
updateRegionLockBadge(card);
}
function setRegionRemovalState(card) {
var removeButton = card.querySelector('[data-region-remove-button]');
if (!removeButton) {
return;
}
var regionKey = String(card.dataset.regionKey || getRegionName(card) || '').trim();
var regionDeletionLocked = regionUsageSet.has(regionKey);
removeButton.disabled = regionDeletionLocked;
if (regionDeletionLocked) {
removeButton.title = 'Regions cannot be deleted while this template is used by slides.';
} else {
removeButton.removeAttribute('title');
}
}
function updateRegionLabel(card) {
var label = getRegionName(card) || 'Region';
var cards = getCards();
@@ -379,6 +410,8 @@
card.className = 'card card-outline card-secondary admin-form-card region-item mb-3';
}
populateRegionCard(card, region);
card.dataset.regionKey = String(region.region_key || region.label || getRegionName(card) || '').trim();
setRegionRemovalState(card);
var nameInput = card.querySelector('[name="region_name[]"]');
var lockRatioInput = card.querySelector('[name="region_lock_ratio[]"]');
var widthInput = card.querySelector('[name="region_width[]"]');
@@ -415,12 +448,12 @@
});
}
card.addEventListener('click', function (event) {
if (event.target && event.target.classList && event.target.classList.contains('remove-region')) {
if (event.target && event.target.closest && event.target.closest('[data-region-remove-button]')) {
return;
}
setSelected(getCards().indexOf(card));
});
card.querySelector('.remove-region').addEventListener('click', function (event) {
card.querySelector('[data-region-remove-button]').addEventListener('click', function (event) {
event.preventDefault();
card.remove();
if (!getCards().length) {
@@ -523,7 +556,9 @@
if (hint) {
hint.remove();
}
regionList.appendChild(makeRegionCard(region));
var card = makeRegionCard(region);
setRegionRemovalState(card);
regionList.appendChild(card);
setSelected(getCards().length - 1);
}
@@ -600,8 +635,12 @@
var currentPoint = toCanvasPoint(moveEvent);
var dx = currentPoint.x - startPoint.x;
var dy = currentPoint.y - startPoint.y;
var next = clampRegion({ x: startRegion.x + dx, y: startRegion.y + dy, width: startRegion.width, height: startRegion.height });
writeCard(cardAt(index), { x: next.x, y: next.y });
var size = getCanvasSize();
var maxX = Math.max(0, size.width - startRegion.width);
var maxY = Math.max(0, size.height - startRegion.height);
var nextX = clamp(startRegion.x + dx, 0, maxX);
var nextY = clamp(startRegion.y + dy, 0, maxY);
writeCard(cardAt(index), { x: nextX, y: nextY, width: startRegion.width, height: startRegion.height });
requestOverlayRender();
}
function upHandler() {
@@ -617,6 +656,24 @@
var startRegion = readCard(cardAt(index));
var lockRatio = normalizeLockRatio(startRegion.lock_ratio);
var aspect = lockRatio ? parseLockRatio(lockRatio) : null;
var canvasSize = getCanvasSize();
var minSize = 12;
function clampResizeDelta(dx, dy) {
if (dir.indexOf('w') !== -1) {
dx = clamp(dx, -startRegion.x, startRegion.width - minSize);
}
if (dir.indexOf('e') !== -1) {
dx = clamp(dx, minSize - startRegion.width, canvasSize.width - startRegion.x - startRegion.width);
}
if (dir.indexOf('n') !== -1) {
dy = clamp(dy, -startRegion.y, startRegion.height - minSize);
}
if (dir.indexOf('s') !== -1) {
dy = clamp(dy, minSize - startRegion.height, canvasSize.height - startRegion.y - startRegion.height);
}
return { dx: dx, dy: dy };
}
function fitFromWidth(width) {
var nextWidth = Math.max(12, Math.round(width));
@@ -638,6 +695,9 @@
var currentPoint = toCanvasPoint(moveEvent);
var dx = currentPoint.x - startPoint.x;
var dy = currentPoint.y - startPoint.y;
var constrainedDelta = clampResizeDelta(dx, dy);
dx = constrainedDelta.dx;
dy = constrainedDelta.dy;
var next = { x: startRegion.x, y: startRegion.y, width: startRegion.width, height: startRegion.height };
if (aspect) {
if (dir === 'e') {
@@ -748,7 +808,6 @@
}
event.preventDefault();
setSelected(-1);
startDraw(event);
});
if (templateForm) {
templateForm.addEventListener('formdata', function (event) {