function highlightedtextarea(config = {}) {
let {value, autocomplete, height="200px", width="100%", maxlength, placeholder, spellcheck, wrap, language="html", tabsize=2} = config;
if (typeof config == "string") value = config;
if (value == null) value = "";
const form = input({
form: html`
<form style="height: ${height}">
<textarea style="display: block; font-size: 0.8em; position: absolute; top: 0; left: 0; z-index: 1; margin: 10px; padding: 10px; border: 1; color: transparent; background: transparent; caret-color: black; overflow: auto; white-space: pre-wrap; resize: none; font: 17px/1.5 monospace; tab-size: ${tabsize}; width: calc(${width} - 32px); height: calc(${height} - 50px);" name=input>${value}</textarea>
<pre aria-hidden="true" style="display: block; font-size: 0.8em; position: absolute; top: 0; left: 0; z-index: 0; margin: 10px; padding: 10px; border: 0; overflow: auto; white-space: pre-wrap; font: 17px/1.5 monospace; tab-size: ${tabsize}; width: calc(${width} - 32px); height: calc(${height} - 50px);"><code class="language-${language}" style="font: 17px/1.5 monospace;">${value.replace(new RegExp("&", "g"), "&").replace(new RegExp("<", "g"), "<")}</code>
</pre>
</form>`,
attributes: {autocomplete, maxlength, placeholder, spellcheck, wrap}
});
Prism.highlightAllUnder(form);
form.output.remove();
form.oninput = (e => {
let text = e.target.value;
let result_element = e.target.parentElement.querySelector("pre > code");
if (text[text.length-1] == "\n") text += " ";
result_element.innerHTML = text.replace(new RegExp("&", "g"), "&").replace(new RegExp("<", "g"), "<");
Prism.highlightElement(result_element);
sync_scroll(e);
})
form.querySelector("textarea").onscroll = sync_scroll;
function sync_scroll(e) {
let result_element = e.target.parentElement.querySelector("pre");
result_element.scrollTop = e.target.scrollTop;
result_element.scrollLeft = e.target.scrollLeft;
}
form.querySelector("textarea").onkeydown = check_tab;
function check_tab(e) {
let code = e.target.value;
if(e.key == "Tab") {
e.preventDefault();
let before_tab = code.slice(0, e.target.selectionStart);
let after_tab = code.slice(e.target.selectionEnd, e.target.value.length);
let cursor_pos = e.target.selectionEnd + 1;
e.target.value = before_tab + "\t" + after_tab;
e.target.selectionStart = cursor_pos;
e.target.selectionEnd = cursor_pos;
}
}
return form;
}