This commit is contained in:
Axce 2026-01-02 05:09:04 +01:00
parent d8f3fc991d
commit 928b1215f8
2 changed files with 140 additions and 89 deletions

View File

@ -193,24 +193,43 @@
.definition-split {
display: flex;
flex-direction: column;
position: absolute;
inset: 0;
}
.definition-half {
width: 50%;
height: 50%;
position: relative;
padding: 2px;
font-size: 5px;
line-height: 6px;
font-size: 8px;
line-height: 10px;
overflow: hidden;
word-wrap: break-word;
display:flex;
align-items:center;
justify-content:center;
font-variant: small-caps;
text-transform:uppercase;
}
.definition-half:first-child {
border-right: 1px solid #6b7280;
border-bottom: 1px solid #6b7280;
}
.definition-text {
font-variant: small-caps;
text-transform:uppercase;
font-size:10px;
display:flex;
align-items:center;
justify-content:center;
}
.definition-item.selected { background-color: #fde68a; }
.def-arrow { position:absolute; pointer-events:none; }
/* Visual hint for hyphens: dotted border between cells */
.cell.hyphen {
border-right: 2px dotted #000;
@ -350,7 +369,9 @@
<div class="grid-container">
<div id="grid" class="grid"></div>
<div class="controls">
<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>
<button class="btn-danger" onclick="removeRow()"> Supprimer ligne</button>
<button class="btn-danger" onclick="removeColumn()"> Supprimer colonne</button>
</div>
@ -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 = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1" class="arrow-down-curved"><path d="M12 0 C12 0 12 6 12 6 L12 16"/><path d="M12 16 L9 13 M12 16 L15 13"/></svg>';
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 = '<svg width="12" height="12" viewBox="0 0 8 8" fill="none" stroke="black" stroke-width="1"><path d="M6 1 L2 4 L6 7"/></svg>';
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 = '<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.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.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 = '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="1"><path d="M0 12 C0 12 6 12 6 12 L16 12"/><path d="M16 12 L13 9 M16 12 L13 15"/></svg>';
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 = '<svg width="12" height="12" viewBox="0 0 8 8" fill="none" stroke="black" stroke-width="1"><path d="M1 6 L4 2 L7 6"/></svg>';
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 = '<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.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.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();
}
});

View File

@ -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