diff --git a/templates/index.html b/templates/index.html index ab7d1fe..1a963bf 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1297,7 +1297,6 @@ // Place items into their origin cell const occ = occupiedCells(); layoutItems.forEach((it, idx) => { - const cellIdx = it.x + ',' + it.y; const originCell = cont.querySelector(`[data-cell="${it.x + it.y * gridCols}"]`); const div = document.createElement('div'); @@ -1305,7 +1304,7 @@ div.className = 'grid-item'; if (it.w > 1 || it.h > 1) div.classList.add('span-2x2'); div.dataset.idx = idx; - div.draggable = true; + div.draggable = true; // legacy HTML5-DnD bleibt für Move; Resize nutzt separaten Handler // OOB marker const hasOOB = it.y + it.h > gridRows || it.x + it.w > gridCols || it.y < 0; @@ -1321,12 +1320,19 @@
`; - if (originCell) { - originCell.classList.add('occupied'); - originCell.appendChild(div); - } else { - cont.appendChild(div); - } + // BUG-03: Span-Geometrie per CSS Grid (grid-column/grid-row) statt + // per Cell-DOM-Anker. Item wird direkt in den Grid-Container gehängt, + // nicht in die Origin-Cell. Damit: + // - NxN-Items rendern visuell über NxN Cells + // - Drag-Events auf Nachbar-Cells werden nicht vom Item-DOM + // verschluckt (Item ist nicht mehr Kind der Cell) + // - Resize (applySize in startResizePointer) kann den Span nahtlos + // aktualisieren ohne den DOM-Anker zu wechseln + div.style.gridColumn = `${it.x + 1} / span ${it.w}`; + div.style.gridRow = `${it.y + 1} / span ${it.h}`; + cont.appendChild(div); + // Origin-Cell nur als "occupied" markieren, damit sie ihre leere Optik verliert + if (originCell) originCell.classList.add('occupied'); }); // Mark occupied cells diff --git a/tests/test_span_geometry.js b/tests/test_span_geometry.js new file mode 100644 index 0000000..04e0dce --- /dev/null +++ b/tests/test_span_geometry.js @@ -0,0 +1,56 @@ +// Test für BUG-03: Span-Geometrie im Initial-Render. +// +// Erwartung nach Fix: +// 1) renderGrid setzt grid-column/grid-row am Item direkt (per JS). +// 2) Item wird in den Container gehängt (cont.appendChild), nicht in originCell. +// 3) Origin-Cell bekommt nur die "occupied"-Klasse. +// 4) 2x2-Item hat style.gridColumn === ' / span 2' und gridRow === ' / span 2'. + +const fs = require('fs'); +const html = fs.readFileSync('templates/index.html', 'utf8'); +const js = html.match(/