This document details the design & philosophy of Wave's rich text editor.
The following information is useful, but not strictly necessary, for understanding this document.
(Note, some of these pertain to the document model and rendering, which is strictly separate from the editor, but we describe them all together for convenience)
<<insert example screenshots here illustrating features/properties>>
As per goals, the editor is designed for collaborative, semantic editing of arbitrary web-focused content. We want to render content to clean HTML, but support editing gestures corresponding to the semantic level of the content. At the same time, we want to avoid re-inventing the wheel, and take advantage of as much of the native functionality present in browsers as possible. As of this writing, browsers provide some level of support for the kinds of goals we desire, but the APIs are immature and incomplete. Maintaining an arbitrary mapping from our abstract data model to an HTML rendering is difficult because letting the browser do everything (e.g. with raw contentEditable) will result in undesirable effects which are hard to control. Nonetheless, many man years have gone into browsers providing all kinds of functionality. So the overarching philosophy we've adopted is to strike a balance: leverage as much of what the web platform provides as is possible, let the browser do its job where it does it well and where we can control and keep track of its actions; for the rest, implement the desired functionality explicitly. This forms the core of the editor, and on top of this stable and flexible base, we can build all our features.
<INSERT IMAGE FROM PRESENTATION>
This diagram is a summary of the layers of event handling related to editing documents. Details follow.Normalize raw browser events using SignalEvent. See Signal Events document. We actually provide a custom factory for the SignalEvent implementation, so that we can create objects, which editor-specific extensions to SignalEvent. Details are discussed below.
Additionally, some doodads may choose to add direct event handlers on their HTML renderings. In this case, what happens is entirely under their control and has nothing to do with the editor
The editor's event routing logic is contained in the EditorEventHandler class. This contains all the fiddly logic for dealing with the events that pass through the editor, after already being normalized as . The class handles the following built in logic:
Furthermore, it handles routing editor events to custom, "3rd party" event handlers. This is part of the rich extensibility story of the editor. The above bullet point contains low-level editing concerns that require fiddly handling, and have not (at this point) been factored out. Regardless, most editing behaviors, from what happens when you press "Enter" in a paragraph or bullet point, to what happens when you hit "Tab" inside an image thumbnail caption (e.g. tabbing to the next caption, indenting for paragraphs), to what happens when you hit "Ctrl/Command+B", is funnelled to these other event handlers.
These handlers, in turn, mutate the document, which then reacts by updating its rendering, completing the cycle so the user's changes are reflected in the HTML. Currently, there are a few bits and pieces to custom event handling.
EditorEvent is an extension of SignalEvent that is passed to custom event handlers. It contains the following additions: