better editor features:

* statusbar with percent scrolled and `row:col` info
* current line highlights
feature/strict-mode
Michael Ochmann 3 years ago
parent 549c6baa96
commit af61963440
  1. 84
      playground/index.php

@ -11,19 +11,44 @@
return elements.length < 2 ? elements[0] : elements; return elements.length < 2 ? elements[0] : elements;
}; };
const output = $("#output"); const output = $("#output");
const input = $("#input"); const input = $("#input");
const numbers = $(".linenumbers"); const numbers = $(".linenumbers");
let timeout; const position = $("#position");
const percent = $("#percent");
const editor = $(".editor");
let lastLine = 1;
let timeout;
let lastSelection;
const onLineChange = event => {
const start = input.selectionStart;
if (start === lastSelection)
return;
const linesToCursor = input.value.substr(0, start).split("\n");
const currentLine = linesToCursor.length;
const char = linesToCursor[linesToCursor.length - 1].length;
const ll = $(`#line_${lastLine}`);
if (ll)
ll.classList.remove("active");
$(`#line_${currentLine}`).classList.add("active");
position.innerHTML = `[${currentLine}:${char}]`;
lastLine = currentLine;
lastSelection = start;
}
const updateOutput = (event) => { const updateOutput = (event) => {
const text = event ? event.target.value : input.value; const text = event ? event.target.value : input.value;
const lines = text.split("\n").length; const lines = text.split("\n").length;
let html = ""; let html = "";
for (let i = 1; i <= lines; i++) { for (let i = 1; i <= lines; i++) {
html += `${i}<br>`; html += `<span id="line_${i}">${i}</span>`;
} }
numbers.innerHTML = html; numbers.innerHTML = html;
onLineChange();
timeout = setTimeout(() => { timeout = setTimeout(() => {
@ -40,6 +65,9 @@
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
updateOutput(); updateOutput();
for (event of ["click", "change", "keydown", "focus"])
input.addEventListener(event, () => onLineChange());
input.addEventListener("keydown", event => { input.addEventListener("keydown", event => {
if (event.key !== "Tab") if (event.key !== "Tab")
return; return;
@ -56,6 +84,16 @@
clearTimeout(timeout); clearTimeout(timeout);
updateOutput(event); updateOutput(event);
}); });
editor.addEventListener("scroll", () => {
const height = input.clientHeight - editor.clientHeight;
const top = editor.scrollTop;
const fromTop = Math.min(100, Math.max(0, Math.round(top * 100 / height)));
percent.innerHTML = `${fromTop}%`;
console.log("SCROOLLL", fromTop, height, top);
});
}); });
window.highlight = (col, row) => { window.highlight = (col, row) => {
@ -102,6 +140,7 @@
body { body {
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
grid-template-rows: auto 30px;
font-family: sans-serif; font-family: sans-serif;
margin: 0; margin: 0;
padding: 0; padding: 0;
@ -146,28 +185,57 @@
height: 100%; height: 100%;
border-right: none; border-right: none;
overflow-y: auto; overflow-y: auto;
border-bottom: none;
overflow-x: hidden; overflow-x: hidden;
} }
.linenumbers { .linenumbers {
font-size: 1.2rem; font-size: 1.2rem;
text-align: right; text-align: right;
padding: 1rem; padding: 1rem 0;
color: #aaa; color: #aaa;
font-family: monospace; font-family: monospace;
background: #222; background: #222;
} }
.linenumbers span {
display: block;
padding: 0 1rem;
}
.linenumbers span.active {
color: yellow;
background: rgba(255,255,255,0.05);
}
.statusbar {
font-size: 0.6rem;
line-height: 30px;
padding: 0 1rem;
background: rgba(0,0,0,0.2);
text-align: right;
border: none;
color: #888;
}
#position {
color: dodgerblue;
font-weight: bold;
}
#output { #output {
overflow-y: auto; overflow-y: auto;
padding: 4rem; padding: 4rem;
max-width: 100%; max-width: 100%;
grid-row: span 2;
} }
#output code { #output code {
word-break: break-word; word-break: break-word;
white-space: break-spaces; white-space: break-spaces;
} }
#output table {
width: 100%;
}
#output img { #output img {
max-width: 100%; max-width: 100%;
height: auto; height: auto;
@ -395,6 +463,10 @@ Unit tests can be run via `composer`:
</textarea> </textarea>
</section> </section>
<section id="output"></section> <section id="output"></section>
<section class="statusbar">
<span id="percent">0%</span>
<span id="position">[1:2]</span>
</section>
</body> </body>
</html> </html>
Loading…
Cancel
Save