This commit is contained in:
Axce 2026-01-02 05:27:53 +01:00
parent 928b1215f8
commit 60f900740f

View File

@ -14,7 +14,8 @@
body {
font-family: Arial, sans-serif;
background-color: #f3f4f6;
padding: 20px;
padding: 28px;
font-size: 18px;
}
.container {
@ -87,11 +88,6 @@
width: 100%;
}
.btn-primary:hover {
background-color: #1d4ed8;
}
.btn-success {
background-color: #16a34a;
color: white;
}
@ -145,8 +141,8 @@
}
.cell {
width: 40px;
height: 40px;
width: 56px;
height: 56px;
border: 1px solid #6b7280;
position: relative;
cursor: pointer;
@ -177,7 +173,7 @@
display: flex;
align-items: center;
justify-content: center;
font-size: 20px;
font-size: 22px;
font-weight: bold;
}
@ -202,8 +198,8 @@
height: 50%;
position: relative;
padding: 2px;
font-size: 8px;
line-height: 10px;
font-size: 7px;
line-height: 8px;
overflow: hidden;
word-wrap: break-word;
display:flex;
@ -220,7 +216,7 @@
.definition-text {
font-variant: small-caps;
text-transform:uppercase;
font-size:10px;
font-size:9px;
display:flex;
align-items:center;
justify-content:center;
@ -369,9 +365,10 @@
<div class="grid-container">
<div id="grid" class="grid"></div>
<div style="display:flex;gap:8px;margin-top:12px;">
<button class="btn-success" onclick="addRow()">+ Ajouter ligne</button>
<button class="btn-success" onclick="addColumn()">+ Ajouter colonne</button>
<div style="display:flex;gap:8px;margin-top:12px;align-items:center;">
<button class="btn-success" onclick="addRow()">Ajouter ligne</button>
<button class="btn-success" onclick="addColumn()">Ajouter colonne</button>
<button class="btn-primary" onclick="transformActiveToDefinition()">Transformer cellule active en définition</button>
<button class="btn-danger" onclick="removeRow()"> Supprimer ligne</button>
<button class="btn-danger" onclick="removeColumn()"> Supprimer colonne</button>
</div>
@ -596,6 +593,28 @@
sectionH.appendChild(btn);
});
}
// Custom input for horizontal definition
const customH = document.createElement('div');
customH.style.display = 'flex';
customH.style.gap = '8px';
customH.style.marginTop = '8px';
const inputH = document.createElement('input');
inputH.type = 'text';
inputH.value = grid[row][col].definitionH || '';
inputH.style.flex = '1';
const saveH = document.createElement('button');
saveH.className = 'btn-primary';
saveH.textContent = 'Enregistrer (H)';
saveH.onclick = () => {
grid[row][col].definitionH = inputH.value.trim();
closeModal();
renderGrid();
};
inputH.addEventListener('keydown', (ev) => { if (ev.key === 'Enter') { ev.preventDefault(); saveH.click(); } });
customH.appendChild(inputH);
customH.appendChild(saveH);
sectionH.appendChild(customH);
}
const sectionV = document.createElement('div');
@ -632,6 +651,28 @@
sectionV.appendChild(btn);
});
}
// Custom input for vertical definition
const customV = document.createElement('div');
customV.style.display = 'flex';
customV.style.gap = '8px';
customV.style.marginTop = '8px';
const inputV = document.createElement('input');
inputV.type = 'text';
inputV.value = grid[row][col].definitionV || '';
inputV.style.flex = '1';
const saveV = document.createElement('button');
saveV.className = 'btn-primary';
saveV.textContent = 'Enregistrer (V)';
saveV.onclick = () => {
grid[row][col].definitionV = inputV.value.trim();
closeModal();
renderGrid();
};
inputV.addEventListener('keydown', (ev) => { if (ev.key === 'Enter') { ev.preventDefault(); saveV.click(); } });
customV.appendChild(inputV);
customV.appendChild(saveV);
sectionV.appendChild(customV);
}
// Delete button: transforms case into letter empty
@ -755,6 +796,24 @@
renderGrid();
}
function transformActiveToDefinition() {
if (!activeCell) {
alert('Aucune cellule active sélectionnée.');
return;
}
const { row, col } = activeCell;
const cell = grid[row][col];
if (cell.type === 'definition') return;
if (cell.letter || cell.definitionH || cell.definitionV) {
if (!confirm('La transformation effacera la lettre actuelle et/ou définitions existantes. Confirmer ?')) return;
}
cell.type = 'definition';
cell.letter = '';
cell.definitionH = '';
cell.definitionV = '';
renderGrid();
}
// Ajoute une colonne
function addColumn() {
grid.forEach((row, rowIndex) => {
@ -912,16 +971,7 @@
gridEl.appendChild(rowEl);
});
// Ligne d'ajout
const addRowLine = document.createElement('div');
addRowLine.className = 'add-row-controls';
for (let i = 0; i < grid[0].length; i++) {
const addBtn = document.createElement('div');
addBtn.className = 'add-col-control';
addBtn.innerHTML = '<button class="add-btn" onclick="addRow()">+</button>';
addRowLine.appendChild(addBtn);
}
gridEl.appendChild(addRowLine);
// No per-cell + buttons (global controls only)
// After grid built, place arrows in the first-letter cells based on adjacent definition cells
if (window._cellEls) {
@ -959,13 +1009,13 @@
if (horizontalIsVertical) {
// arrow downwards from top border
arrow.innerHTML = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1"><path d="M12 3 L12 18"/><path d="M12 18 L8 14 M12 18 L16 14"/></svg>';
arrow.style.top = '0px';
arrow.style.top = '-10px';
arrow.style.left = '50%';
arrow.style.transform = 'translateX(-50%)';
} else {
// arrow pointing leftwards from left border into cell (originates from definition at left)
arrow.innerHTML = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1"><path d="M3 12 L18 12"/><path d="M18 12 L14 8 M18 12 L14 16"/></svg>';
arrow.style.left = '0px';
arrow.style.left = '-10px';
arrow.style.top = '50%';
arrow.style.transform = 'translateY(-50%)';
}
@ -992,13 +1042,13 @@
if (verticalIsHorizontal) {
// arrow rightwards from left border
arrow.innerHTML = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1"><path d="M3 12 L18 12"/><path d="M18 12 L14 8 M18 12 L14 16"/></svg>';
arrow.style.left = '0px';
arrow.style.left = '-10px';
arrow.style.top = '50%';
arrow.style.transform = 'translateY(-50%)';
} else {
// arrow pointing upwards from top border? we want from definition to word, so arrow downwards from top border
arrow.innerHTML = '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1"><path d="M12 3 L12 18"/><path d="M12 18 L8 14 M12 18 L16 14"/></svg>';
arrow.style.top = '0px';
arrow.style.top = '-10px';
arrow.style.left = '50%';
arrow.style.transform = 'translateX(-50%)';
}
@ -1028,6 +1078,26 @@
if (!activeCell) return;
const { row, col } = activeCell;
// Enter: transform empty letter into definition (or open modal if definition exists)
if (e.key === 'Enter') {
e.preventDefault();
if (grid[row][col].type === 'letter' && !grid[row][col].letter) {
transformActiveToDefinition();
return;
}
if (grid[row][col].type === 'definition') {
// open modal for this definition
const wordInfoH = (row === 0) ? getWordAt(row, col + 1, 'vertical') : getWordAt(row, col + 1, 'horizontal');
const wordInfoV = (col === 0) ? getWordAt(row + 1, col, 'horizontal') : getWordAt(row + 1, col, 'vertical');
const wordH = (wordInfoH && wordInfoH.word) ? wordInfoH.word : null;
const wordV = (wordInfoV && wordInfoV.word) ? wordInfoV.word : null;
const defsH = wordH ? ([...new Set(dictionaries[normalizeWord(wordH)] || [])]) : [];
const defsV = wordV ? ([...new Set(dictionaries[normalizeWord(wordV)] || [])]) : [];
showDefinitionModal(row, col, wordH, defsH, wordV, defsV);
return;
}
}
if (e.key === 'Backspace') {
e.preventDefault();
if (grid[row][col].letter) {