Friday:
Made some decent progress. Nothing interesting to show. Sadly got stuck on rich text editing. The last log entry has more on that.
13:00: Worked out what I want to get done by the end of the jam. Getting to work on that now!
14:20: The rough structure of the ui is in place. There is a list of notes (zettels) on the left, an editor in the middle, and an inspector on the right. When you click on a zettel in the list, the editor switches to that zettel. The inspector doesn't do anything yet. Basic stuff. I'll go enjoy the sun for a while; then I'll add more functionality.
16:05: The most important thing, that I still need to figure out, is how to create a "rich text" editor with inline objects in html. So, I'll get to work on that now.
16:40: Yeah, that's gonna be a bit tricky. The most common approach seems to be "contentEditable". The problem is that I'll have my own data structure representing the rich text. To render it, it has to be turned it into dom nodes. Naively using contentEditable will mutate the dom nodes, and I'd have to effectively parse the dom nodes and turn them back into my representation. That doesn't sound like fun.
My current idea is to use contentEditable purely for cursor movement and selection. Any mutating events (i.e. input) will be caught by event listeners, which block the event's default behavior, translate it into mutations of my representation, and trigger a re-render.
Experimenting with that idea now.
17:50: This seems workable: My rich text representation is turned into dom nodes with annotations (source mappings, if you will). beforeinput let's me prevent all input changes and only process those, which make sense for me. Using getTargetRanges, I can figure out which dom nodes (and their sub-ranges) are affected by an edit. The source info lets me map back to my representation. Taking a break, then exploring that further.
19:15: Back to work on the rich text editor thingy: Implementing the dom markup (source locations) and editing.
20:30: It's a bit complicated, but I'm making progress. Need some quick down time.
20:45: Final session for today. Let's see how far I can get with this text editor!
21:55: Well, not that far :D There are a few nasty problems: Not all inputs are cancellable using beforeinput. And for the most important one ("insertText"), it is undefined whether it can be blocked - yay.
So I thought: Alright, let's not block any input events and just "render to make unwanted input go away." That has two problems: 1) preact is a bit silly and doesn't update the text, as it doesn't know that the dom node's text has changed. The v-node still contains the unchanged string, so the diff against my unchanged string prevents the overwriting of the incorrect dom text. I could probably find a workaround for that. But then there is problem 2: If a span's text is changed programmatically, the cursor jumps to the beginning of that span. I guess I could remember the current cursor position and restore it on each render. But I'm not sure that wouldn't cause flickering.
I'm left unsure what to do about these problems. Maybe I'll have an idea tomorrow.
There is of course the option to use an off-the-shelf rich text editor. But that isn't really an option, because I want to do some pretty "core" things differently.
For example: I'll have the usual way of boldening a range of text using two asterisks. However, unlike in markdown, when typing the second asterisk, the range is stored as "structured information", and the characters are removed from the text. (Yes, this will be a separate undo history entry.) But when the cursor moves back into that boldened range, I want to show the asterisks again. They won't quite be normal characters though: You can drag them around using the mouse to change the range, or delete one of them to delete the range (the boldening and the two virtual asterisks go away). I haven't tried to make an existing solution do that, but I wouldn't expect that to be much easier than creating my own.
It would probably be a good idea to look at some other rich text editor implementations though. Many of them use the dom directly though. As in: They don't try to force the browser's hand like mine (instead they send commands to the browser, which then adds <b> tags for example). Hmm, but somehow these editors have to get the info back out of the dom. Come to think of it, maybe dom parsing isn't that bad of an idea after all.