+
+
+
@@ -516,12 +537,20 @@
// Gère le double-clic
function handleCellDoubleClick(row, col) {
const cell = grid[row][col];
- cell.type = cell.type === 'letter' ? 'definition' : 'letter';
- if (cell.type === 'letter') {
+ if (cell.type === 'letter' && !cell.letter) {
+ // empty letter -> become empty definition
+ cell.type = 'definition';
cell.definitionH = '';
cell.definitionV = '';
} else {
- cell.letter = '';
+ // otherwise toggle
+ cell.type = cell.type === 'letter' ? 'definition' : 'letter';
+ if (cell.type === 'letter') {
+ cell.definitionH = '';
+ cell.definitionV = '';
+ } else {
+ cell.letter = '';
+ }
}
renderGrid();
}
@@ -558,6 +587,7 @@
const btn = document.createElement('button');
btn.className = 'definition-item';
btn.textContent = def;
+ if (grid[row][col].definitionH === def) btn.classList.add('selected');
btn.onclick = () => {
grid[row][col].definitionH = def;
closeModal();
@@ -593,6 +623,7 @@
const btn = document.createElement('button');
btn.className = 'definition-item';
btn.textContent = def;
+ if (grid[row][col].definitionV === def) btn.classList.add('selected');
btn.onclick = () => {
grid[row][col].definitionV = def;
closeModal();
@@ -893,83 +924,85 @@
gridEl.appendChild(addRowLine);
// After grid built, place arrows in the first-letter cells based on adjacent definition cells
- // Clear any previous arrows
if (window._cellEls) {
for (let r = 0; r < grid.length; r++) {
for (let c = 0; c < grid[0].length; c++) {
const el = window._cellEls[r] && window._cellEls[r][c];
if (el) {
- const prev = el.querySelector('.def-arrow');
- if (prev) prev.remove();
+ const prev = el.querySelectorAll('.def-arrow');
+ prev.forEach(p => p.remove());
}
}
}
- // For each definition cell, compute target first-letter cell and append arrow there
for (let dr = 0; dr < grid.length; dr++) {
for (let dc = 0; dc < grid[0].length; dc++) {
const defCell = grid[dr][dc];
if (defCell.type !== 'definition') continue;
- // Horizontal-definition mapping
- if (defCell.definitionH) {
- const tr = dr;
- const tc = dc + 1;
- if (tr >= 0 && tr < grid.length && tc >= 0 && tc < grid[0].length) {
- const targetEl = window._cellEls[tr] && window._cellEls[tr][tc];
- if (targetEl) {
- const arrow = document.createElement('div');
- arrow.className = 'def-arrow';
- // special top-row: curve down
- if (dr === 0) {
- arrow.innerHTML = '
';
- arrow.style.position = 'absolute';
- arrow.style.top = '2px';
- arrow.style.left = '50%';
- arrow.style.transform = 'translateX(-50%)';
- } else {
- // left-pointing arrow near left border
- arrow.innerHTML = '
';
- arrow.style.position = 'absolute';
- arrow.style.left = '4px';
- arrow.style.top = '50%';
- arrow.style.transform = 'translateY(-50%)';
- }
- arrow.style.pointerEvents = 'none';
- arrow.classList.add('def-arrow');
- targetEl.appendChild(arrow);
+ // Horizontal mapping: def at (dr,dc) -> word starts at (dr,dc+1) normally
+ let trH = dr;
+ let tcH = dc + 1;
+ // top-row special: horizontal definition maps to vertical word starting at (dr,dc+1)
+ let horizontalIsVertical = false;
+ if (dr === 0) {
+ horizontalIsVertical = true;
+ trH = dr;
+ tcH = dc + 1;
+ }
+
+ if (defCell.definitionH && tcH < grid[0].length) {
+ const targetEl = window._cellEls[trH] && window._cellEls[trH][tcH];
+ if (targetEl) {
+ const arrow = document.createElement('div');
+ arrow.className = 'def-arrow';
+ if (horizontalIsVertical) {
+ // arrow downwards from top border
+ arrow.innerHTML = '
';
+ arrow.style.top = '0px';
+ 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 = '
';
+ arrow.style.left = '0px';
+ arrow.style.top = '50%';
+ arrow.style.transform = 'translateY(-50%)';
}
+ targetEl.appendChild(arrow);
}
}
- // Vertical-definition mapping
- if (defCell.definitionV) {
- const tr = dr + 1;
- const tc = dc;
- if (tr >= 0 && tr < grid.length && tc >= 0 && tc < grid[0].length) {
- const targetEl = window._cellEls[tr] && window._cellEls[tr][tc];
- if (targetEl) {
- const arrow = document.createElement('div');
- arrow.className = 'def-arrow';
- if (dc === 0) {
- // left-edge special: curve right
- arrow.innerHTML = '
';
- arrow.style.position = 'absolute';
- arrow.style.left = '2px';
- arrow.style.top = '50%';
- arrow.style.transform = 'translateY(-50%)';
- } else {
- // up-pointing arrow near top border
- arrow.innerHTML = '
';
- arrow.style.position = 'absolute';
- arrow.style.top = '4px';
- arrow.style.left = '50%';
- arrow.style.transform = 'translateX(-50%)';
- }
- arrow.style.pointerEvents = 'none';
- arrow.classList.add('def-arrow');
- targetEl.appendChild(arrow);
+ // Vertical mapping: def at (dr,dc) -> word starts at (dr+1,dc) normally
+ let trV = dr + 1;
+ let tcV = dc;
+ // left-column special: vertical definition maps to horizontal word starting at (dr+1,dc)
+ let verticalIsHorizontal = false;
+ if (dc === 0) {
+ verticalIsHorizontal = true;
+ trV = dr + 1;
+ tcV = dc;
+ }
+
+ if (defCell.definitionV && trV < grid.length) {
+ const targetEl = window._cellEls[trV] && window._cellEls[trV][tcV];
+ if (targetEl) {
+ const arrow = document.createElement('div');
+ arrow.className = 'def-arrow';
+ if (verticalIsHorizontal) {
+ // arrow rightwards from left border
+ arrow.innerHTML = '
';
+ arrow.style.left = '0px';
+ 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 = '
';
+ arrow.style.top = '0px';
+ arrow.style.left = '50%';
+ arrow.style.transform = 'translateX(-50%)';
}
+ targetEl.appendChild(arrow);
}
}
}
@@ -977,19 +1010,24 @@
}
}
- // Gestion du clavier
+ // Gestion du clavier (saisie, navigation, suppression)
document.addEventListener('keydown', (e) => {
- if (!activeCell || document.getElementById('gridScreen').style.display === 'none') return;
-
- const { row, col } = activeCell;
-
+ // don't intercept when modifier keys are pressed
+ if (e.ctrlKey || e.altKey || e.metaKey) return;
+ if (document.getElementById('gridScreen').style.display === 'none') return;
+
+ // Toggle orientation with Tab when an active cell exists
if (e.key === 'Tab') {
+ if (!activeCell) return;
e.preventDefault();
orientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';
renderGrid();
return;
}
-
+
+ if (!activeCell) return;
+ const { row, col } = activeCell;
+
if (e.key === 'Backspace') {
e.preventDefault();
if (grid[row][col].letter) {
@@ -1014,27 +1052,27 @@
}
return;
}
-
+
if (e.key.startsWith('Arrow')) {
e.preventDefault();
let newRow = row;
let newCol = col;
-
+
if (e.key === 'ArrowUp') newRow = Math.max(0, row - 1);
if (e.key === 'ArrowDown') newRow = Math.min(grid.length - 1, row + 1);
if (e.key === 'ArrowLeft') newCol = Math.max(0, col - 1);
if (e.key === 'ArrowRight') newCol = Math.min(grid[0].length - 1, col + 1);
-
+
activeCell = { row: newRow, col: newCol };
renderGrid();
return;
}
-
+
if (e.key.length === 1 && /[a-zA-Z]/.test(e.key)) {
e.preventDefault();
-
+
if (grid[row][col].type !== 'letter') return;
-
+
// Crée automatiquement une case définition si nécessaire
if (orientation === 'horizontal' && col > 0) {
const prevCell = grid[row][col - 1];
@@ -1047,9 +1085,9 @@
prevCell.type = 'definition';
}
}
-
+
grid[row][col].letter = e.key.toUpperCase();
-
+
// Avance à la case suivante
if (orientation === 'horizontal' && col < grid[0].length - 1) {
let nextCol = col + 1;
@@ -1068,16 +1106,7 @@
activeCell = { row: nextRow, col };
}
}
-
- renderGrid();
- }
- });
- // Ensure tab toggles orientation even if focus is elsewhere
- document.addEventListener('keydown', (e) => {
- if (e.key === 'Tab') {
- e.preventDefault();
- orientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';
renderGrid();
}
});
diff --git a/mots.txt b/mots.txt
index 4d5fb89..43f2056 100644
--- a/mots.txt
+++ b/mots.txt
@@ -1,5 +1,27 @@
chat: doux mais violent
+chat: doux mais violent violent violent violent violent
chat: mais violent
+chat: mais violent
+chat: mais violenta
+chat: mais violentu
+chat: mais violenti
+chat: mais violente
+chat: mais violent,
+chat: mais violentc
+chat: mais violentt
+chat: mais violents
+chat: mais violentr
+chat: mais violentn
+chat: mais violentb
+chat: mais violenté
+chat: mais violentp
+chat: mais violento
+chat: mais violentè
+chat: mais violent
+chat: mais violentôv
+chat: mais violentd
+chat: mais violentl
+chat: mais violentj
plante: assoiffée de calme
président: affiné un mandat
président: affiné pour un mandat