Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Hack & Tell TO 3: Rich Text Editor in Pure JS

Hack & Tell TO 3: Rich Text Editor in Pure JS

This was an informal presentation about my exploratory efforts to implement a pure JS rich-text editor on the web (https://github.com/unframework/motepad)

Nick Matantsev

July 28, 2015
Tweet

More Decks by Nick Matantsev

Other Decks in Programming

Transcript

  1. Hi, I’m Nick Matantsev • @unframework (find me on GitHub!)

    • product technical lead at Myplanet • backend, frontend, server automation • first fulltime gig was at TMX in 2002 • passionate about: ◦ UX ◦ lean enterprise ◦ empathy-driven engineering
  2. Rich Text Editors on the Web • textbox + bold,

    italics, font sizing, etc • contentEditable to the rescue! • how it works: ◦ put contenteditable=”true” on an element ◦ done! or is it? • problematic ◦ browser bugs, content model issues, extensibility ◦ https://medium.com/medium-eng/why- contenteditable-is-terrible-122d8a40e480
  3. Pure JS Rich Text • initial inspiration: Google Docs ◦

    the Google Docs team needed custom layout/formatting power ◦ used pure JS/DOM • wanted simple rich textbox, not full MS Word ◦ string with arbitrary meta-data (including links/etc) ◦ example: Twitter/FB social text (mentions, tags, etc) • seemed like a nifty challenge! :)
  4. Motepad History • initial implementation in 2011 • cleaning up

    in 2013 • dusted off and fixed a couple things in earlier 2015 • https://github.com/unframework/motepad
  5. Implementation Basics • draw the surrounding box ◦ div style=”border:1px

    solid #444” • draw cursor ◦ div style=”background:#000”, blink? • draw text ◦ div with some text in it? ◦ let’s do “manual” layout!
  6. Custom Text Layout • split text into tokens by whitespace

    • start laying out, row by row • for each token: ◦ compute width in pixels (put in a span, read width) ◦ see if line would overflow (start a new line then) ◦ add the token • easy
  7. Text Attributes • naive model: for each character, a key-value

    map like this: ◦ bold: true ◦ italic: false ◦ link: http://example.com ◦ color: (null or a hex value) ◦ etc • run-length encoding helps
  8. Undo/Redo! • the editor is a state machine • editor

    state is immutable as a whole (!) • state1 + input = state2 • before undoable action, save current state on stack • undo = pop from stack
  9. Input -> Editor State -> Renderer • input ◦ stream

    of events into the editor ◦ insert, move cursor (left/right), move line (up/down), home/end ◦ mouseUp/mouseDown, mouseMove • editor state ◦ text + attribute data ◦ normal mode: cursor position index ◦ dragging/selection mode: selection range indices
  10. Text Editors are Hard • moar challenges: ◦ copy/paste -

    plain/Word/HTML ◦ input pattern detection for hashtags/@-mentions/etc ◦ performance (cache all the things) ◦ keyboard behaviour nitpicks (OS-specific, even!) ◦ things we take for granted! • deep dive = excellent learning experience