đŸŽČ — mikrobloggeriet jals — jals-5 · jals-6 · jals-7

JALS-6 - Lage en editor i browseren

Jeg jobber med Ă„ lage en editor Unicad for ren tekst (uten formatering). Men vi Ăžnsker Ă„ lagre informasjon om hva brukeren gjĂžr, ikke kun enderesultatet.

Dvs, istedet for Ä lagre teksten hei, vil vi lagre det brukeren gjorde for Ä komme dit. Om brukeren skriver hi, ser brukeren har gjort en feil, visker vekk i og skriver ei sÄ det blir hei, vil vi lagre:

  1. Skrev h pÄ posisjon 0
  2. Skrev i pÄ posisjon 1
  3. Visket ut posisjon 1
  4. Skrev e pÄ posisjon 1
  5. Skrev i pÄ posisjon 2

Dette for Ä fÄ til collaborative editing, og for effektivt kontinuerlig kunne sende meldinger frem og tilbake til serveren.

Det finnes en lĂžsning for dette, og det er et event som heter beforeInput. Det er er en event som skjer rett etter brukeren har gjort en handling, men fĂžr handlingen “fĂ„r effekt” i DOM-en. Her kan vi bĂ„de se hva brukeren gjĂžr, og ogsĂ„ stoppe handlingen. Dette er det vi bruker for rik-tekst i Unicad.

Denne eventen stÞttes av <textarea>. SÄ alt ser bra ut. Trodde jeg. Helt til jeg fant ut at nÄr man kobler dette pÄ en <textarea> sÄ fungerer ikke getTargetRanges(), som er en funksjon som returnerer hvor endringen skjedde. Det hjelper ikke om vi vet at brukeren skrev i hvis vi ikke vet hvor i-en skal vÊre.

Vi kan trikse oss rundt det ved Ä bruke <textarea> sin selectionStart og selectionEnd. Men disse returnerer hvor selection er nÄ (dvs fÞr hendelsen skjedde, siden DOM-en ikke er oppdatert enda), ikke hvor endringen kommer til Ä skje.

Om brukeren trykker Ctrl+Backspace vil man i de fleste browsere viske ut et helt ord. Men for Ä stÞtte denne med beforeInput i et textarea mÄ vi faktisk selv finne ut hvilket ord brukeren har visket ut, vi fÄr kun vite at brukeren har gjort input action deleteWordBackward, og hvor cursoren stod nÄr brukeren gjorde det.

Det er ogsÄ flere ting som gjorde koden vanskelig Ä ha med Ä gjÞre nÄr jeg brukte textarea og beforeInput. Resultatet var at jeg mÄtte endre til en <div> med content-editable=true som har sine egne quirks, blant annet dÄrligere stÞtte for universell utforming.

SÄ konklusjonen er: Editering i browseren er broken (men ikke sÄ broken som fÞr vi fikk beforeInput, som var sÄ sent som 2021). Skal du lage en editor i browseren, bruk et tredjepartsbibliotek som CodeMirror (for ren tekst) eller ProseMirror (for rik tekst). Det er en grunn til hvorfor vi velger Ä ikke gjÞre det i Unicad, selv om vi pÄ ingen mÄte er sikre pÄ at vi tok riktig valg (men fremdeles heller mot at vi gjorde det riktige valget). Hvorfor vi ikke bruker CodeMirror og ProseMirror i Unicad fÄr vÊre en annen jals.

Har du spÞrsmÄl eller kommentarer, ta kontakt med meg pÄ slack (for Iterate-ansatte) eller pÄ mail (for andre).

– Sindre