Medium's engineering team writes about the editor, microservices, hiring, and bugs like the disappearing Polish S.
HN commenters call the ContentEditable post a classic technical explanation and link the Polish S bug, and cite its editor design and microservices.
Writing a ContentEditable editor means learning the internal state machines and undocumented behaviors of every browser you support. There are many articles online about ContentEditable / rich text editing. This one is a classic https://medium.engineering/why-contenteditable-is-terrible-122d8a40e480
The major issue for both Android and CJK input is dealing with “composition” of characters by an “input method editor”. https://en.m.wikipedia.org/wiki/Input_method
In English, usually it’s okay to assume one key press event = one letter input. The opposite is true on Android generally, and for CJK languages on all platforms. These use input systems (like handwriting) where keypresses never occur, or many keypresses compose to produce one character. There are also new rules for IME composition input like “you can’t touch the DOM or change the selection during composition or the input will cancel and your user will be mad”. It turns the problem from “Hard” difficulty to “Nightmare” difficulty.
The baffling thing on Android is that each keyboard (Gboard, Samsung Keyboard, Swiftkey, Simeji, Sogou, Naver) have different composition behaviors with different event patterns… and GBoard’s ENGLISH input is probably the most strange! It composes whole English words like they were Chinese characters, and it wants to compose SO badly it will move text selection from wherever the user tapped to the nearest English word. And as an added bonus on Android only, the browsers selection APIs…
One of unresolved questions of rich text in my mind is what to do with these markup “codes”, explicit or hidden, because while the (usually) nested open/close structure is a non-terrible way for describing formatting in plain text, it is IMO a completely unnatural model (mental or programmatic) of describing rich text by itself, not backed by marked-up plain text. This is apparent in abstraction leaks like the one you describe, but it also has a way of making your life really miserable as soon as you want to reason about transformations of documents, like in a collaborative editor or just a HTML-based editor.
In fact, both Google Wave (IIRC, not going to look up the reference right now) and the Medium editor (https://medium.engineering/why-contenteditable-is-terrible-122d8a40e480) represent inline formatting as a bucket of non-nested “spans”, because while this still doesn’t yield a unique representation of what you want to call rich text, it gets much easier to pick a canonical representative for each class of equivalent representations that doesn’t get completely upturned by localized editing operations.
Even the text editor example in the GoF book just assigned each character a (shared, CoW) style object... Does anyone actually do it this way?
There is also a whole slew of issues with Polish characters. Polish keyboard setup relies on "right-alt" and a letter to get it's diacritics variation. Ie:
'ą' is 'right-alt'+a
Windows for backwards compatibility reports 'right-alt' as 'alt+control'.
Many applications developers assign key combos with no negative checks. So 'ctrl-s', typically used for save gets triggered when user wants to type 'ś'. To repeat, "right-alt"+"s" is reported as "alt"+"control"+"s", which triggers crappy "control"+"s" checks.
Similar scenarios happen many places that check for 'alt'+'letter' without checking if control also is not pressed.
Microsoft thread for team user voice issues on this https://microsoftteams.uservoice.com/forums/555103-public/suggestions/32265802-alt-a-and-alt-s-affecting-polish-character-for-%C4%85
or Medium's developer talking about 'ś' and 'ctrl'+'s'.
https://medium.engineering/the-curious-case-of-disappearing-polish-s-fa398313d4df?gi=56e8f39b530e
You can create whatever arbitrary naming convention you want for internal networks, and use either hosts files or your own private DNS server to resolve those names. But if your scheme overlaps with something that's published publicly, it's probably going to cause problems at some point.
There's a little bit of info in some RFC's about special / reserved names, which are dedicated to certain special uses. See, for example:
https://tools.ietf.org/html/rfc6761
https://tools.ietf.org/html/rfc2606
In years past, a lot of people would just pick a tld that didn't exist and then use that for internal domain names. That was probably safe back when new TLD's came into existence very infrequently. In this day and age, TLD squatting is a risky proposition, as seen here:
https://medium.engineering/use-a-dev-domain-not-anymore-95219778e6fd
There are a number of rich text editors that model documents as a flat array of characters and a separate table of formatting modifiers (each with an offset and length). Medium's text editor is one of them. This post [1] on their engineering blog introduced me to the idea, and I think it's a good starting point for anyone interested in this topic.
ProseMirror (a JavaScript library for building rich text editors) also employs a document model like this. The docs for that project [2] do a good job of explaining how their implementation of this idea works, and what problems it solves.
[1]: https://medium.engineering/why-contenteditable-is-terrible-122d8a40e480
[2]: https://prosemirror.net/docs/guide/#doc
> Architecturally monolithic Web apps use GraphQL all the time.
Sure, but a significant motivation for using GraphQL is to stitch together a bunch of microservices into a cohesive API for the front end.
My comment about Medium using microservices was just an informed guess, but a good one. They started migrating from a monolith to microservices back in 2018: https://medium.engineering/microservice-architecture-at-medium-9c33805eb74f
Is it a coincidence that that's around the time frame that I noticed the Medium web site becoming slower than it used to be?