All Projects → yanmao-cc → am-editor

yanmao-cc / am-editor

Licence: MIT license
A rich text collaborative editor framework that can use React and Vue custom plug-ins. 一个富文本实时协同编辑器框架,可以使用React和Vue自定义插件。

Programming Languages

typescript
32286 projects
CSS
56736 projects
Vue
7211 projects
javascript
184084 projects - #8 most used programming language
Less
1899 projects
HTML
75241 projects

Projects that are alternatives of or similar to am-editor

Wysiwyg.js
wysiwyg contenteditable editor (minified+compression: 6kb)
Stars: ✭ 520 (-4.06%)
Mutual labels:  contenteditable, wysiwyg, text-editor, rich-text-editor, wysiwyg-editor
Pell
📝 the simplest and smallest WYSIWYG text editor for web, with no dependencies
Stars: ✭ 11,653 (+2050%)
Mutual labels:  contenteditable, wysiwyg, text-editor, rich-text-editor, wysiwyg-editor
Slate Plugins
🔌 Next-gen slate plugins
Stars: ✭ 399 (-26.38%)
Mutual labels:  contenteditable, wysiwyg, rich-text-editor, wysiwyg-editor
Ckeditor5
Powerful rich text editor framework with a modular architecture, modern integrations, and features like collaborative editing.
Stars: ✭ 5,406 (+897.42%)
Mutual labels:  contenteditable, wysiwyg, rich-text-editor, wysiwyg-editor
ember-pell
Ember addon for simplest and smallest (1kB) WYSIWYG text editor for web, with no dependencies
Stars: ✭ 56 (-89.67%)
Mutual labels:  contenteditable, wysiwyg, text-editor, rich-text-editor
Awesome Wysiwyg
A curated list of awesome WYSIWYG editors.
Stars: ✭ 1,801 (+232.29%)
Mutual labels:  contenteditable, wysiwyg, rich-text-editor, wysiwyg-editor
Megadraft
Megadraft is a Rich Text editor built on top of Facebook's Draft.JS featuring a nice default base of components and extensibility
Stars: ✭ 982 (+81.18%)
Mutual labels:  contenteditable, wysiwyg, rich-text-editor, wysiwyg-editor
typester
✒️ A WYSIWYG that gives you predictable and clean HTML
Stars: ✭ 29 (-94.65%)
Mutual labels:  wysiwyg, text-editor, rich-text-editor, wysiwyg-editor
Angular Froala Wysiwyg
Angular 4, 5, 6, 7, 8 and 9 plugin for Froala WYSIWYG HTML Rich Text Editor.
Stars: ✭ 696 (+28.41%)
Mutual labels:  wysiwyg, text-editor, rich-text-editor, wysiwyg-editor
bangle.dev
Collection of higher level rich text editing tools. It powers the local only note taking app https://bangle.io
Stars: ✭ 541 (-0.18%)
Mutual labels:  wysiwyg, text-editor, rich-text-editor, wysiwyg-editor
wysiwyg-editor-python-sdk
Python SDK to ease the integration of Froala WYSIWYG Editor on server side.
Stars: ✭ 20 (-96.31%)
Mutual labels:  wysiwyg, rich-text-editor, wysiwyg-editor
Sceditor
A lightweight HTML and BBCode WYSIWYG editor
Stars: ✭ 503 (-7.2%)
Mutual labels:  contenteditable, wysiwyg, wysiwyg-editor
ngx-wall
Helps build content editor for note-taking application
Stars: ✭ 78 (-85.61%)
Mutual labels:  wysiwyg, rich-text-editor, wysiwyg-editor
Medium Editor
Medium.com WYSIWYG editor clone. Uses contenteditable API to implement a rich text solution.
Stars: ✭ 15,421 (+2745.2%)
Mutual labels:  contenteditable, wysiwyg, rich-text-editor
Textbus
基于组件 + 数据驱动的现代富文本编辑器
Stars: ✭ 242 (-55.35%)
Mutual labels:  wysiwyg, rich-text-editor, wysiwyg-editor
Suneditor
Pure javascript based WYSIWYG html editor, with no dependencies.
Stars: ✭ 557 (+2.77%)
Mutual labels:  contenteditable, rich-text-editor, wysiwyg-editor
svelte-slate
slate svelte view layer
Stars: ✭ 43 (-92.07%)
Mutual labels:  wysiwyg, text-editor, wysiwyg-editor
Awesome Medium Editor
Medium.com WYSIWYG editor clone, with RTL support.
Stars: ✭ 12 (-97.79%)
Mutual labels:  contenteditable, wysiwyg, rich-text-editor
wysihtml5-rails
A wysiwyg text editor for use in the Rails asset pipeline
Stars: ✭ 28 (-94.83%)
Mutual labels:  wysiwyg, rich-text-editor, wysiwyg-editor
Flutter Quill
Rich text editor for Flutter
Stars: ✭ 177 (-67.34%)
Mutual labels:  wysiwyg, rich-text-editor, wysiwyg-editor

In the past two years, the am-editor editor has done a lot of functions and extensions based on the contenteditable attribute, but also encountered many problems. Of course, some problems are doomed from the very beginning of the architectural design. So, be bold now and try to abandon the contenteditable attribute and use the self-drawn cursor mode to develop the next version of the rich text editor.

am-editor

A rich text editor that supports collaborative editing, you can freely use React, Vue and other front-end common libraries to extend and define plugins.

Preview · Document · Plugins

Features

  • 🍉 Out of the box - Dozens of ready to use plug to meet most needs
  • 🍋 Extensibility - In addition to the basic plugin of mark, inlineandblocktype, we also providecardcomponent combined withReact, Vue and other front-end libraries to render the plugin UI
  • 🍎 Markdown Support
  • 👨‍🦳 I18n
  • 🔥 Zero dependency - The engine is written by pure JavaScript and does not rely on any front-end libraries. Plugins can be developed by any libraries such as ReactVue or Svelte
  • 🦔 Collaboration - Ready to use with lightweight configuration
  • Compatible with most of the latest mobile browsers
  • 🦾 TypeScript - Of course

Example

Vue2

Vue3

React

Vue2 Demo

Vue2 Nuxt Demo

Fundamental

Use the contenteditable attribute provided by the browser to make a DOM node editable:

<div contenteditable="true"></div>

So its value looks like this:

<div data-element="root" contenteditable="true">
	<p>Hello world!</p>
	<p><br /></p>
</div>

Of course, in some scenarios, for the convenience of operation, an API that converts to a JSON type value is also provided:

[
	'div', // node name
	// All attributes of the node
	{
		'data-element': 'root',
		contenteditable: 'true',
	},
	// child node 1
	[
		// child node name
		'p',
		// Child node attributes
		{},
		// child node of byte point
		'Hello world!',
	],
	// child node 2
	['p', {}, ['br', {}]],
];
The editor relies on the input capabilities provided by the contenteditable attribute and cursor control capabilities. Therefore, it has all the default browser behaviors, but the default behavior of the browser has different processing methods under different browser vendors' implementations, so we intercept most of its default behaviors and customize them.

For example, during the input process, beforeinput, input, delete, enter, and shortcut keys related to mousedown, mouseup, click and other events will be intercepted and customized processing will be performed.

After taking over the event, what the editor does is to manage all the child nodes under the root node based on the contenteditable property, such as inserting text, deleting text, inserting pictures, and so on.

In summary, the data structure in editing is a DOM tree structure, and all operations are performed directly on the DOM tree, not a typical MVC mode that drives view rendering with a data model.

Node constraints

In order to manage nodes more conveniently and reduce complexity. The editor abstracts node attributes and functions, and formulates four types of nodes, mark, inline, block, and card. They are composed of different attributes, styles, or html structures, and use the schema uniformly. They are constrained.

A simple schema looks like this:

{
  name:'p', // node name
  type:'block' // node type
}

In addition, you can also describe attributes, styles, etc., such as:

{
  name:'span', // node name
  type:'mark', // node type
  attributes: {
    // The node has a style attribute
    style: {
      // Must contain a color style
      color: {
        required: true, // must contain
        value:'@color' // The value is a color value that conforms to the css specification. @color is the color validation defined in the editor. Here, methods and regular expressions can also be used to determine whether the required rules are met
      }
    },
    // Optional include a test attribute, its value can be arbitrary, but it is not required
    test:'*'
  }
}

The following types of nodes conform to the above rules:

<span style="color:#fff"></span>
<span style="color:#fff" test="test123" test1="test1"></span>
<span style="color:#fff;background-color:#000;"></span>
<span style="color:#fff;background-color:#000;" test="test123"></span>

But except that color and test have been defined in schema, other attributes (background-color, test1) will be filtered out by the editor during processing.

The nodes in the editable area have four types of combined nodes of mark, inline, block, and cardthrough theschemarule. They are composed of different attributes, styles orhtml` structures. Certain constraints are imposed on nesting.

Getting Started

Installation

The editor consists of engine, toolbar, and plugin. Engine provides us with core editing capabilities.

Install engine package using npm or yarn

$ npm install @aomao/engine
# or
$ yarn add @aomao/engine

Usage

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>('<p>Hello word!</p>');

	useEffect(() => {
		if (!ref.current) return;
		//Instantiate the engine
		const engine = new Engine(ref.current);
		//Set the editor value
		engine.setValue(content);
		//Listen to the editor value change event
		engine.on('change', () => {
			const value = engine.getValue();
			setContent(value);
			console.log(`value:${value}`);
		});
		//Set the engine instance
		setEngine(engine);
	}, []);

	return <div ref={ref} />;
};
export default EngineDemo;

Plugins

Import @aomao/plugin-bold bold plugin

import Bold from '@aomao/plugin-bold';

Add the Bold plugin to the engine

//Instantiate the engine
const engine = new Engine(ref.current, {
	plugins: [Bold],
});

Card

A card is a separate area in the editor. The UI and logic inside the card can be customized using React, Vue or other front-end libraries to customize the rendering content, and finally mount it to the editor.

Import the @aomao/plugin-codeblock code block plugin. The Language drop-down box of this plugin is rendered using React, so there is a distinction. Vue3 uses @aomao/plugin-codeblock-vue

import CodeBlock, { CodeBlockComponent } from '@aomao/plugin-codeblock';

Add the 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 to trigger it after pressing Space.

Toolbar

Import the @aomao/toolbar toolbar. Due to the complex interaction, the toolbar is basically rendered using React + Antd UI components, while Vue3 uses @aomao/toolbar-vue

Except for UI interaction, most of the work of the toolbar is just to call the engine to execute the corresponding plugin commands after different button events are triggered. In the case of complicated requirements or the need to re-customize the UI, it is easier to modify after the fork.

import Toolbar, { ToolbarPlugin, ToolbarComponent } from '@aomao/toolbar';

Add the ToolbarPlugin plugin and ToolbarComponent card component to the engine, which allows us to use the shortcut key / in the editor to wake up the card toolbar

//Instantiate the engine
const engine = new Engine(ref.current, {
	plugins: [ToolbarPlugin],
	cards: [ToolbarComponent],
});

Rendering toolbar, the toolbar has been configured with all plugins, here we only need to pass in the plugin name

return (
    ...
    {
        engine && (
            <Toolbar
                engine={engine}
                items={[
                    ['collapse'],
                    [
                        'bold',
                    ],
                ]}
            />
        )
    }
    ...
)

For more complex toolbar configuration, please check the document https://editor.aomao.com/config/toolbar

Collaborative editing

Use the MutationObserver to monitor the mutation of the html structure in the editable area (contenteditable root node) to reverse infer OT. Connect to ShareDB through Websocket, and then use commands to add, delete, modify, and check the data saved in ShareDB.

Interactive mode

Each editor acts as a Client through WebSocket and Server Communication and exchange of data in json0 format generated by the editor.

The server will keep a copy of the html structure data in the json format. After receiving the instructions from the client, it will modify the data, and finally forward it to each client.

Before enabling collaborative editing, we need to configure Client and Server

The server is a NodeJs environment, and a network service built using express + WebSocket.

Example

In the example, we have a relatively basic client code

View the complete React example

View the complete example of Vue3

View the complete example of Vue2

//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',
);

Project icon

Iconfont

Development

React

Need to install dependencies in `am-editor

//After the dependencies are installed, you only need to execute the following commands in the root directory

yarn start
  • packages engine and toolbar
  • plugins all plugins
  • api supports api access required by some plugins. By default, https://editor.aomao.com is used as the api service
  • ot-server collaborative server. Start: yarn dev

Visit localhost:7001 after startup

Vue

am-editor vue example

Vue example powered by modern-vue-template

Contribution

Thanks pleasedmiElena211314zb201307cheon for donation

Alipay

alipay

WeChat Pay

wechat

PayPal

https://paypal.me/aomaocom

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].