编辑器开发
This commit is contained in:
@@ -9,12 +9,12 @@
|
|||||||
<div class="mg-editor-box">
|
<div class="mg-editor-box">
|
||||||
<div ref="mgEditor" class="mg-editor" contenteditable="true"></div>
|
<div ref="mgEditor" class="mg-editor" contenteditable="true"></div>
|
||||||
<div class="mg-editor-toolbar" :style="getMgEditorToolbarStyle(selectionInfo)">
|
<div class="mg-editor-toolbar" :style="getMgEditorToolbarStyle(selectionInfo)">
|
||||||
<span class="iconfont icon-h1" @click.stop="handleToolbarHn('h1')"></span>
|
<span class="iconfont icon-h1" @click="handleToolbarHn('h1')"></span>
|
||||||
<span class="iconfont icon-h2" @click.stop="handleToolbarHn('h2')"></span>
|
<span class="iconfont icon-h2" @click="handleToolbarHn('h2')"></span>
|
||||||
<span class="iconfont icon-h3" @click.stop="handleToolbarHn('h3')"></span>
|
<span class="iconfont icon-h3" @click="handleToolbarHn('h3')"></span>
|
||||||
<span class="iconfont icon-hn"></span>
|
<span class="iconfont icon-hn"></span>
|
||||||
<span class="iconfont icon-border"></span>
|
<span class="iconfont icon-border" @click="handleToolbarBorder()"></span>
|
||||||
<span class="iconfont icon-delete"></span>
|
<span class="iconfont icon-delete" @click="handleToolbarStrikeThrough()"></span>
|
||||||
<span class="iconfont icon-backcolor"></span>
|
<span class="iconfont icon-backcolor"></span>
|
||||||
<span class="iconfont icon-orderedlist"></span>
|
<span class="iconfont icon-orderedlist"></span>
|
||||||
<span class="iconfont icon-unorderedlist"></span>
|
<span class="iconfont icon-unorderedlist"></span>
|
||||||
@@ -30,9 +30,12 @@
|
|||||||
import "./css/MgEditorIconfont.css";
|
import "./css/MgEditorIconfont.css";
|
||||||
import utilPast from './util/past';
|
import utilPast from './util/past';
|
||||||
import utilBase from './util/util';
|
import utilBase from './util/util';
|
||||||
|
import utilSelection from './util/selection';
|
||||||
import toolbarHn from "./toolbar/hn";
|
import toolbarHn from "./toolbar/hn";
|
||||||
import toolbarCommon from './toolbar/common';
|
import toolbarCommon from './toolbar/common';
|
||||||
import toolbarCodeList from "./toolbar/inlineCodeList";
|
import toolbarCodeList from "./toolbar/inlineCodeList";
|
||||||
|
import toolbarBorder from "./toolbar/border";
|
||||||
|
import toolbarStrikeThrough from "./toolbar/strikeThrough";
|
||||||
|
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
|
|
||||||
@@ -121,7 +124,7 @@
|
|||||||
let domInnerText = handleClassDom.innerText;
|
let domInnerText = handleClassDom.innerText;
|
||||||
let selectRange = window.getSelection().getRangeAt(0);
|
let selectRange = window.getSelection().getRangeAt(0);
|
||||||
// 光标在行的最后才执行此操作,否则用系统默认的
|
// 光标在行的最后才执行此操作,否则用系统默认的
|
||||||
if (selectRange.startOffset == selectRange.endOffset && selectRange.endOffset == domInnerText.length) {
|
if (utilSelection.isSelectionEmpty() && selectRange.endOffset == domInnerText.length) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let newEle = $(`<div><br/></div>`)[0];
|
let newEle = $(`<div><br/></div>`)[0];
|
||||||
$(handleClassDom).after(newEle);
|
$(handleClassDom).after(newEle);
|
||||||
@@ -139,7 +142,7 @@
|
|||||||
let nowContainer = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
let nowContainer = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
||||||
let lineText = nowContainer.data;
|
let lineText = nowContainer.data;
|
||||||
if (lineText == '```') {
|
if (lineText == '```') {
|
||||||
toolbarCodeList.createCodeListBlock();
|
toolbarCodeList.handleCodeList();
|
||||||
}
|
}
|
||||||
// 判断是否是在最后一行输入,如果是就再在最后加一行
|
// 判断是否是在最后一行输入,如果是就再在最后加一行
|
||||||
let locate = this.findParentClassDom(nowContainer, 'locate');
|
let locate = this.findParentClassDom(nowContainer, 'locate');
|
||||||
@@ -176,9 +179,14 @@
|
|||||||
domHaveClass(container, cls) {
|
domHaveClass(container, cls) {
|
||||||
return container && container.classList && container.classList.contains(cls);
|
return container && container.classList && container.classList.contains(cls);
|
||||||
},
|
},
|
||||||
|
handleToolbarBorder() {
|
||||||
|
toolbarBorder.handleBorder();
|
||||||
|
},
|
||||||
|
handleToolbarStrikeThrough() {
|
||||||
|
toolbarStrikeThrough.handleStrikeThrough();
|
||||||
|
},
|
||||||
handleToolbarHn(hn) {
|
handleToolbarHn(hn) {
|
||||||
toolbarHn.toolbarHn(hn);
|
toolbarHn.handleHn(hn);
|
||||||
this.selectionInfo.haveSelect = false;
|
|
||||||
},
|
},
|
||||||
getMgEditorToolbarStyle(selectionInfo) {
|
getMgEditorToolbarStyle(selectionInfo) {
|
||||||
let style = {};
|
let style = {};
|
||||||
|
|||||||
@@ -145,3 +145,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*Hn样式-E-*/
|
/*Hn样式-E-*/
|
||||||
|
|
||||||
|
.mg-editor .border {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mg-editor .strikethrough {
|
||||||
|
text-decoration: line-through;
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
import toolbarCommon from './common';
|
||||||
|
|
||||||
|
const $ = require("jquery");
|
||||||
|
|
||||||
|
export default {
|
||||||
|
handleBorder() {
|
||||||
|
toolbarCommon.selectionAddClass("border");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import utilSelection from "../util/selection";
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
getSelectionContainer(judgeRoot) {
|
getSelectionContainer(judgeRoot) {
|
||||||
let container = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
let container = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
||||||
@@ -9,11 +11,85 @@ export default {
|
|||||||
}
|
}
|
||||||
return container;
|
return container;
|
||||||
},
|
},
|
||||||
|
getRootDom(nowDom) {
|
||||||
|
let newDom = this.getRealElem(nowDom);
|
||||||
|
if (!newDom || this.isRootBox(nowDom)) return null;
|
||||||
|
if (this.isRootBox(newDom.parentNode)) return newDom;
|
||||||
|
return this.getRootDom(newDom.parentNode);
|
||||||
|
},
|
||||||
|
getRealElem: function (elem) {
|
||||||
|
return !elem || elem.nodeType === 1 ? elem : elem.parentNode;
|
||||||
|
},
|
||||||
isRootBox(container) {
|
isRootBox(container) {
|
||||||
return this.domHaveClass(container, "mg-editor");
|
return this.domHaveClass(container, "mg-editor");
|
||||||
},
|
},
|
||||||
domHaveClass(container, cls) {
|
domHaveClass(container, cls) {
|
||||||
return container && container.classList && container.classList.contains(cls);
|
return container && container.classList && container.classList.contains(cls);
|
||||||
},
|
},
|
||||||
|
selectionAddClass(cls) {
|
||||||
|
let range = window.getSelection().getRangeAt(0);
|
||||||
|
let nowContainer = range.startContainer;
|
||||||
|
let newDomArr = [], innerText, newDom, haveEndDom = false;
|
||||||
|
|
||||||
|
while (nowContainer != null) {
|
||||||
|
innerText = nowContainer.data || nowContainer.innerText;
|
||||||
|
if (nowContainer == range.startContainer && nowContainer == range.endContainer) {
|
||||||
|
innerText = innerText.substring(range.startOffset, range.endOffset);
|
||||||
|
} else if (nowContainer == range.startContainer) {
|
||||||
|
innerText = innerText.substring(range.startOffset, innerText.length);
|
||||||
|
} else if (nowContainer == range.endContainer || nowContainer.firstChild == range.endContainer) {
|
||||||
|
innerText = innerText.substring(0, range.endOffset);
|
||||||
|
}
|
||||||
|
newDom = document.createElement("span");
|
||||||
|
var classList = utilSelection.getRealElem(nowContainer).classList;
|
||||||
|
if (classList) {
|
||||||
|
newDom.classList = classList;
|
||||||
|
}
|
||||||
|
newDom.classList.add(cls);
|
||||||
|
newDom.innerText = innerText;
|
||||||
|
newDomArr.push(newDom);
|
||||||
|
if (nowContainer == range.endContainer || nowContainer.firstChild == range.endContainer) {
|
||||||
|
haveEndDom = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nowContainer = nowContainer.nextSibling || utilSelection.getRealElem(nowContainer).nextSibling;
|
||||||
|
}
|
||||||
|
if (!haveEndDom) {
|
||||||
|
nowContainer = range.endContainer;
|
||||||
|
innerText = nowContainer.data || nowContainer.innerText;
|
||||||
|
innerText = innerText.substring(0, range.endOffset);
|
||||||
|
newDom = document.createElement("span");
|
||||||
|
if (nowContainer.classList) {
|
||||||
|
newDom.classList = nowContainer.classList;
|
||||||
|
}
|
||||||
|
newDom.classList.add(cls);
|
||||||
|
newDom.innerText = innerText;
|
||||||
|
newDomArr.push(newDom);
|
||||||
|
}
|
||||||
|
let appendHtml = '';
|
||||||
|
for (let i = 0; i < newDomArr.length; i++) {
|
||||||
|
var item = newDomArr[i];
|
||||||
|
if (i + 1 < newDomArr.length) {
|
||||||
|
var itemNext = newDomArr[i + 1];
|
||||||
|
if (itemNext.classList.value == item.classList.value) {
|
||||||
|
i++;
|
||||||
|
item.innerText += itemNext.innerText;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let removeCls = [];
|
||||||
|
item.classList.forEach(cls => {
|
||||||
|
if (cls.startsWith("head-") || cls == 'head') {
|
||||||
|
removeCls.push(cls);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
for (let j = 0; j < removeCls.length; j++) {
|
||||||
|
item.classList.remove(removeCls[j]);
|
||||||
|
}
|
||||||
|
appendHtml += item.outerHTML;
|
||||||
|
}
|
||||||
|
document.execCommand('styleWithCSS', false, false);
|
||||||
|
document.execCommand('insertHTML', false, appendHtml);
|
||||||
|
},
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,38 @@
|
|||||||
import toolbarCommon from './common';
|
import toolbarCommon from './common';
|
||||||
|
import utilSelection from "../util/selection";
|
||||||
|
|
||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
toolbarHn(hn) {
|
handleHn(hn) {
|
||||||
// 找到内容,生成div把每一行包住
|
// 找到内容,生成div把每一行包住
|
||||||
let container = toolbarCommon.getSelectionContainer(true);
|
// let container = toolbarCommon.getSelectionContainer(true);
|
||||||
if (container == null) return;
|
// if (container == null) return;
|
||||||
let innerTextArr = container.innerText.split("\n");
|
// let innerTextArr = container.innerText.split("\n");
|
||||||
if (innerTextArr.length >= 1) {
|
// if (innerTextArr.length >= 1) {
|
||||||
innerTextArr.filter(item => !!item).forEach(item => {
|
// innerTextArr.filter(item => !!item).forEach(item => {
|
||||||
$(container).before(`<div class="head head-${hn}">${item}</div>`);
|
// $(container).before(`<div class="head head-${hn}">${item}</div>`);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// // 最后把当前行移出掉
|
||||||
|
// container.remove();
|
||||||
|
let range = window.getSelection().getRangeAt(0);
|
||||||
|
let nowContainer = range.startContainer;
|
||||||
|
while (nowContainer != null) {
|
||||||
|
let rootDom = toolbarCommon.getRootDom(nowContainer);
|
||||||
|
if (rootDom == null) return;
|
||||||
|
rootDom.classList.forEach(cls => {
|
||||||
|
if (cls.startsWith("head-")) {
|
||||||
|
rootDom.classList.remove(cls);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
rootDom.classList.add('head', 'head-' + hn);
|
||||||
|
if (nowContainer == range.endContainer || nowContainer.firstChild == range.endContainer) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
nowContainer = nowContainer.nextSibling || utilSelection.getRealElem(nowContainer).nextSibling;
|
||||||
}
|
}
|
||||||
// 最后把当前行移出掉
|
document.execCommand('styleWithCSS', false, false);
|
||||||
container.remove();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import utilBase from '../util/util';
|
|||||||
const $ = require("jquery");
|
const $ = require("jquery");
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
createCodeListBlock() {
|
handleCodeList() {
|
||||||
let containerNow = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
let containerNow = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
||||||
let divEle = this.findRootDomOnNotCode(containerNow);
|
let divEle = this.findRootDomOnNotCode(containerNow);
|
||||||
if (divEle == null) return;
|
if (divEle == null) return;
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import toolbarCommon from "./common";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
handleStrikeThrough() {
|
||||||
|
toolbarCommon.selectionAddClass("strikethrough");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
/**
|
||||||
|
* 本文件内容拷贝自:https://github.com/wangfupeng1988/wangEditor
|
||||||
|
* zyplayer-doc在此基础上有稍作修改
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// 选区是否为空
|
||||||
|
isSelectionEmpty: function () {
|
||||||
|
let range = window.getSelection().getRangeAt(0);
|
||||||
|
if (range && range.startContainer) {
|
||||||
|
if (range.startContainer === range.endContainer) {
|
||||||
|
if (range.startOffset === range.endOffset) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
getRealElem: function (elem) {
|
||||||
|
return !elem || elem.nodeType === 1 ? elem : elem.parentNode;
|
||||||
|
},
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* 本文件内容拷贝自:https://github.com/wangfupeng1988/wangEditor
|
||||||
|
* zyplayer-doc在此基础上有稍作修改
|
||||||
|
*/
|
||||||
|
|
||||||
|
import utilBase from './util'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
// 获取粘贴的纯文本
|
||||||
|
getPasteText(e) {
|
||||||
|
},
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user