wesh
This commit is contained in:
parent
928b1215f8
commit
60f900740f
128
index.html
128
index.html
@ -14,7 +14,8 @@
|
|||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
background-color: #f3f4f6;
|
background-color: #f3f4f6;
|
||||||
padding: 20px;
|
padding: 28px;
|
||||||
|
font-size: 18px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
@ -87,11 +88,6 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary:hover {
|
|
||||||
background-color: #1d4ed8;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-success {
|
|
||||||
background-color: #16a34a;
|
background-color: #16a34a;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
@ -145,8 +141,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cell {
|
.cell {
|
||||||
width: 40px;
|
width: 56px;
|
||||||
height: 40px;
|
height: 56px;
|
||||||
border: 1px solid #6b7280;
|
border: 1px solid #6b7280;
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -177,7 +173,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
font-size: 20px;
|
font-size: 22px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +198,8 @@
|
|||||||
height: 50%;
|
height: 50%;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
font-size: 8px;
|
font-size: 7px;
|
||||||
line-height: 10px;
|
line-height: 8px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
display:flex;
|
display:flex;
|
||||||
@ -220,7 +216,7 @@
|
|||||||
.definition-text {
|
.definition-text {
|
||||||
font-variant: small-caps;
|
font-variant: small-caps;
|
||||||
text-transform:uppercase;
|
text-transform:uppercase;
|
||||||
font-size:10px;
|
font-size:9px;
|
||||||
display:flex;
|
display:flex;
|
||||||
align-items:center;
|
align-items:center;
|
||||||
justify-content:center;
|
justify-content:center;
|
||||||
@ -369,9 +365,10 @@
|
|||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div id="grid" class="grid"></div>
|
<div id="grid" class="grid"></div>
|
||||||
<div style="display:flex;gap:8px;margin-top:12px;">
|
<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="addRow()">Ajouter ligne</button>
|
||||||
<button class="btn-success" onclick="addColumn()">+ Ajouter colonne</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="removeRow()">− Supprimer ligne</button>
|
||||||
<button class="btn-danger" onclick="removeColumn()">− Supprimer colonne</button>
|
<button class="btn-danger" onclick="removeColumn()">− Supprimer colonne</button>
|
||||||
</div>
|
</div>
|
||||||
@ -596,6 +593,28 @@
|
|||||||
sectionH.appendChild(btn);
|
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');
|
const sectionV = document.createElement('div');
|
||||||
@ -632,6 +651,28 @@
|
|||||||
sectionV.appendChild(btn);
|
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
|
// Delete button: transforms case into letter empty
|
||||||
@ -755,6 +796,24 @@
|
|||||||
renderGrid();
|
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
|
// Ajoute une colonne
|
||||||
function addColumn() {
|
function addColumn() {
|
||||||
grid.forEach((row, rowIndex) => {
|
grid.forEach((row, rowIndex) => {
|
||||||
@ -912,16 +971,7 @@
|
|||||||
gridEl.appendChild(rowEl);
|
gridEl.appendChild(rowEl);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Ligne d'ajout
|
// No per-cell + buttons (global controls only)
|
||||||
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);
|
|
||||||
|
|
||||||
// After grid built, place arrows in the first-letter cells based on adjacent definition cells
|
// After grid built, place arrows in the first-letter cells based on adjacent definition cells
|
||||||
if (window._cellEls) {
|
if (window._cellEls) {
|
||||||
@ -959,13 +1009,13 @@
|
|||||||
if (horizontalIsVertical) {
|
if (horizontalIsVertical) {
|
||||||
// arrow downwards from top border
|
// 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.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.left = '50%';
|
||||||
arrow.style.transform = 'translateX(-50%)';
|
arrow.style.transform = 'translateX(-50%)';
|
||||||
} else {
|
} else {
|
||||||
// arrow pointing leftwards from left border into cell (originates from definition at left)
|
// 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.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.top = '50%';
|
||||||
arrow.style.transform = 'translateY(-50%)';
|
arrow.style.transform = 'translateY(-50%)';
|
||||||
}
|
}
|
||||||
@ -992,13 +1042,13 @@
|
|||||||
if (verticalIsHorizontal) {
|
if (verticalIsHorizontal) {
|
||||||
// arrow rightwards from left border
|
// 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.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.top = '50%';
|
||||||
arrow.style.transform = 'translateY(-50%)';
|
arrow.style.transform = 'translateY(-50%)';
|
||||||
} else {
|
} else {
|
||||||
// arrow pointing upwards from top border? we want from definition to word, so arrow downwards from top border
|
// 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.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.left = '50%';
|
||||||
arrow.style.transform = 'translateX(-50%)';
|
arrow.style.transform = 'translateX(-50%)';
|
||||||
}
|
}
|
||||||
@ -1028,6 +1078,26 @@
|
|||||||
if (!activeCell) return;
|
if (!activeCell) return;
|
||||||
const { row, col } = activeCell;
|
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') {
|
if (e.key === 'Backspace') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (grid[row][col].letter) {
|
if (grid[row][col].letter) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user