ntm
This commit is contained in:
parent
d8f3fc991d
commit
928b1215f8
187
index.html
187
index.html
@ -193,24 +193,43 @@
|
|||||||
|
|
||||||
.definition-split {
|
.definition-split {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
inset: 0;
|
inset: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.definition-half {
|
.definition-half {
|
||||||
width: 50%;
|
height: 50%;
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
font-size: 5px;
|
font-size: 8px;
|
||||||
line-height: 6px;
|
line-height: 10px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
display:flex;
|
||||||
|
align-items:center;
|
||||||
|
justify-content:center;
|
||||||
|
font-variant: small-caps;
|
||||||
|
text-transform:uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.definition-half:first-child {
|
.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 */
|
/* Visual hint for hyphens: dotted border between cells */
|
||||||
.cell.hyphen {
|
.cell.hyphen {
|
||||||
border-right: 2px dotted #000;
|
border-right: 2px dotted #000;
|
||||||
@ -350,7 +369,9 @@
|
|||||||
|
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
<div id="grid" class="grid"></div>
|
<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="removeRow()">− Supprimer ligne</button>
|
||||||
<button class="btn-danger" onclick="removeColumn()">− Supprimer colonne</button>
|
<button class="btn-danger" onclick="removeColumn()">− Supprimer colonne</button>
|
||||||
</div>
|
</div>
|
||||||
@ -516,12 +537,20 @@
|
|||||||
// Gère le double-clic
|
// Gère le double-clic
|
||||||
function handleCellDoubleClick(row, col) {
|
function handleCellDoubleClick(row, col) {
|
||||||
const cell = grid[row][col];
|
const cell = grid[row][col];
|
||||||
cell.type = cell.type === 'letter' ? 'definition' : 'letter';
|
if (cell.type === 'letter' && !cell.letter) {
|
||||||
if (cell.type === 'letter') {
|
// empty letter -> become empty definition
|
||||||
|
cell.type = 'definition';
|
||||||
cell.definitionH = '';
|
cell.definitionH = '';
|
||||||
cell.definitionV = '';
|
cell.definitionV = '';
|
||||||
} else {
|
} else {
|
||||||
cell.letter = '';
|
// otherwise toggle
|
||||||
|
cell.type = cell.type === 'letter' ? 'definition' : 'letter';
|
||||||
|
if (cell.type === 'letter') {
|
||||||
|
cell.definitionH = '';
|
||||||
|
cell.definitionV = '';
|
||||||
|
} else {
|
||||||
|
cell.letter = '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
renderGrid();
|
renderGrid();
|
||||||
}
|
}
|
||||||
@ -558,6 +587,7 @@
|
|||||||
const btn = document.createElement('button');
|
const btn = document.createElement('button');
|
||||||
btn.className = 'definition-item';
|
btn.className = 'definition-item';
|
||||||
btn.textContent = def;
|
btn.textContent = def;
|
||||||
|
if (grid[row][col].definitionH === def) btn.classList.add('selected');
|
||||||
btn.onclick = () => {
|
btn.onclick = () => {
|
||||||
grid[row][col].definitionH = def;
|
grid[row][col].definitionH = def;
|
||||||
closeModal();
|
closeModal();
|
||||||
@ -593,6 +623,7 @@
|
|||||||
const btn = document.createElement('button');
|
const btn = document.createElement('button');
|
||||||
btn.className = 'definition-item';
|
btn.className = 'definition-item';
|
||||||
btn.textContent = def;
|
btn.textContent = def;
|
||||||
|
if (grid[row][col].definitionV === def) btn.classList.add('selected');
|
||||||
btn.onclick = () => {
|
btn.onclick = () => {
|
||||||
grid[row][col].definitionV = def;
|
grid[row][col].definitionV = def;
|
||||||
closeModal();
|
closeModal();
|
||||||
@ -893,83 +924,85 @@
|
|||||||
gridEl.appendChild(addRowLine);
|
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
|
||||||
// Clear any previous arrows
|
|
||||||
if (window._cellEls) {
|
if (window._cellEls) {
|
||||||
for (let r = 0; r < grid.length; r++) {
|
for (let r = 0; r < grid.length; r++) {
|
||||||
for (let c = 0; c < grid[0].length; c++) {
|
for (let c = 0; c < grid[0].length; c++) {
|
||||||
const el = window._cellEls[r] && window._cellEls[r][c];
|
const el = window._cellEls[r] && window._cellEls[r][c];
|
||||||
if (el) {
|
if (el) {
|
||||||
const prev = el.querySelector('.def-arrow');
|
const prev = el.querySelectorAll('.def-arrow');
|
||||||
if (prev) prev.remove();
|
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 dr = 0; dr < grid.length; dr++) {
|
||||||
for (let dc = 0; dc < grid[0].length; dc++) {
|
for (let dc = 0; dc < grid[0].length; dc++) {
|
||||||
const defCell = grid[dr][dc];
|
const defCell = grid[dr][dc];
|
||||||
if (defCell.type !== 'definition') continue;
|
if (defCell.type !== 'definition') continue;
|
||||||
|
|
||||||
// Horizontal-definition mapping
|
// Horizontal mapping: def at (dr,dc) -> word starts at (dr,dc+1) normally
|
||||||
if (defCell.definitionH) {
|
let trH = dr;
|
||||||
const tr = dr;
|
let tcH = dc + 1;
|
||||||
const tc = dc + 1;
|
// top-row special: horizontal definition maps to vertical word starting at (dr,dc+1)
|
||||||
if (tr >= 0 && tr < grid.length && tc >= 0 && tc < grid[0].length) {
|
let horizontalIsVertical = false;
|
||||||
const targetEl = window._cellEls[tr] && window._cellEls[tr][tc];
|
if (dr === 0) {
|
||||||
if (targetEl) {
|
horizontalIsVertical = true;
|
||||||
const arrow = document.createElement('div');
|
trH = dr;
|
||||||
arrow.className = 'def-arrow';
|
tcH = dc + 1;
|
||||||
// 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>';
|
if (defCell.definitionH && tcH < grid[0].length) {
|
||||||
arrow.style.position = 'absolute';
|
const targetEl = window._cellEls[trH] && window._cellEls[trH][tcH];
|
||||||
arrow.style.top = '2px';
|
if (targetEl) {
|
||||||
arrow.style.left = '50%';
|
const arrow = document.createElement('div');
|
||||||
arrow.style.transform = 'translateX(-50%)';
|
arrow.className = 'def-arrow';
|
||||||
} else {
|
if (horizontalIsVertical) {
|
||||||
// left-pointing arrow near left border
|
// arrow downwards from top 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.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.position = 'absolute';
|
arrow.style.top = '0px';
|
||||||
arrow.style.left = '4px';
|
arrow.style.left = '50%';
|
||||||
arrow.style.top = '50%';
|
arrow.style.transform = 'translateX(-50%)';
|
||||||
arrow.style.transform = 'translateY(-50%)';
|
} else {
|
||||||
}
|
// arrow pointing leftwards from left border into cell (originates from definition at left)
|
||||||
arrow.style.pointerEvents = 'none';
|
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.classList.add('def-arrow');
|
arrow.style.left = '0px';
|
||||||
targetEl.appendChild(arrow);
|
arrow.style.top = '50%';
|
||||||
|
arrow.style.transform = 'translateY(-50%)';
|
||||||
}
|
}
|
||||||
|
targetEl.appendChild(arrow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Vertical-definition mapping
|
// Vertical mapping: def at (dr,dc) -> word starts at (dr+1,dc) normally
|
||||||
if (defCell.definitionV) {
|
let trV = dr + 1;
|
||||||
const tr = dr + 1;
|
let tcV = dc;
|
||||||
const tc = dc;
|
// left-column special: vertical definition maps to horizontal word starting at (dr+1,dc)
|
||||||
if (tr >= 0 && tr < grid.length && tc >= 0 && tc < grid[0].length) {
|
let verticalIsHorizontal = false;
|
||||||
const targetEl = window._cellEls[tr] && window._cellEls[tr][tc];
|
if (dc === 0) {
|
||||||
if (targetEl) {
|
verticalIsHorizontal = true;
|
||||||
const arrow = document.createElement('div');
|
trV = dr + 1;
|
||||||
arrow.className = 'def-arrow';
|
tcV = dc;
|
||||||
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>';
|
if (defCell.definitionV && trV < grid.length) {
|
||||||
arrow.style.position = 'absolute';
|
const targetEl = window._cellEls[trV] && window._cellEls[trV][tcV];
|
||||||
arrow.style.left = '2px';
|
if (targetEl) {
|
||||||
arrow.style.top = '50%';
|
const arrow = document.createElement('div');
|
||||||
arrow.style.transform = 'translateY(-50%)';
|
arrow.className = 'def-arrow';
|
||||||
} else {
|
if (verticalIsHorizontal) {
|
||||||
// up-pointing arrow near top border
|
// arrow rightwards from left 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.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.position = 'absolute';
|
arrow.style.left = '0px';
|
||||||
arrow.style.top = '4px';
|
arrow.style.top = '50%';
|
||||||
arrow.style.left = '50%';
|
arrow.style.transform = 'translateY(-50%)';
|
||||||
arrow.style.transform = 'translateX(-50%)';
|
} else {
|
||||||
}
|
// arrow pointing upwards from top border? we want from definition to word, so arrow downwards from top border
|
||||||
arrow.style.pointerEvents = 'none';
|
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.classList.add('def-arrow');
|
arrow.style.top = '0px';
|
||||||
targetEl.appendChild(arrow);
|
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) => {
|
document.addEventListener('keydown', (e) => {
|
||||||
if (!activeCell || document.getElementById('gridScreen').style.display === 'none') return;
|
// don't intercept when modifier keys are pressed
|
||||||
|
if (e.ctrlKey || e.altKey || e.metaKey) return;
|
||||||
const { row, col } = activeCell;
|
if (document.getElementById('gridScreen').style.display === 'none') return;
|
||||||
|
|
||||||
|
// Toggle orientation with Tab when an active cell exists
|
||||||
if (e.key === 'Tab') {
|
if (e.key === 'Tab') {
|
||||||
|
if (!activeCell) return;
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
orientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';
|
orientation = orientation === 'horizontal' ? 'vertical' : 'horizontal';
|
||||||
renderGrid();
|
renderGrid();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!activeCell) return;
|
||||||
|
const { row, col } = activeCell;
|
||||||
|
|
||||||
if (e.key === 'Backspace') {
|
if (e.key === 'Backspace') {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
if (grid[row][col].letter) {
|
if (grid[row][col].letter) {
|
||||||
@ -1072,15 +1110,6 @@
|
|||||||
renderGrid();
|
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();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
22
mots.txt
22
mots.txt
@ -1,5 +1,27 @@
|
|||||||
chat: doux mais violent
|
chat: doux mais violent
|
||||||
|
chat: doux mais violent violent violent violent violent
|
||||||
chat: mais 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
|
plante: assoiffée de calme
|
||||||
président: affiné un mandat
|
président: affiné un mandat
|
||||||
président: affiné pour un mandat
|
président: affiné pour un mandat
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user