This article is not intended to teach you how to write an editor in 10 minutes. If you want to speed things up, don’t read on.
Rich text editors are a sinkhole
This is an ancient saying handed down from the front, even if you have never touched this thing should be heard this sentence. I guess that was the cry of a user of uEditor who changed the bug to crash in the wee hours of the morning 😄.
The first rich text editor I came into contact with was the famous uEditor. The first impression was that it was ugly and ugly in appearance. Later, WHEN I tried to read its code, I found that it was not only ugly in appearance but also messy in code.
On a quiet night thinking about this sentence, the biggest pitfall is browser compatibility and different browser commands, which contenteditable has brought about. Read on…
2. Write your own editor
In fact, it is very simple to write an editor now, and more than 90% of the editors on the market are inseparable from two magic weapons
1. contenteditable
2. document.execcommand
Copy the code
I’m sure you’ve got a prototype editor in your head. Online tutorials for 10-minute crash editors are 100% about these two things, and the rest is about styles, feature extensions, etc. Even the simplest editors probably use less than 100 lines of code. If you’re interested, take a look at Pell, which is by far the most straightforward editor I’ve read
The core of a regular editor is this: we respond to user actions by calling browser commands, and of course the browser has the final power to interpret them.
Simple as it is, the resulting editor is out of control, with user input and interpretation of browser commands beyond the control of our code. React and other modern frameworks give us a bright future in which we can focus on data. All user views are controllable, so the editor we created is actually not in line with the data <–> view model. Data to us might just be a serialized string of HTML code.
I simply split the editor into two parts, core module and plugins module.
Plugins allow plugins to register some of their capabilities (font size, color, insert elements, etc.)Copy the code
The goal is to better provide security capabilities to plug-ins.
The editor itself should be a socket, and what it can do depends on what “appliances” are attached to the socket. A good socket will not disable all appliances or even burn itself out because of a faulty appliance.
Plug-in systems are often the most complex module of the entire editor. The difficulty is not how to deliver power, but how to control the power of a third party. If a plugin wants to do something bad, it’s easy.
A good plug-in system is actually more like the concept of one-way data flow. Upper-layer application plug-ins often need to take advantage of the capabilities of the underlying core, but cannot modify them (like immutable data), and the core needs to establish reporting and broadcasting mechanisms (lifecycle) for event distribution.
Crayon-editor, an editor I wrote myself, was developed using this model.
3. My ideal editor
The above is just the infrastructure of an open source editor. The editor based on this architecture is still command-driven, and the underlying capabilities have not changed fundamentally. So are there other modes besides command-driven? That’s data-driven
Editor architecture — Data driven
People who have worked with React and Vue will be familiar with the data-driven approach, which basically maps data to the view DOM. All changes are made to manipulate the data, and ultimately to re-render the data. In other words, the input and output of the editor are abstracted into modules. The user’s operation is transformed from direct DOM operation to data operation, and the final output is module. Then, the mature React and Vue are combined to render modules, and a complete editing logic is finally formed. Here the editor is responsible for translating, interpreting the DOM and Module, and mapping all actions to changes to the Module, a bit like the AST.
So data-driven editors are bound to discard contenteditable and Document. execcommand because both are uncontrollable factors, resulting in dom and Module inconsistence.
Of course, this solution can be very complex, such as figuring out how to edit and cursor in the first place, and how to map subsequent browser instructions. The only models I know of so far are draft.js and Trix, both of which are based on React.
This is the most advanced editor solution to date, realizing a fully controllable editor, and multi-person collaborative online editing is not a problem. Combined with immutable data, user operation paths can also be recorded…
Plugins — extend capabilities
For rich text editors, plug-ins mean capabilities, but no matter how hard developers try, they can’t satisfy everyone’s needs. In the face of personalized needs, the ability to accommodate custom development plug-ins is also a must
Brief appearance — beauty
A big part of the reason I don’t use Baidu’s uEditor is because it’s ugly
Active user base — Engagement
Maintaining a community is critical, and if the feedback goes unanswered for a long time, people often feel the project is dead. Although uEditor has so many problems, it is still one of the best editors in China. I think the biggest reason is the large user base.
conclusion
That’s what I want to say about the editor