Thanks to Google Translate
am-editor, a web multi-person collaborative rich text editor based on ShareDB, suitable for React
and Vue
frameworks, compatible with mainstream modern browsers .
View online documentation and demo
Technical exchange QQ group: 907664876
am-editor, a web multi-person real-time collaborative rich text editor. Use the contenteditable
attribute provided by the browser to make a DOM node editable.
As we all know, the contenteditable
property will be different in different browser vendors, and its default behavior is unpredictable, so we encapsulate a certain controllable editing capability engine library @aomao/engine
, A trade-off between the default behavior and the desired behavior.
The engine library is written in javascript
. We encapsulate and derive interfaces for a series of operations such as DOM node insertion, deletion, and replacement, including cursors and events. Therefore, all our operations in the engine will directly edit the complex DOM tree, and in the data structure we will also present it in the DOM tree structure. However, in practical applications, it is very necessary for us to constrain the complex DOM tree structure to avoid unexpected behavior, and in the current popular use of front-end frameworks such as React
and Vue
to render the UI, let us re Using javascript
to customize the UI is a very painful thing. So we divide the DOM nodes into the following categories according to their functions and characteristics: mark
inline
block
card
and use the schema
to constrain their specific behaviors and some idiosyncratic attributes. In the card
component we It can also be combined with the front-end framework to complete complex UI rendering and editing nesting.
In modern enterprises, collaborative office is synonymous with high efficiency. Collaborating documents after instant messaging and video conferencing is a general trend. In the engine library, we provide collaborative editing capabilities based on ShareDB and convert the complex DOM structure to JSON0 After the data structure of the protocol, submit it to sharedb
to handle the interaction of collaborative editing.
- 📦 Out of the box, it provides dozens of rich plug-ins to meet most needs
- 🏷 High scalability, in addition to the
mark
inline
block
basic plug-in, we also providecard
component combined withReact
Vue
and other front-end framework rendering plug-in UI - 📋 Rich multimedia support, not only supports pictures, audio and video, but also supports inserting embedded multimedia content
- 🐠 Do not rely on front-end framework, easy to deal with complex architecture
- 📡 Built-in collaborative editing program, ready to use with lightweight configuration
-
@aomao/plugin-alignment
alignment -
@aomao/plugin-backcolor
background color -
@aomao/plugin-bold
bold -
@aomao/plugin-code
inline code -
@aomao/plugin-codelock
block-level code -
@aomao/plugin-fontcolor
foreground color -
@aomao/plugin-fontsize
font size -
@aomao/plugin-heading
heading -
@aomao/plugin-hr
dividing line -
@aomao/plugin-indent
indent -
@aomao/plugin-italic
italic -
@aomao/plugin-link
link -
@aomao/plugin-mark
mark -
@aomao/plugin-orderedlist
ordered list -
@aomao/plugin-paintformat
format paint -
@aomao/plugin-quote
quote -
@aomao/plugin-redo
to redo history -
@aomao/plugin-removeformat
remove format -
@aomao/plugin-selectall
select all -
@aomao/plugin-strikethrough
strikethrough -
@aomao/plugin-sub
subscript -
@aomao/plugin-sup
superscript -
@aomao/plugin-tasklist
task list -
@aomao/plugin-underline
underline -
@aomao/plugin-undo
undo history -
@aomao/plugin-unorderedlist
unordered list -
@aomao/plugin-image
image -
@aomao/plugin-table
table -
@aomao/plugin-file
file -
@aomao/plugin-mark-range
cursor range mark -
@aomao/plugin-video
video -
@aomao/plugin-math
Mathematical formula
The engine
, toolbar
, and each plug-in
in am-editor are separate packages. Among them, the engine
is the core package, and all other packages will depend on it
Install engine package using npm or yarn
$ npm install @aomao/engine
# or
$ yarn add @aomao/engine
Vue
users please see https://github.com/itellyou-com/am-editor/tree/master/demo-vue
We follow the convention to output a Hello word!
import React, { useEffect, useRef, useState } from 'react';
import Engine, { EngineInterface } from '@aomao/engine';
const EngineDemo = () => {
//Editor container
const ref = useRef<HTMLDivElement | null>(null);
//Engine instance
const [engine, setEngine] = useState<EngineInterface>();
//Editor content
const [content, setContent] = useState<string>('Hello word!');
useEffect(() => {
if (!ref.current) return;
//Instantiate the engine
const engine = new Engine(ref.current);
//Initialize local collaboration to record history
engine.ot.initLockMode();
//Set the editor value
engine.setValue(content);
//Listen to the editor value change event
engine.on('change', value => {
setContent(value);
console.log(`value:${value}`);
});
//Set the engine instance
setEngine(engine);
}, []);
return <div ref={ref} />;
};
export default EngineDemo;
Now, on the basis of the appeal code, we introduce the @aomao/plugin-bold
bold plug-in
import Bold from '@aomao/plugin-bold';
Then add the Bold
plugin to the engine
//Instantiate the engine
const engine = new Engine(ref.current, {
plugin: [Bold],
});
A card is a separate area in the editor. The UI and logic inside the card can be customized to render content using React, Vue or other frameworks, and finally mounted on the editor.
Introduce the @aomao/plugin-codeblock
code block plug-in, part of the plug-in UI uses frame rendering, so there is a distinction. vue
developers use @aomao/plugin-codeblock-vue
import CodeBlock, { CodeBlockComponent } from '@aomao/plugin-codeblock';
Add CodeBlock
plugin and CodeBlockComponent
card component to the engine
//Instantiate the engine
const engine = new Engine(ref.current, {
plugins: [CodeBlock],
cards: [CodeBlockComponent],
});
The CodeBlock
plugin supports markdown
by default. Enter the code block syntax ```javascript` at the beginning of a line in the editor, and then see the effect.
Introduce the @aomao/toolbar
toolbar, which basically uses frame rendering, and vue
developers use @aomao/toolbar-vue
import Toolbar, { ToolbarPlugin, ToolbarComponent } from '@aomao/toolbar';
Add the ToolbarPlugin
plugin and the ToolbarComponent
card component to the engine, it will allow us to use the shortcut key /
to wake up the toolbar in the editor
//Instantiate the engine
const engine = new Engine(ref.current, {
plugins: [ToolbarPlugin],
cards: [ToolbarComponent],
});
Rendering toolbar, the toolbar has been configured with all plug-ins, here we only need to pass in the plug-in name
return (
...
{
engine && (
<Toolbar
engine={engine}
items={[
['collapse'],
[
'bold',
],
]}
/>
)
}
...
)
Collaborative editing is based on ShareDB. Each editor acts as client through WebSocket
and server to exchange data. The editor processes and renders data.
After we set up the client and server, we start collaborative editing. View full example
//Instantiate the collaborative editing client and pass in the current editor engine instance
const otClient = new OTClient(engine);
//Connect to the collaboration server, `demo` is the same as the server document ID
otClient.connect(
`ws://127.0.0.1:8080${currentMember ? '?uid=' + currentMember.id : ''}`,
'demo',
);