better notes

This commit is contained in:
Adrien MALINGREY 2020-10-21 21:26:10 +02:00
parent f97758f275
commit 661a25638e
3 changed files with 90 additions and 68 deletions

94
app.js
View File

@ -20,8 +20,9 @@ window.onload = function() {
if (!box.disabled) { if (!box.disabled) {
box.onfocus = onfocus box.onfocus = onfocus
box.oninput = oninput box.oninput = oninput
box.oncontextmenu = oncontextmenu box.onblur = onblur
} }
box.oncontextmenu = oncontextmenu
box.rowId = rowId box.rowId = rowId
box.columnId = columnId box.columnId = columnId
box.regionId = regionId box.regionId = regionId
@ -43,12 +44,12 @@ window.onload = function() {
highlightAndTab() highlightAndTab()
if (/Win/.test(navigator.platform) || /Linux/.test(navigator.platform)) accessKeyModifiers = "Alt+Maj+" if (/Win/.test(navigator.platform) || /Linux/.test(navigator.platform)) accessKeyModifiers = "Alt+Maj+"
else if (/Mac/.test(navigator.platform)) accessKeyModifiers = "⌃⌥ " else if (/Mac/.test(navigator.platform)) accessKeyModifiers = "⌃⌥"
for(node of document.querySelectorAll("*[accesskey]")) { for(node of document.querySelectorAll("*[accesskey]")) {
node.title += " [" + (node.accessKeyLabel || accessKeyModifiers + node.accessKey) + "]" node.title += " [" + (node.accessKeyLabel || accessKeyModifiers + node.accessKey) + "]"
} }
document.body.onclick = function (event) { document.onclick = function (event) {
contextMenu.style.display = "none" contextMenu.style.display = "none"
} }
suggestionTimer = setTimeout(showSuggestion, 30000) suggestionTimer = setTimeout(showSuggestion, 30000)
@ -60,31 +61,34 @@ function searchCandidatesOf(box) {
} }
function onfocus() { function onfocus() {
this.previousValue = this.value if (penStyle == "pencil" && this.value == "") {
this.select() this.value = this.placeholder
this.placeholder = ""
this.classList.add("pencil")
} else {
this.select()
}
} }
function oninput() { function oninput() {
history.push({box: this, value: this.previousValue, className: this.className}) history.push({box: this, value: this.previousValue, placeholder: this.previousPlaceholder})
undoButton.disabled = false undoButton.disabled = false
refresh(this) if (penStyle != "pencil") {
refresh(this)
}
} }
function undo() { function undo() {
if (history.length) { if (history.length) {
previousState = history.pop() previousState = history.pop()
previousState.box.value = previousState.value previousState.box.value = previousState.value
previousState.box.className = previousState.className previousState.box.placeholder = previousState.placeholder
refresh(previousState.box) refresh(previousState.box)
if (history.length < 1) undoButton.disabled = true if (history.length < 1) undoButton.disabled = true
} }
} }
function refresh(box) { function refresh(box) {
box.classList.remove("ink-pen", "pencil")
if (box.value.length)
box.classList.add(penStyle)
box.neighbourhood.concat([box]).forEach(neighbour => { box.neighbourhood.concat([box]).forEach(neighbour => {
searchCandidatesOf(neighbour) searchCandidatesOf(neighbour)
neighbour.setCustomValidity("") neighbour.setCustomValidity("")
@ -128,6 +132,16 @@ function refresh(box) {
} }
} }
function onblur() {
if (this.classList.contains("pencil")) {
this.placeholder = this.value
this.value = ""
this.classList.remove("pencil")
}
this.previousValue = this.value
this.previousPlaceholder = this.placeholder
}
function enableButtons() { function enableButtons() {
for (button of buttons.getElementsByTagName("button")) { for (button of buttons.getElementsByTagName("button")) {
if (boxes.filter(box => box.value == "").some(box => box.candidates.has(button.textContent))) { if (boxes.filter(box => box.value == "").some(box => box.candidates.has(button.textContent))) {
@ -209,28 +223,26 @@ function oncontextmenu(event) {
event.preventDefault() event.preventDefault()
while (contextMenu.firstChild) contextMenu.firstChild.remove() while (contextMenu.firstChild) contextMenu.firstChild.remove()
const box = event.target const box = event.target
if (box.value == "") { if (box.candidates.size) {
if (box.candidates.size) { candidatesArray = Array.from(box.candidates).sort().forEach(candidate => {
candidatesArray = Array.from(box.candidates).sort().forEach(candidate => {
li = document.createElement("li")
li.innerText = candidate
li.onclick = function (event) {
contextMenu.style.display = "none"
box.value = event.target.innerText
refresh(box)
}
contextMenu.appendChild(li)
})
} else {
li = document.createElement("li") li = document.createElement("li")
li.innerText = "Aucun chiffre possible" li.innerText = candidate
li.classList.add("error") li.onclick = function (event) {
contextMenu.style.display = "none"
box.value = event.target.innerText
oninput.apply(box)
}
contextMenu.appendChild(li) contextMenu.appendChild(li)
} })
contextMenu.style.left = `${event.pageX}px` } else {
contextMenu.style.top = `${event.pageY}px` li = document.createElement("li")
contextMenu.style.display = "block" li.innerText = "Aucun chiffre possible"
li.classList.add("error")
contextMenu.appendChild(li)
} }
contextMenu.style.left = `${event.pageX}px`
contextMenu.style.top = `${event.pageY}px`
contextMenu.style.display = "block"
return false return false
} }
@ -258,11 +270,23 @@ function erase(someBoxes) {
} }
function erasePencil() { function erasePencil() {
if (confirm("Effacer les chiffres écrits au crayon ?")) if (confirm("Effacer les chiffres écrits au crayon ?")) {
erase(grid.getElementsByClassName("pencil")) boxes.filter(box => !box.disabled).forEach(box => {
box.placeholder = ""
})
}
} }
function eraseAll() { function eraseAll() {
if (confirm("Effacer tous les chiffres (écrits au crayon et au stylo) ?")) if (confirm("Effacer tous les chiffres écrits au crayon et au stylo ?")) {
erase(boxes.filter(box => !box.disabled && box.value.length)) boxes.filter(box => !box.disabled).forEach(box => {
box.value = ""
box.placeholder = ""
box.setCustomValidity("")
box.required = false
})
boxes.forEach(searchCandidatesOf)
enableButtons()
highlightAndTab()
}
} }

View File

@ -19,6 +19,9 @@
<header> <header>
<h1>Sudoku</h1> <h1>Sudoku</h1>
</header> </header>
<section>
Remplissez la grille de sorte que chaque ligne, colonne et région (carré de 3×3 cases) contienne tous les chiffres de 1 à 9.
</section>
<form id='sudokuForm'> <form id='sudokuForm'>
<div> <div>
<table id='grid' class='grid'> <table id='grid' class='grid'>
@ -33,14 +36,12 @@
if ($value == UNKNOWN) { if ($value == UNKNOWN) {
$value = ""; $value = "";
$disabled = ""; $disabled = "";
$class = "ink-pen";
} else { } else {
$disabled = "disabled"; $disabled = "disabled";
$class = "";
} }
?> ?>
<td> <td>
<input type='number' min='1' max='9' step='1' value='<?=$value?>' title='Valeurs possibles [Clic-droit]' class="<?=$class?>" <?=$disabled?>/> <input type='number' min='1' max='9' step='1' value='<?=$value?>' title='Valeurs possibles [Clic-droit]' <?=$disabled?>/>
</td> </td>
<?php <?php
} }
@ -69,7 +70,7 @@
<button type='button' onclick='erasePencil()' title='Effacer le crayon'> <button type='button' onclick='erasePencil()' title='Effacer le crayon'>
<img src="img/pencil-eraser.png" alt="Gomme blanche" width=16 height=16/> <img src="img/pencil-eraser.png" alt="Gomme blanche" width=16 height=16/>
</button> </button>
<button type='button' onclick='eraseAll()' title='Effacer tout'> <button class="warning" type='button' onclick='eraseAll()' title='Effacer tout'>
<img src="img/ink-eraser.png" alt="Gomme bleue" width=16 height=16/> <img src="img/ink-eraser.png" alt="Gomme bleue" width=16 height=16/>
</button> </button>
<button id='undoButton' type='button' onclick='undo()' disabled title='Annuler' accesskey='z'> <button id='undoButton' type='button' onclick='undo()' disabled title='Annuler' accesskey='z'>
@ -78,9 +79,6 @@
<!--<input id='colorPicker' type='color' title='Changer de couleur de stylo' value='#00008b'/> --> <!--<input id='colorPicker' type='color' title='Changer de couleur de stylo' value='#00008b'/> -->
</div> </div>
</form> </form>
<section>
Remplissez la grille de sorte que chaque ligne, colonne et région (carré de 3×3 cases) contienne tous les chiffres de 1 à 9.
</section>
<ul id="contextMenu" class="context-menu"> <ul id="contextMenu" class="context-menu">
</ul> </ul>
<footer> <footer>

View File

@ -1,19 +1,21 @@
body { body {
font-family: sans-serif; font-family: sans-serif;
width: min-content;
margin: auto;
} }
h1 { h1 {
text-align: center; text-align: center;
margin: 0.5em; margin: 1rem;
} }
section, div, footer { section, div, footer {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
align-items: center; align-items: center;
row-gap: 0.5em; row-gap: 0.5rem;
column-gap: 0.5em; column-gap: 0.5rem;
margin: 0.8em auto; margin: 0.8rem auto;
justify-content: center; justify-content: center;
text-align: center; text-align: center;
} }
@ -72,9 +74,9 @@ section, div, footer {
} }
.grid input { .grid input {
width: 1.5em; width: 2.5rem;
height: 1.5em; height: 2.5rem;
font-size: 1.5em; font-size: 1.5rem;
border: 0; border: 0;
padding: 0; padding: 0;
text-align: center; text-align: center;
@ -91,6 +93,7 @@ input::-webkit-calendar-picker-indicator {
} }
.grid input:enabled { .grid input:enabled {
background: white; background: white;
color: darkblue;
} }
.grid input:disabled, button:enabled { .grid input:disabled, button:enabled {
color: white; color: white;
@ -110,17 +113,11 @@ input::-webkit-calendar-picker-indicator {
color: #ffff99 !important; color: #ffff99 !important;
background: #00cc66 !important; background: #00cc66 !important;
} }
input::placeholder { .grid input.pencil, input::placeholder {
color: #888; color: #888 !important;
} font-size: 1rem !important;
.grid input.ink-pen { width: 2.5rem !important;
color: darkblue; height: 2.5rem !important;
}
.grid input.pencil {
color: #888;
font-size: 0.8em;
width: 2.8em;
height: 2.8em;
} }
.highlight-buttons { .highlight-buttons {
@ -129,7 +126,7 @@ input::placeholder {
button, input[type="color"] { button, input[type="color"] {
border: 2px outset #6666ff; border: 2px outset #6666ff;
border-radius: 4px; border-radius: 4px;
font-size: 1.2em; font-size: 1.3rem;
padding: 4px 9px 5px 9px; padding: 4px 9px 5px 9px;
margin: 0px 1px 1px 1px; margin: 0px 1px 1px 1px;
} }
@ -139,7 +136,6 @@ button:enabled:hover {
padding: 5px 9px 5px 10px; padding: 5px 9px 5px 10px;
margin: 1px 1px 1px 2px; margin: 1px 1px 1px 2px;
} }
button:enabled:active,
button.pressed:enabled:hover { button.pressed:enabled:hover {
border-width: 3px; border-width: 3px;
border-style: inset; border-style: inset;
@ -152,11 +148,11 @@ button.pressed {
padding: 4px 8px 4px 9px; padding: 4px 8px 4px 9px;
margin: 1px 1px 0px 2px; margin: 1px 1px 0px 2px;
} }
button.pressed:enabled:active { button:enabled:active {
border-width: 4px; border-width: 4px !important;
border-style: inset; border-style: inset !important;
padding: 4px 4px 0px 9px; padding: 4px 4px 0px 9px !important;
margin: 0px 1px 0px 2px; margin: 0px 1px 0px 2px !important;
} }
button:disabled { button:disabled {
color: #666; color: #666;
@ -165,6 +161,10 @@ button:disabled {
padding: 5px 10px 6px 10px; padding: 5px 10px 6px 10px;
margin: 0px 1px 1px 1px; margin: 0px 1px 1px 1px;
} }
button.warning {
background: #ff5050;
border-color: #ff5050;
}
input[type="color"] { input[type="color"] {
padding: 0; padding: 0;
} }
@ -196,7 +196,7 @@ a {
list-style-type: none; list-style-type: none;
transition: all .3s ease; transition: all .3s ease;
user-select: none; user-select: none;
font-size: 0.8em; font-size: 1rem;
} }
.context-menu li:hover { .context-menu li:hover {