The hardest part of WYSIWYG editors is always cursor positioning and selection across mixed content. How did you handle that? Also curious if you considered using a canvas-based renderer vs DOM — what made you go with your current approach?

Cursor positioning is simple. The layout is a tree of nested box. Each box knows the x,y-position of its children. There is also an index dimension which numbers possible cursor positions. A box lies from i1 to i2 in index space. You just iterate over all boxes holding cursor position i to find the cursor coordinate x,y. Selection is simple as well. It is defined by a start index s1 and end index s2. Some objects have a special selection, e.g. tables where you select a rectangular range of table cells.