I now have algorithms for translating between text editor (row, col)
and the browser Selection, which is abstracted as to a path + offset format (List Int, Int)
.
The path describes a path from a parent node elm-editor
, down to some point within a text node in the DOM. So [1,2,1,0]
, means follow child 1, then child 2, then child 1, then child 0. On offset of 10, would then mean step 10 characters into the text node found at the end of that path.
Iām not 100% sure yet, but I think mweiss/elm-rte-toolkit
did something super clever here. Because you need to write your HTML using its own ElementNode
model, for reasons described above, it is also able to figure out these paths itself. So even though you write a view to customize your editable content, cursor position maintenance is automatic?
The situation is simpler for my text editor, since I know the DOM structure. It may get trickier later on, depending on how customizable the view is in the completed work. That is, if I let users write their own arbitrary elm/html
Html
views, they will also need to supply a correct (row, col)
<-> (List Int, Int)
coordinate mapping. Other options would be:
- Steal another trick from
elm-rte-toolkit
and only allow customization through an alternate HTML DSL, that is able to figure out the mapping itself.
- Only allow very limited customization, such as setting color, bold/italic, and so on.
Was hoping to avoid both of those optionsā¦ anyway, a decision for later.
===
I am also thinking about cursor control on tablets/phones. Doing most cursor control through keyboard events at the moment, intercepted in Elm. I think that may not work well away from Desktop PCs, since virtual keyboards may have their own ideas about cursor control. I could let the browser do all cursor control, and map back into (row, col)
on the Elm side. I think the browsers cursor contol sucks some of the time thoughā¦ Perhaps both ways need to be implemented, selected at runtime by feature flags depending on the browser and device being used.
Will park this exploration for the time being, and just do Elm side keyboard events for this spike.
===
In the demo at the moment, I am displaying 2 cursors. One is the browsers cursor, and the other is an Elm rendered custom cursor. You can see they track each other well, and if you enter some "
to get syntax highlighting, that creates more child nodes on the line, so the path + offset logic does some work there to keep them in sync.
Lots of ways you can split the cursors at the moment, such as scrolling down or clicking with mouse. Iām working on cleaning that up now: