170 lines
4.2 KiB
JavaScript
170 lines
4.2 KiB
JavaScript
//
|
|
// Keyboard handling
|
|
//
|
|
|
|
const TAB_WIDTH = 4;
|
|
|
|
let sourceFocused = false;
|
|
|
|
source_text.addEventListener("mousedown", () => { sourceFocused = true; });
|
|
source_text.addEventListener("focusout", () => { sourceFocused = false; });
|
|
|
|
source_text.addEventListener("keydown", (event) => {
|
|
if (event.key != "Tab") {
|
|
sourceFocused = true;
|
|
}
|
|
|
|
if (event.key == "Enter" && event.shiftKey) {
|
|
event.preventDefault();
|
|
button_graph.click();
|
|
} else if (event.key == "Escape") {
|
|
sourceFocused = false;
|
|
} else if (event.key == "Backspace" && !event.ctrlKey) {
|
|
let selStart = source_text.selectionStart;
|
|
let selEnd = source_text.selectionEnd;
|
|
|
|
if (selStart == selEnd) {
|
|
let pre = source_text.value.slice(0, selStart);
|
|
let lineStart = pre.lastIndexOf("\n") + 1;
|
|
let preLine = pre.slice(lineStart);
|
|
|
|
if (preLine.length > 2 && preLine.trim() == "") {
|
|
let count = (selStart - lineStart - 1)%TAB_WIDTH + 1;
|
|
for (let i = 0; i < count; i++) {
|
|
if (pre[pre.length - i - 1] != " ") {
|
|
count = i;
|
|
}
|
|
}
|
|
|
|
let post = source_text.value.slice(selStart);
|
|
source_text.value = pre.slice(0, selStart - count) + post;
|
|
source_text.selectionStart = selStart - count;
|
|
source_text.selectionEnd = selEnd - count;
|
|
event.preventDefault();
|
|
}
|
|
}
|
|
} else if (event.key == "Tab" && sourceFocused) {
|
|
event.preventDefault();
|
|
|
|
let selStart = source_text.selectionStart;
|
|
let selEnd = source_text.selectionEnd;
|
|
let pre = source_text.value.slice(0, selStart);
|
|
let post = source_text.value.slice(selStart);
|
|
let lineStart = pre.lastIndexOf("\n") + 1;
|
|
|
|
if (event.shiftKey) {
|
|
let count = (selStart - lineStart - 1)%TAB_WIDTH + 1;
|
|
for (let i = 0; i < count; i++) {
|
|
if (pre[pre.length - i - 1] != " ") {
|
|
count = i;
|
|
}
|
|
}
|
|
|
|
if (count > 0) {
|
|
source_text.value = pre.slice(0, selStart - count) + post;
|
|
source_text.selectionStart = selStart - count;
|
|
source_text.selectionEnd = selEnd - count;
|
|
}
|
|
} else {
|
|
let count = TAB_WIDTH - (selStart - lineStart)%TAB_WIDTH;
|
|
source_text.value = pre + " ".repeat(count) + post;
|
|
source_text.selectionStart = selStart + count;
|
|
source_text.selectionEnd = selEnd + count;
|
|
}
|
|
}
|
|
});
|
|
|
|
//
|
|
// Special characters
|
|
//
|
|
|
|
export let charMap = {
|
|
"alpha": "\u03b1",
|
|
"beta": "\u03b2",
|
|
"gamma": "\u03b3",
|
|
"delta": "\u03b4",
|
|
"epsilon": "\u03b5",
|
|
"zeta": "\u03b6",
|
|
"eta": "\u03b7",
|
|
"theta": "\u03b8",
|
|
"iota": "\u03b9",
|
|
"kappa": "\u03ba",
|
|
"lambda": "\u03bb",
|
|
"mu": "\u03bc",
|
|
"nu": "\u03bd",
|
|
"xi": "\u03be",
|
|
"omicron": "\u03bf",
|
|
"pi": "\u03c0",
|
|
"rho": "\u03c1",
|
|
"fsigma": "\u03c2",
|
|
"sigma": "\u03c3",
|
|
"tau": "\u03c4",
|
|
"upsilon": "\u03c5",
|
|
"phi": "\u03c6",
|
|
"chi": "\u03c7",
|
|
"psi": "\u03c8",
|
|
"omega": "\u03c9",
|
|
"Alpha": "\u0391",
|
|
"Beta": "\u0392",
|
|
"Gamma": "\u0393",
|
|
"Delta": "\u0394",
|
|
"Epsilon": "\u0395",
|
|
"Zeta": "\u0396",
|
|
"Eta": "\u0397",
|
|
"Theta": "\u0398",
|
|
"Iota": "\u0399",
|
|
"Kappa": "\u039a",
|
|
"Lambda": "\u039b",
|
|
"Mu": "\u039c",
|
|
"Nu": "\u039d",
|
|
"Xi": "\u039e",
|
|
"Omicron": "\u039f",
|
|
"Pi": "\u03a0",
|
|
"Rho": "\u03a1",
|
|
"Sigma": "\u03a3",
|
|
"Tau": "\u03a4",
|
|
"Upsilon": "\u03a5",
|
|
"Phi": "\u03a6",
|
|
"Chi": "\u03a7",
|
|
"Psi": "\u03a8",
|
|
"Omega": "\u03a9",
|
|
"vartheta": "\u03d1",
|
|
"0": "\u2080",
|
|
"1": "\u2081",
|
|
"2": "\u2082",
|
|
"3": "\u2083",
|
|
"4": "\u2084",
|
|
"5": "\u2085",
|
|
"6": "\u2086",
|
|
"7": "\u2087",
|
|
"8": "\u2088",
|
|
"9": "\u2089",
|
|
};
|
|
let specialChars = new RegExp(
|
|
`\\\\(${Object.keys(charMap).join("|")})`
|
|
);
|
|
|
|
source_text.addEventListener("input", (event) => {
|
|
if(event.isComposing) return;
|
|
let e = source_text.selectionEnd;
|
|
let amnt = 0;
|
|
source_text.value = source_text.value.replace(
|
|
specialChars,
|
|
(m, p) => {
|
|
amnt += m.length - charMap[p].length;
|
|
return charMap[p];
|
|
}
|
|
);
|
|
source_text.selectionEnd = e - amnt;
|
|
});
|
|
|
|
source_text.addEventListener("change", () => {
|
|
localStorage.setItem("editor_content", source_text.value);
|
|
});
|
|
|
|
if (localStorage.getItem("editor_content") !== null) {
|
|
source_text.value = localStorage.getItem("editor_content");
|
|
} else {
|
|
source_text.value = "f(z) = 6z^2 - 2i - 1\nplot(z) = f(1 + sin(z)) / 8";
|
|
}
|