diff --git a/playground/index.php b/playground/index.php
index b0f6f63..a2fbc10 100644
--- a/playground/index.php
+++ b/playground/index.php
@@ -11,19 +11,44 @@
return elements.length < 2 ? elements[0] : elements;
};
- const output = $("#output");
- const input = $("#input");
- const numbers = $(".linenumbers");
- let timeout;
+ const output = $("#output");
+ const input = $("#input");
+ const numbers = $(".linenumbers");
+ 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 text = event ? event.target.value : input.value;
const lines = text.split("\n").length;
let html = "";
for (let i = 1; i <= lines; i++) {
- html += `${i}
`;
+ html += `${i}`;
}
numbers.innerHTML = html;
+ onLineChange();
timeout = setTimeout(() => {
@@ -40,6 +65,9 @@
document.addEventListener("DOMContentLoaded", () => {
updateOutput();
+ for (event of ["click", "change", "keydown", "focus"])
+ input.addEventListener(event, () => onLineChange());
+
input.addEventListener("keydown", event => {
if (event.key !== "Tab")
return;
@@ -56,6 +84,16 @@
clearTimeout(timeout);
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) => {
@@ -102,6 +140,7 @@
body {
display: grid;
grid-template-columns: 1fr 1fr;
+ grid-template-rows: auto 30px;
font-family: sans-serif;
margin: 0;
padding: 0;
@@ -146,28 +185,57 @@
height: 100%;
border-right: none;
overflow-y: auto;
+ border-bottom: none;
overflow-x: hidden;
}
.linenumbers {
font-size: 1.2rem;
text-align: right;
- padding: 1rem;
+ padding: 1rem 0;
color: #aaa;
font-family: monospace;
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 {
overflow-y: auto;
padding: 4rem;
max-width: 100%;
+ grid-row: span 2;
}
#output code {
word-break: break-word;
white-space: break-spaces;
}
+ #output table {
+ width: 100%;
+ }
+
#output img {
max-width: 100%;
height: auto;
@@ -395,6 +463,10 @@ Unit tests can be run via `composer`:
+