diff --git a/ime.html b/ime.html new file mode 100644 index 0000000..382a9ce --- /dev/null +++ b/ime.html @@ -0,0 +1,28 @@ + + + + + + ime test + + + + + +

type in ime, wow!!!!!!!!!!!

+ + + + + \ No newline at end of file diff --git a/ime.js b/ime.js new file mode 100644 index 0000000..52f456a --- /dev/null +++ b/ime.js @@ -0,0 +1,271 @@ +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; + } +} \ No newline at end of file diff --git a/ime.txt b/ime.txt new file mode 100644 index 0000000..61ca6cc --- /dev/null +++ b/ime.txt @@ -0,0 +1,56 @@ + +Description of IME: + +5 states: + - STARTING + - COMPOSING + - TRAILING + + Nomenclature: [Whole] / [Up|Down] + + At any times, enter can be pressed to finish the input process. + Pressing enter with input process already finished will send the message. + +STATE 1 - STARTING + Any first letter input is displayed as non-composing non-trailing symbol. + The big standalone variant. + + Consonant [K] + Vowel [A] + + If CONSONANT was inputted: + - Move to COMPOSING if next a VOWEL is inputted. + - Repeat this step if not, but adding the input as a trailing letter instead (uppercase). This can only happen once. + If VOWEL was inputted, move to TRAILING. + +STATE 2 - COMPOSING + + Only vowels are inputted. It is transcribed to heonian as a downside letter. + + Vowel -> [K|A] + + Move to TRAILING. + +STATE 3 - TRAILING. (UP TO 2 TIMES) + Any letter input is displayed as a trailing symbol. + Aka uppercase. + + 1-3 -> [A][N| ] + 1-3-3 -> [A][N| ][N| ] + 1-2-3 -> [K|A][N| ] + 1-2-3-3 -> [K|A][N| ][N| ] + 1-1-2-3 -> [K][K|A][N| ] + 1-1-2-3-3 -> [K][K|A][N| ][N| ] + + This process can be repeated up to two times. + +https://cronut.cafe/~lustlion/myrheon/test/ +0xE -> Heonian Letter +next two digits: Vowels / What Consonant +last digit: Standalone / Trailing / Composing + +simplified: +1. First letter inputted is standalone except if composing. +2. There can only be one composing per syllable, if it manages to go composing it goes to trailing. +3. You can input up to two letters before either composing or ending the syllable. +4. You can have 0, 1 or 2 trailing letters. diff --git a/main.js b/main.js index 02f4103..70e330e 100644 --- a/main.js +++ b/main.js @@ -1,8 +1,3 @@ -//since this _entire thing_ will be generated, -//you could "theoretically" (you definitive can) -//just sorta. skip the whole "scan all words" bit, -//which is why that's in a separate function - let words = {} let currentFont = "r"; @@ -116,7 +111,6 @@ function init() { document.querySelector("#popup-container").style.pointerEvents = "none"; } }); - // above are commented out until wordlist is added~ document.querySelector("#font-button").addEventListener("click", () => {fontButton();}); }