271 lines
7.7 KiB
JavaScript
271 lines
7.7 KiB
JavaScript
let input = [];
|
|
|
|
let currentWord = [];
|
|
|
|
let selected = -1;
|
|
|
|
window.onload = () => {
|
|
document.querySelectorAll(".ime").forEach(input => {
|
|
input.addEventListener("keydown", (key) => {
|
|
imeDown(key, input);
|
|
});
|
|
input.addEventListener("mousedown", (e) => {
|
|
e.preventDefault();
|
|
input.focus();
|
|
imeUpdate(input);
|
|
})
|
|
});
|
|
}
|
|
|
|
function imeDown(keyEvent, inputField) {
|
|
keyEvent.preventDefault();
|
|
switch (keyEvent.key) {
|
|
case "Backspace":
|
|
if (selected == -1) {
|
|
let latest = input[input.length]
|
|
console.log(latest);
|
|
|
|
|
|
if (currentWord.join("") == "") {
|
|
currentWord = input.pop() || [];
|
|
} else {
|
|
currentWord.pop();
|
|
}
|
|
} else {
|
|
input[selected].pop();
|
|
if (input[selected].join("") == "") {
|
|
input.splice(selected,1);
|
|
imeMove("left");
|
|
}
|
|
}
|
|
break;
|
|
case "Enter":
|
|
if (selected == -1) {
|
|
if (currentWord.join() == "") { //blame js :)
|
|
let s = document.createElement("p");
|
|
s.innerText = input.join("");
|
|
document.body.appendChild(s);
|
|
input = [];
|
|
selected = -1;
|
|
} else {
|
|
input.push(currentWord);
|
|
currentWord = [];
|
|
}
|
|
} else {
|
|
if (selected+1 >= input.length) {
|
|
selected = -1;
|
|
} else {
|
|
selected += 1;
|
|
}
|
|
}
|
|
imeReset();
|
|
break;
|
|
case "Space":
|
|
//adds a '
|
|
break;
|
|
case "ArrowLeft":
|
|
imeMove("left");
|
|
break;
|
|
case "ArrowRight":
|
|
imeMove("right");
|
|
break;
|
|
case "ArrowDown":
|
|
imeMove("start");
|
|
break;
|
|
case "ArrowUp":
|
|
imeMove("end");
|
|
break;
|
|
default:
|
|
imeInput(keyEvent.key);
|
|
if (selected == -1) {
|
|
currentWord = inputFull;
|
|
} else {
|
|
input[selected] = inputFull;
|
|
}
|
|
break;
|
|
}
|
|
imeUpdate(inputField);
|
|
}
|
|
|
|
function imeUpdate(inputField) {
|
|
let renderText = "";
|
|
input.forEach((w) => {
|
|
renderText += w.join("");
|
|
})
|
|
inputField.value = renderText + currentWord.join("");
|
|
if (selected == -1) {
|
|
inputField.setSelectionRange(renderText.length, renderText.length+currentWord.join("").length);
|
|
} else {
|
|
from = 0;
|
|
for (let x = 0; x < selected; x++) {
|
|
from += input[x].join("").length;
|
|
}
|
|
to = from+input[selected].join("").length;
|
|
inputField.setSelectionRange(from, to);
|
|
}
|
|
}
|
|
|
|
function clamp(min, max, value) {
|
|
return Math.max(min, Math.min(max, value));
|
|
}
|
|
|
|
function imeMove(direction) {
|
|
let d = 1;
|
|
if (currentWord.join("") != "") {
|
|
input.push(currentWord);
|
|
currentWord = [];
|
|
d = 2;
|
|
}
|
|
switch (direction) {
|
|
case "start":
|
|
selected = 0;
|
|
break;
|
|
case "end":
|
|
selected = -1;
|
|
break;
|
|
case "left":
|
|
if (selected == -1) selected = input.length;
|
|
selected -= 1 * d;
|
|
if (selected != -1) {
|
|
selected = clamp(0,input.length,selected);
|
|
//is there even a point in clamping it here,,,,
|
|
}
|
|
break;
|
|
case "right":
|
|
selected += 1 * d;
|
|
selected = clamp(0,input.length,selected);
|
|
//tbh same here, like.
|
|
//oh well ig ???/
|
|
if (selected == input.length) {
|
|
selected = -1;
|
|
}
|
|
break;
|
|
}
|
|
imeReset();
|
|
}
|
|
|
|
let inputState = 0; //STARTING, COMPOSTING, TRAILING, Fucking Nothing, ...cleanup
|
|
let stateState = 0; //depends on the state
|
|
let inputFull = [];
|
|
let inputCurrent = "";
|
|
|
|
let hVowels = { //standalone, composing, trailing
|
|
"a": ["0", "5", "A"],
|
|
"e": ["1", "6", "B"],
|
|
"i": ["2", "7", "C"],
|
|
"o": ["3", "8", "D"],
|
|
"u": ["4", "9", "E"]
|
|
};
|
|
|
|
let hConsonants = { //0 = standalone, 1 = composing, 2-6 = vowels
|
|
"g": "01",
|
|
"s": "02",
|
|
"r": "03",
|
|
"n": "04",
|
|
"c": "05",
|
|
"m": "06",
|
|
"j": "07",
|
|
"f": "08",
|
|
"t": "09",
|
|
"k": "0A",
|
|
"w": "0B",
|
|
"l": "0C",
|
|
"p": "0D",
|
|
"b": "0E",
|
|
"d": "0F",
|
|
"h": "10",
|
|
};
|
|
|
|
function getUnicodeVowel(vowel, sot) {
|
|
if (sot == "standalone") sot = 0;
|
|
if (sot == "composing") sot = 1;
|
|
if (sot == "trailing") sot = 2;
|
|
return String.fromCharCode(parseInt("E00" + hVowels[vowel][sot], 16));
|
|
}
|
|
|
|
function getUnicodeConsonant(consonant, scv) {
|
|
if (scv == "standalone") {scv = 0;}
|
|
else if (scv == "trailing") {scv = 1;}
|
|
else {scv = Number(hVowels[scv][0])+2}
|
|
return String.fromCharCode(parseInt("E" + hConsonants[consonant] + "" + scv, 16));
|
|
}
|
|
|
|
let hVowelsK = Object.keys(hVowels)
|
|
let hConsonantsK = Object.keys(hConsonants);
|
|
|
|
function debugInput(key) {
|
|
console.log("pre "+key+": inputstate - "+inputState +", statestate - "+ stateState);
|
|
console.log("inputfull: " + inputFull.join(" ") + ", inputcurrent:" + inputCurrent);
|
|
imeInput(key);
|
|
console.log("post "+key+": inputstate - "+inputState +", statestate - "+ stateState);
|
|
console.log("inputfull: " + inputFull.join(" ") + ", inputcurrent:" + inputCurrent);
|
|
console.log("------------------------------")
|
|
}
|
|
|
|
function imeReset() {
|
|
stateState = 0;
|
|
inputState = 0;
|
|
inputFull = [];
|
|
inputCurrent = "";
|
|
}
|
|
|
|
function imeInput(key) {
|
|
key = key.toLowerCase();
|
|
if (!hConsonantsK.includes(key) && !hVowelsK.includes(key)) return;
|
|
switch (inputState) {
|
|
case 0: //starting
|
|
if (stateState == 0) {
|
|
if (hVowelsK.includes(key)) {
|
|
inputFull.push(getUnicodeVowel(key, "standalone"));
|
|
inputState = 2;
|
|
} else {
|
|
inputFull.push(getUnicodeConsonant(key, "standalone"));
|
|
stateState = 1;
|
|
inputCurrent = key;
|
|
}
|
|
break;
|
|
} else if (stateState == 1) {
|
|
if (hVowelsK.includes(key)) {
|
|
inputState = 1;
|
|
stateState = 0;
|
|
} else {
|
|
inputFull.push(getUnicodeConsonant(key, "trailing"));
|
|
inputCurrent = key;
|
|
stateState = 2;
|
|
break;
|
|
}
|
|
} else if (stateState == 2) {
|
|
if (hVowelsK.includes(key)) {
|
|
inputState = 1;
|
|
stateState = 0;
|
|
} else break;
|
|
}
|
|
case 1: //composing
|
|
if (hVowelsK.includes(key)) {
|
|
inputState = 2;
|
|
inputFull.pop();
|
|
inputFull.push(getUnicodeConsonant(inputCurrent, key));
|
|
inputCurrent = "";
|
|
}
|
|
break;
|
|
case 2: //trailing
|
|
if (hVowelsK.includes(key)) {
|
|
inputFull.push(getUnicodeVowel(key, "trailing"));
|
|
stateState += 1;
|
|
} else {
|
|
inputFull.push(getUnicodeConsonant(key, "trailing"));
|
|
stateState += 1;
|
|
}
|
|
if (stateState == 2) {
|
|
stateState = 0;
|
|
inputState = 3;
|
|
}
|
|
break;
|
|
case 3: //do nothing (i.e "waiting 4 u 2 hit enter")
|
|
break;
|
|
case 4: //cleanup (reset vars)
|
|
stateState = 0;
|
|
inputCurrent = "";
|
|
break;
|
|
}
|
|
} |