What is a rich text editor?

In general, products that can edit text, images, and so on are called rich text editors. However, with the increasing demand and changing technology, today’s rich text editors are not only limited to text and pictures, but also include videos, tables, code blocks, mind maps, attachments, formulas, format brushes and other more complex functions.

Editor development history

🎉 At present, in the field of rich text editor, the specific implementation methods can be roughly divided into three types, namely, L0 editor, L1 editor and L2 editor. Their specific differences are as follows:

  • L0: rely onDOMthecontenteditableProperty, based on nativeexecCommandOr custom extendedexecCommandTo operateDOMRealize the modification of rich text content. The output ofHTMLA string. Such asCKEditor1-4,UEditor,wangEditor.
  • L1:DOM TreeThe modification of the data has been abstracted so that the developer does not, for the most part, operate directlyDOMThe various functions are accomplished using apis provided by models built with the L1 framework. Such asQuill.js,ProseMirror,Draft.js,Slate. Its output is the data represented by a self-encapsulated model.
  • L2: Independent cursor and layout independent of browser editing capabilities. Such asGoole Doc. This method is expensive.

Problems with execCommand

🎉 why L0~L2? The answer must be that L0 is flawed, or needs to be optimized, to continue to develop.

  • The development of rich text editing is an old but enduring topic.

  • The L0 phase of rich text editor development relies on two native apis provided by browsers, Contenteditable and execCommand, to implement a simple rich text editor:

    • First, the external container (generally asdiv)contenteditableProperty set totrue, the container can be used for keyboard, mouse and other operations.
    • Also, add a toolbar with the help ofexecCommandCommand to edit the contents of a container, such as bold, italic, and underscore.
  • Theoretically speaking, the above operations can complete a simple rich text editor development. However, execCommand has a few problems:

    • compatibility:execCommandThe command is browser-dependent, which depends on how well each browser supports the command. MDN makes it clear that this is a deprecated command.

    • Black box: execCommand is executed by the browser, just like a black box. We only provide the input (parameters), and the specific operation is not under our control, which is very uncomfortable for development. The return value of the execCommand is a Boolean value indicating whether the command was executed correctly. The syntax is as follows:
       bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)
    Copy the code

    Return value: A Boolean value indicating whether the command was executed correctly.

    parameter meaning
    aCommandName The commandName, such as blod (bold) and backColor (background color).
    aShowDefaultUI Whether to display the user interfacefalse.
    aValueArgument Additional parameter values, such as image valuesurlAnd so on.
  • Inconsistent behavior: The execCommand command causes different behavior for the same function. For example, Internet Explorer uses the tag for bold, while other browsers use the tag. And all sorts of other confusing behaviors… . As a result, the DOM of each browser for the same function may be inconsistent, and various bogeymen may appear later.

  • ExecCommand is not an omnipotent command. It can only implement some simple functions, such as text bold, text background color, color, font, size, italic, heading, stripper, underline, etc. The font must be 1-7 and the title must be H1-H6. In addition, for slightly more complex functions, such as tables, images, code blocks, attachments, etc., this command cannot be implemented directly.

To solve the problem

🎉 Since there are so many problems with execCommand, can we implement a command similar to this one? Make the behavior, structure, and performance consistent, and the process manageable? Of course you can. This is called self-development execCommand.

  • In L0, thetawangEditorFor example, inexecCommandThere’s a layer on the top, forexecCommandThe functions that can be implemented by default are still used by themselves, and for complex functions that cannot be implemented, useinsertHTML å’Œ insertElemTo implement. This approach can basically achieve our requirements, but not rightexecCommandThe extension itself, and it’s a black box, doesn’t essentially solve the problem. Details are as follows:
switch (name) {
    case 'insertHTML':
    	this.insertHTML(value as string)
    	break
    case 'insertElem':
    	this.insertElem(value as DomElement)
    	break
    default:
      / / the default command
      this.execCommand(name, value as string)
      break
}
Copy the code

When inserting formatted content into an editor, it is traditional to insert the corresponding DOM directly into the editor and compare the DOM tree to record the content changes. Manipulating the DOM directly has many inconveniences, such as the difficulty of knowing the format of certain characters or content in the editor, especially for custom rich text formats. Is it possible to make the content representation of the editor concise and accurate, and then operate it more conveniently?

🎉 the answer is yes, do an abstraction on the DOM, that is to use a very simple data structure model to describe the content and changes of the editor, similar to the use of VDOM to describe the DOM structure, convenient for the subsequent DOM add, delete, change and other column operations.

In L1, most of the approach is to use a data model (such as Delta) that describes the structure of the document, and when the content changes, the data model also describes the structure of the document. You then make changes to the view using the API provided by your homegrown execCommand. That is, when the content changes, modify the data model first, then modify the view. Js, ProseMirror, draft.js, Slate, etc.

  • Reference:
    • First experience with editor
    • Evolution of open source rich text editor technology
    • MDN
    • why-contenteditable-is-terrible

🎉 If you are interested in developing rich text editors, check out our open source team: WangEditor. We have a group of partners who love editor development, and we constantly improve our skills through sharing and technical exchanges, as well as working together on the open source project wangEditor. We all firmly believe that valuable things will be realized in the future.