前言
- 本文主要记录在React项目中集成Editor.md,且需要支持图片跨域上传的情况
- 非React项目集成,可直接移步Editor.md
- React项目,不需要支持图片跨域上传,可直接移步React Component Based on Editor.md
Editor.md 简介
Editor.md 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。
主要特性
- 支持通用 Markdown / CommonMark 和 GFM (GitHub Flavored Markdown) 风格的语法,也可变身为代码编辑器;
- 支持实时预览、图片(跨域)上传、预格式文本/代码/表格插入、代码折叠、跳转到行、搜索替换、只读模式、自定义样式主题和多语言语法高亮等功能;
- 支持 ToC(Table of Contents)、Emoji表情、Task lists、@链接等 Markdown 扩展语法;
- 支持 TeX 科学公式(基于 KaTeX)、流程图 Flowchart 和 时序图 Sequence Diagram;
- 支持识别和解析 HTML 标签,并且支持自定义过滤标签及属性解析,具有可靠的安全性和几乎无限的扩展性;
- 支持 AMD / CMD 模块化加载(支持 Require.js & Sea.js),并且支持自定义扩展插件;
- 兼容主流的浏览器(IE8+)和 Zepto.js,且支持 iPad 等平板设备;
更多详情请参考:README & Examples
React项目中集成 Editor.md
1、下载editor.md源码
源码目录如下:
- examples文件中是所有示例
- lib中是editor.md所依赖的第三方js资源
- plugins中是如emoji表情支持、代码格式化等插件
2、在项目中新建editormd文件夹,存放精简后的代码
3、在template.html中,引入相关的css和js
css:
<link rel="stylesheet" href="/editormd/css/editormd.min.css" />
js:
<script src="/editormd/js/jquery.min.js"></script>
<script src="/editormd/editormd.min.js"></script>
4、使用wrap-md-editor组件
- 基于Editor.md开发的React Component
- 源码React Component Based on Editor.md
4.1 基本用法
Install
npm install wrap-md-editor -S
Create a Markdown editor
import React, {Component} from 'react';
import {render} from 'react-dom';
import Editor from 'wrap-md-editor';
render(
<Editor config={
{
markdown: // testEditor.getMarkdown().replace(/`/g, '\`')
`## Test
```
console.log('what can i do for you')
```
# 123123`,
onload: (editor, func) => {
let md = editor.getMarkdown();
let html = editor.getHTML();
debugger
}
}
}/>,
document.querySelector('#root')
);
Markdown to HTML
import React, {Component} from 'react';
import {render} from 'react-dom';
import Editor from 'wrap-md-editor';
render(
<Editor.EditorShow config={
{
markdown: // testEditor.getMarkdown().replace(/`/g, '\\`')
`## Test
\`\`\`
console.log('what can i do for you')
\`\`\`
# 123123`
}
}/>,
document.querySelector('#root')
);
4.2 图片上传
- 要支持图片上传,需要修改wrap-md-editor组件的源码
- 核心点就是我们采用ajax方法直接上传,然后获取返回值,进行赋值
1、下载wrap-md-editor源码,将dist/index.js文件,放到项目目录中,修改dist/index.js中defaultConfig配置
如下图所示:
2、修改组件的引用路径
// import Editor from 'wrap-md-editor'; // 引用wrap-md-editor组件
import Editor from '../editormd'; // 注意:这里是你 存放wrap-md-editor源码的路径
3、修改文件 editormd/plugins/image-dialog/image-dialog.js中的uploadIframe.onload函数,代码如下
uploadIframe.onload = function() {
loading(false);
// 注释的是官方写法
// var body = (uploadIframe.contentWindow ? uploadIframe.contentWindow : uploadIframe.contentDocument).document.body;
// var json = (body.innerText) ? body.innerText : ( (body.textContent) ? body.textContent : null);
//
// json = (typeof JSON.parse !== "undefined") ? JSON.parse(json) : eval("(" + json + ")");
//
// if(!settings.crossDomainUpload)
// {
// if (json.success === 1)
// {
// dialog.find("[data-url]").val(json.url);
// }
// else
// {
// alert(json.message);
// }
// }
//
// return false;
// 这是ajax的写法
var formData = new FormData();
formData.append("file",$("#editormd-image-file")[0].files[0]);
var action = settings.imageUploadURL + (settings.imageUploadURL.indexOf("?") >= 0 ? "&" : "?") + "guid=" + guid;
$.ajax({
type:"post",
url:action,
data:formData,
dataType:"json",
async:false,
processData : false, // 使数据不做处理
contentType : false, // 不要设置Content-Type请求头
success:function(res){
// 成功拿到结果放到这个函数 data就是拿到的结果
if(res.success == 1){
dialog.find("[data-url]").val(res.imgUrl);
}else{
alert(res.message);
}
},
});
return false;
};
Editor.md 配置参数
{
mode : "gfm", // gfm or markdown
name : "", // Form element name for post
value : "", // value for CodeMirror, if mode not gfm/markdown
theme : "", // Editor.md self themes, before v1.5.0 is CodeMirror theme, default empty
editorTheme : "default", // Editor area, this is CodeMirror theme at v1.5.0
previewTheme : "", // Preview area theme, default empty
markdown : "", // Markdown source code
appendMarkdown : "", // if in init textarea value not empty, append markdown to textarea
width : "100%",
height : "100%",
path : "./lib/", // Dependents module file directory
pluginPath : "", // If this empty, default use settings.path + "../plugins/"
delay : 300, // Delay parse markdown to html, Uint : ms
autoLoadModules : true, // Automatic load dependent module files
watch : true,
placeholder : "Enjoy Markdown! coding now...",
gotoLine : true, // Enable / disable goto a line
codeFold : false,
autoHeight : false,
autoFocus : true, // Enable / disable auto focus editor left input area
autoCloseTags : true,
searchReplace : true, // Enable / disable (CodeMirror) search and replace function
syncScrolling : true, // options: true | false | "single", default true
readOnly : false, // Enable / disable readonly mode
tabSize : 4,
indentUnit : 4,
lineNumbers : true, // Display editor line numbers
lineWrapping : true,
autoCloseBrackets : true,
showTrailingSpace : true,
matchBrackets : true,
indentWithTabs : true,
styleSelectedText : true,
matchWordHighlight : true, // options: true, false, "onselected"
styleActiveLine : true, // Highlight the current line
dialogLockScreen : true,
dialogShowMask : true,
dialogDraggable : true,
dialogMaskBgColor : "#fff",
dialogMaskOpacity : 0.1,
fontSize : "13px",
saveHTMLToTextarea : false, // If enable, Editor will create a <textarea name="{editor-id}-html-code"> tag save HTML code for form post to server-side.
disabledKeyMaps : [],
onload : function() {},
onresize : function() {},
onchange : function() {},
onwatch : null,
onunwatch : null,
onpreviewing : function() {},
onpreviewed : function() {},
onfullscreen : function() {},
onfullscreenExit : function() {},
onscroll : function() {},
onpreviewscroll : function() {},
imageUpload : false, // Enable/disable upload
imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"],
imageUploadURL : "", // Upload url
crossDomainUpload : false, // Enable/disable Cross-domain upload
uploadCallbackURL : "", // Cross-domain upload callback url
toc : true, // Table of contents
tocm : false, // Using [TOCM], auto create ToC dropdown menu
tocTitle : "", // for ToC dropdown menu button
tocDropdown : false, // Enable/disable Table Of Contents dropdown menu
tocContainer : "", // Custom Table Of Contents Container Selector
tocStartLevel : 1, // Said from H1 to create ToC
htmlDecode : false, // Open the HTML tag identification
pageBreak : true, // Enable parse page break [========]
atLink : true, // for @link
emailLink : true, // for email address auto link
taskList : false, // Enable Github Flavored Markdown task lists
emoji : false, // :emoji: , Support Github emoji, Twitter Emoji (Twemoji);
// Support FontAwesome icon emoji :fa-xxx: > Using fontAwesome icon web fonts;
// Support Editor.md logo icon emoji :editormd-logo: :editormd-logo-1x: > 1~8x;
tex : false, // TeX(LaTeX), based on KaTeX
flowChart : false, // flowChart.js only support IE9+
sequenceDiagram : false, // sequenceDiagram.js only support IE9+
previewCodeHighlight : true, // Enable / disable code highlight of editor preview area
toolbar : true, // show or hide toolbar
toolbarAutoFixed : true, // on window scroll auto fixed position
toolbarIcons : "full", // Toolbar icons mode, options: full, simple, mini, See `editormd.toolbarModes` property.
toolbarTitles : {},
toolbarHandlers : {
ucwords : function() {
return editormd.toolbarHandlers.ucwords;
},
lowercase : function() {
return editormd.toolbarHandlers.lowercase;
}
},
toolbarCustomIcons : { // using html tag create toolbar icon, unused default <a> tag.
lowercase : "<a href=\"javascript:;\" title=\"Lowercase\" unselectable=\"on\"><i class=\"fa\" name=\"lowercase\" style=\"font-size:24px;margin-top: -10px;\">a</i></a>",
"ucwords" : "<a href=\"javascript:;\" title=\"ucwords\" unselectable=\"on\"><i class=\"fa\" name=\"ucwords\" style=\"font-size:20px;margin-top: -3px;\">Aa</i></a>"
},
toolbarIconTexts : {},
lang : { // Language data, you can custom your language.
name : "zh-cn",
description : "开源在线Markdown编辑器<br/>Open source online Markdown editor.",
tocTitle : "目录",
toolbar : {
//...
},
button: {
//...
},
dialog : {
//...
}
//...
}
}