<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />

    <title>preval</title>
    <link href="/favicon.png" rel="icon" type="image/png" />

    <style>
html, body, main {
  font-family: "Courier New";
  height: 100%;
  margin: 0;
  padding: 0;
  width: 100%;
}

main {
  display: flex;
}

textarea {
  background-color: black;
  box-sizing: border-box;
  color: white;
  font-family: inherit;
  resize: none;
}

textarea, code {
  flex-basis: 50%;
  font-size: 18px;
  padding: .5em;
}
    </style>
  </head>
  <body>
    <main>
      <textarea placeholder="Enter Ruby code..."></textarea>
      <code></code>
    </main>
    <script>
(() => {
  const textarea = document.querySelector("textarea");
  const code = document.querySelector("code");

  const fetchCode = () => {
    var xhr = new XMLHttpRequest();
    xhr.open("POST", "/", true);

    xhr.onreadystatechange = () => {
      if (xhr.readyState === XMLHttpRequest.DONE) {
        code.innerText = xhr.status === 200 ? xhr.responseText : "";
      }
    };

    xhr.send(textarea.value);
  };

  let timeout = 0;

  textarea.addEventListener("input", () => {
    clearTimeout(timeout);
    timeout = setTimeout(fetchCode, 300);
  });

  const handleTab = event => {
    event.preventDefault();

    const { selectionStart, selectionEnd, value } = textarea;

    const preSpace = value.substring(0, selectionStart);
    const postSpace = value.substring(selectionEnd);

    textarea.value = `${preSpace}  ${postSpace}`;
    textarea.selectionStart = textarea.selectionEnd = selectionStart + 2;
  };

  const indentLine = line => `  ${line}`;
  const dedentLine = line => {
    if (line.startsWith("  ")) {
      return line.slice(2);
    }
    if (line.startsWith(" ")) {
      return line.slice(1);
    }
    return line;
  };

  const handleDent = event => {
    event.preventDefault();

    const { selectionStart, selectionEnd, value } = textarea;
    const lines = value.split("\n");

    let currentStart = selectionStart;
    let currentEnd = selectionEnd;
    let startLine = null;
    let endLine = null;

    for (let lineIdx = 0; lineIdx < lines.length; lineIdx += 1) {
      currentStart -= (lines[lineIdx].length + 1);
      if (startLine === null && currentStart < 0) {
        startLine = lineIdx;
      }

      currentEnd -= (lines[lineIdx].length + 1);
      if (endLine === null && currentEnd < 0) {
        endLine = lineIdx;
      }

      if (currentStart < 0 && currentEnd < 0) {
        break;
      }
    }

    const nextLines = (
      lines.slice(0, startLine)
        .concat(lines.slice(startLine, endLine + 1).map(
          event.key === "]" ? indentLine : dedentLine
        ))
        .concat(lines.slice(endLine + 1))
    );

    textarea.value = nextLines.join("\n");

    const buffer = nextLines.slice(0, startLine + 1).join("\n").length;
    textarea.selectionStart = textarea.selectionEnd = (
      buffer + currentStart + 1
    );
  };

  textarea.addEventListener("keydown", event => {
    if (event.key === "Tab") {
      handleTab(event);
    } else if (["[", "]"].includes(event.key) && event.metaKey) {
      handleDent(event);
    }
  });
})();
    </script>
  </body>
</html>