Code Monkey home page Code Monkey logo

red-axe / am-editor Goto Github PK

View Code? Open in Web Editor NEW
923.0 20.0 196.0 7.84 MB

A rich text editor that supports collaborative editing and allows for the free use of front-end common libraries such as React and Vue to extend and define plugins.

Home Page: https://editor.aomao.com

License: MIT License

TypeScript 86.30% JavaScript 1.24% CSS 8.15% HTML 0.03% Less 1.31% Vue 2.96%
rich-text-editor typescript contenteditable wysiwyg-editor collaborative-editor am-editor sharedb vue-editor react-editor editor

am-editor's Introduction

Here, we have a new rich text editor called Editable, which does not use the native editable property contenteditable, but instead uses a custom renderer. This approach allows us to better control the behavior of the 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

Vue2

Vue3

React

Vue2 Demo

Vue2 Nuxt Demo

Features

  • 🎁 Out-of-the-box solution with dozens of rich plugins to meet most needs
  • 🚀 Highly extensible, in addition to basic plugins for mark, inline, and block types, we also provide card components combined with front-end libraries like React and Vue to render plugin UI
  • 🎨 Rich multimedia support, not only supports images and audio/video, but also supports embedding multimedia content
  • 📝 Supports Markdown syntax
  • 🌍 Supports internationalization
  • 💻 Engine written purely in JavaScript, without relying on any front-end libraries, plugins can be rendered using front-end libraries like React and Vue. Can easily handle complex architecture
  • 👥 Built-in collaborative editing solution, lightweight configuration to use
  • 📱 Compatible with most latest mobile browsers

Plugins

Package Version Size description
@aomao/toolbar Toolbar, suitable for React
@aomao/toolbar-vue Toolbar, suitable for Vue3
am-editor-toolbar-vue2 Toolbar, suitable for Vue2
@aomao/plugin-alignment Alignment
@aomao/plugin-embed Embed URL
@aomao/plugin-backcolor Background color
@aomao/plugin-bold Bold
@aomao/plugin-code Inline code
@aomao/plugin-codeblock CodeBlock, suitable for React
@aomao/plugin-codeblock-vue CodeBlock, suitable for Vue3
am-editor-codeblock-vue2 CodeBlock, suitable for Vue2
@aomao/plugin-fontcolor Font color
@aomao/plugin-fontfamily Font Family
@aomao/plugin-fontsize Font Size
@aomao/plugin-heading Heading
@aomao/plugin-hr Horizontal rule
@aomao/plugin-indent Indentation
@aomao/plugin-italic Italic
@aomao/plugin-link Link, suitable for React
@aomao/plugin-link-vue Link, suitable for Vue3
am-editor-link-vue2 Link, suitable for Vue2
@aomao/plugin-line-height Line height
@aomao/plugin-mark Mark
@aomao/plugin-mention Mention
@aomao/plugin-orderedlist Ordered list
@aomao/plugin-paintformat Format painter
@aomao/plugin-quote Blockquote
@aomao/plugin-redo Redo
@aomao/plugin-removeformat Remove format
@aomao/plugin-selectall Select all
@aomao/plugin-status Status
@aomao/plugin-strikethrough Strikethrough
@aomao/plugin-sub Sub
@aomao/plugin-sup Sup
@aomao/plugin-tasklist Task list
@aomao/plugin-underline Underline
@aomao/plugin-undo Undo
@aomao/plugin-unorderedlist Unordered list
@aomao/plugin-image Image
@aomao/plugin-table Table
@aomao/plugin-file File
@aomao/plugin-mark-range Mark range
@aomao/plugin-math Mathematical formula
@aomao/plugin-video Video

Getting Started

Installation

The editor consists of the engine, toolbar, and plugins. The engine provides us with the core editing capability.

Use npm or yarn to install the engine package.

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

Usage

We'll start by outputting a "Hello world!" message as usual.

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 world!</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 the @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 separately defined area in the editor, with its UI and logic for rendering custom content inside the card using React, Vue, or other front-end libraries before being mounted onto the editor.

Introduce @aomao/plugin-codeblock, a code block plugin with a language drop-down that is rendered using React, which distinguishes it from Vue3 using @aomao/plugin-codeblock-vue.

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

Add the CodeBlock plugin and the 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. You can trigger it by typing the code block syntax at the beginning of a line in the editor, followed by a space and the language name, such as ```javascript.

Node Constraints

To manage nodes more conveniently and reduce complexity, the editor abstracts node properties and functionality and defines four types of nodes: mark, inline, block, and card. They are composed of different attributes, styles, or HTML structures, and are uniformly constrained using a schema.

A simple schema looks like this:

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

In addition, properties, styles, etc. can also be described, for example:

{
  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.

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

This open-source library listens to changes in the HTML structure of the editing area (contenteditable root node), uses MutationObserver to reverse-engineer the data structure, and connects and interacts with Yjs through WebSocket to achieve multi-user collaborative editing.

Interactive mode

Each editor, as a client, communicates and interacts with the server through the WebSocket function in the @aomao/plugin-yjs-websocket plugin.

  • @aomao/yjs implements the conversion of editor and Yjs data
  • @aomao/plugin-yjs-websocket provides the WebSocket client function of the editor and Yjs
  • @aomao/plugin-yjs-websocket/server provides the WebSocket server of Yjs, written in Node.js, and supports data storage using MongoDB and LevelDB.

Project icon

Iconfont

Development

React

Before using this open-source library, you need to install dependencies in the project root directory.

yarn install

lerna bootstrap

After installing the dependencies, you only need to execute the following command in the root directory to start the project:

yarn start

The development directory structure of this open-source library is as follows:

  • packages contains the engine and toolbar-related code
  • plugins contains all plugins
  • api provides API access required by some plugins, and uses https://editor.aomao.com as the default API service
  • yjs-server contains collaborative server code, which can be started by yarn dev.

Vue

am-editor vue example

Contribution

Thanks pleasedmiElena211314zb201307cheon for donation

Alipay

alipay

WeChat Pay

wechat

PayPal

https://paypal.me/aomaocom

am-editor's People

Contributors

big-camel avatar byoungd avatar chunyangyang avatar dlttsite avatar flordh avatar givebest avatar kim-xie avatar listar avatar myprelude avatar pipi-lv avatar qujh97 avatar smartwujun avatar yelmor avatar yesw6a avatar zgh035 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

am-editor's Issues

这个确定可以用吗???

作者您好,您确定这个真的可以用吗?真心发问,没别的意思。知道开源不易,但是这个我跑了一下实在是不能用啊
不知道你测试过没有
首先这个粘贴外部md文档或者是转化后的html,甚至是word复制过来的纯文档,格式都会错乱。搞得我都无语了

然后就是这个复制慢,改格式慢,一篇一两万字的纯文档,加个粗或者改个字体都肉眼可见的卡
实在是没办法用,实在不懂是我没配置好还是编辑器本身的问题。

工具栏的 collapse 按钮点击没有出现对应下拉面板

不知道是不是我项目的问题,工具栏的 collapse 按钮点击没有出现对应下拉面板,页面无报错提示,其他的按钮选项是没有问题的。
同时在编辑器中使用快捷键/ 是能出现下拉面板的。
代码是复制react demo进行改造的,删除了共享用户编辑和评论的部分,其他没有做任何改动。
如果不是bug,还望大神们帮忙解答解答是为啥
谢谢

FontSize and FontFamily tool wont work on pasted text and Seletion changed after command triggered

Describe the bug
Copy some text from the editor and paste them just after, then select them all (including the original text), use toolbar FontSize or FontFamily wont work properly.

To Reproduce
Steps to reproduce the behavior:

  1. Go to editor.aomao.com demo site
  2. copy some text and paste just after it
  3. select these text
  4. try to run FontSize or FontFamily tool

Expected behavior
We expected the effect takes on all the selection but Only the first paragraph change and the selection change too! You can found these texts are nested in span in dom.

Screenshots

am-editor.-.Google.Chrome.2021-07-11.11-48-31.mp4

Desktop (please complete the following information):

  • OS:window10
  • Browse chrome
  • Version 91.0.4472.124(stable) (64 bit)

中文

选择一段文字然后直接复制在他的后面,然后选中他们,尝试使用字体或者字号的功能时,发现只有第一段或前几段的文字产生了效果而不是选取的所有段落,而且选取发生了改变,如视频中的演示所示。

使用工具栏的话就不支持vite吗?

使用了工具栏(有引入antd-design-vue)
控制台报错
Uncaught Error: Dynamic require of "..../node_modules/ant-design-vue/lib/style/index.css" is not supported

在vue3项目中引入项目会遇到一些问题。

  1. 项目中的vue3版本如果和editor的版本不相同会出现多版本共存问题会有警告,并且toolbar不能正常渲染。
  2. 修改为相同版本后警告消除,toolbar中除了dropdown渲染的标题、字号、文本样式、对齐方式有效,其他的点击没有效果。
  3. button按钮执行triggerClick函数时,autoExecute始终为false,无法执行命令。

期望支持 行距lineHeight 功能

期望支持 行距lineHeight 功能

作为富文本编辑器 目前的功能已经比较全了 为了进一步完善整体功能 期望可以加入对 行距 设置的功能

非常感谢!

表格单元格使用Tab键移动光标至下一个单元格后,前一个单元格无法获得焦点

Describe the bug

safari下,不管是在中间或者末尾换行会出错排版错乱问题,chrome下无此问题。

To Reproduce
Steps to reproduce the behavior:

1、添加表格
2、在任意一个单元格内使用Tab键多次移动光标,直到下一个单元格
3、前一个单元格无法获得输入焦点

Expected behavior
排版正常

Screenshots
2021-08-19 11 18 40

Desktop (please complete the following information):

  • OS: MacOS Mojave 10.14.6
  • Browser: safari,chrome
  • Version:14.1.2

建议添加警告提示组件

警告提示在文档编写中,还是挺实用的,可以考虑添加,类型这种antd的 风格:
image

或者是vue官方文档的这种风格:

image
image
image

建议增加的几个功能

  • 1、增加支持段落TOC功能
  • 2、支持复制粘贴md文件,自动转换
  • 3、增加附件插件
  • 4、增加文字选择评论功能

工具栏图片icon不显示

微信图片_20211112092500
如图所示,demo里的工具栏图标不显示。还有就是工具栏插件在项目里使用后图标还是不显示,作者辛苦看下,点赞

建议添加流程图插件,并且适配markdown类型

md:

st=>start: 开始框
op=>operation: 处理框
cond=>condition: 判断框(是或否?)
sub1=>subroutine: 子流程
io=>inputoutput: 输入输出框
e=>end: 结束框
st->op->cond
cond(yes)->io->e
cond(no)->sub1(right)->op

image

希望可以支持nuxt.js

大多数主流富文本编辑器都可以支持,这个在nuxt.js里面引入,报Cannot find module 'xxx'错误,engine文件通过vue实例化引入后,可以展示编辑器,但是例如Bold扩展还是报以上错误,这个编辑器很不错,希望早日可以实现。🤔

任务列表在safari下换行会错乱

Describe the bug

safari下,不管是在中间或者末尾换行会出错排版错乱问题,chrome下无此问题。

To Reproduce
Steps to reproduce the behavior:

1、输入文字
2、选中文字,选择任务列表工具
3、在末尾项换行,中间项亦可
4、换行前的几项跳变缩进(现象)

Expected behavior
排版正常

Screenshots

2021-08-19 11 17 48

Desktop (please complete the following information):

  • OS: MacOS Mojave 10.14.6
  • Browser: safari
  • Version:14.1.2

vue必须得绑定antd吗

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

  • OS: [e.g. iOS]
  • Browser [e.g. chrome, safari]
  • Version [e.g. 22]

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]
  • Browser [e.g. stock browser, safari]
  • Version [e.g. 22]

Additional context
Add any other context about the problem here.

我在自定义antdv主题时。 异步组件引入编辑器时会发生个别组件样式会被编辑器内部给覆盖了

@itellyou-com
你好。我在自定义antdv主题时。 异步组件引入编辑器时会发生个别组件样式会被编辑器内部给覆盖了。我看了下源码

这些用到antdv的组件。引入组件样式的地方。 不知道能否去引入ant-design-vue/es/.../style/index.less 文件。这样编辑器也能同时应用我自定义主题后的颜色和样式。 不知道可不可以
image

Originally posted by @Thornchg in #16 (comment)

关于用户加入或退出改变

是怎么判断用户加入的?
otClient.on('membersChange', members => {
members.value = members;
});
并没有触发这个事件,使用的是Vue

公式内容闪动

Describe the bug

公式内容会跳动

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Screenshots

2021-06-10 19 51 17

Desktop (please complete the following information):

  • OS: Mojave 10.14.6
  • Browser: safari、edge
  • Version 14.3.3、 89.0.774.68

是不是只能用ts?

Describe the bug
image

To Reproduce
vue3.0项目,按vue案例中的写法,改成js后,控制台有警告,toolBar无法渲染

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.