编辑器开发

This commit is contained in:
暮光:城中城
2020-06-07 23:12:48 +08:00
parent 0965f44866
commit cafe72fcc2
9 changed files with 183 additions and 19 deletions

View File

@@ -9,12 +9,12 @@
<div class="mg-editor-box">
<div ref="mgEditor" class="mg-editor" contenteditable="true"></div>
<div class="mg-editor-toolbar" :style="getMgEditorToolbarStyle(selectionInfo)">
<span class="iconfont icon-h1" @click.stop="handleToolbarHn('h1')"></span>
<span class="iconfont icon-h2" @click.stop="handleToolbarHn('h2')"></span>
<span class="iconfont icon-h3" @click.stop="handleToolbarHn('h3')"></span>
<span class="iconfont icon-h1" @click="handleToolbarHn('h1')"></span>
<span class="iconfont icon-h2" @click="handleToolbarHn('h2')"></span>
<span class="iconfont icon-h3" @click="handleToolbarHn('h3')"></span>
<span class="iconfont icon-hn"></span>
<span class="iconfont icon-border"></span>
<span class="iconfont icon-delete"></span>
<span class="iconfont icon-border" @click="handleToolbarBorder()"></span>
<span class="iconfont icon-delete" @click="handleToolbarStrikeThrough()"></span>
<span class="iconfont icon-backcolor"></span>
<span class="iconfont icon-orderedlist"></span>
<span class="iconfont icon-unorderedlist"></span>
@@ -30,9 +30,12 @@
import "./css/MgEditorIconfont.css";
import utilPast from './util/past';
import utilBase from './util/util';
import utilSelection from './util/selection';
import toolbarHn from "./toolbar/hn";
import toolbarCommon from './toolbar/common';
import toolbarCodeList from "./toolbar/inlineCodeList";
import toolbarBorder from "./toolbar/border";
import toolbarStrikeThrough from "./toolbar/strikeThrough";
const $ = require("jquery");
@@ -121,7 +124,7 @@
let domInnerText = handleClassDom.innerText;
let selectRange = window.getSelection().getRangeAt(0);
// 光标在行的最后才执行此操作,否则用系统默认的
if (selectRange.startOffset == selectRange.endOffset && selectRange.endOffset == domInnerText.length) {
if (utilSelection.isSelectionEmpty() && selectRange.endOffset == domInnerText.length) {
e.preventDefault();
let newEle = $(`<div><br/></div>`)[0];
$(handleClassDom).after(newEle);
@@ -139,7 +142,7 @@
let nowContainer = window.getSelection().getRangeAt(0).commonAncestorContainer;
let lineText = nowContainer.data;
if (lineText == '```') {
toolbarCodeList.createCodeListBlock();
toolbarCodeList.handleCodeList();
}
// 判断是否是在最后一行输入,如果是就再在最后加一行
let locate = this.findParentClassDom(nowContainer, 'locate');
@@ -176,9 +179,14 @@
domHaveClass(container, cls) {
return container && container.classList && container.classList.contains(cls);
},
handleToolbarBorder() {
toolbarBorder.handleBorder();
},
handleToolbarStrikeThrough() {
toolbarStrikeThrough.handleStrikeThrough();
},
handleToolbarHn(hn) {
toolbarHn.toolbarHn(hn);
this.selectionInfo.haveSelect = false;
toolbarHn.handleHn(hn);
},
getMgEditorToolbarStyle(selectionInfo) {
let style = {};

View File

@@ -145,3 +145,11 @@
}
/*Hn样式-E-*/
.mg-editor .border {
font-weight: bold;
}
.mg-editor .strikethrough {
text-decoration: line-through;
}

View File

@@ -0,0 +1,12 @@
import toolbarCommon from './common';
const $ = require("jquery");
export default {
handleBorder() {
toolbarCommon.selectionAddClass("border");
}
}

View File

@@ -1,3 +1,5 @@
import utilSelection from "../util/selection";
export default {
getSelectionContainer(judgeRoot) {
let container = window.getSelection().getRangeAt(0).commonAncestorContainer;
@@ -9,11 +11,85 @@ export default {
}
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) {
return this.domHaveClass(container, "mg-editor");
},
domHaveClass(container, 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);
},
}

View File

@@ -1,20 +1,38 @@
import toolbarCommon from './common';
import utilSelection from "../util/selection";
const $ = require("jquery");
export default {
toolbarHn(hn) {
handleHn(hn) {
// 找到内容生成div把每一行包住
let container = toolbarCommon.getSelectionContainer(true);
if (container == null) return;
let innerTextArr = container.innerText.split("\n");
if (innerTextArr.length >= 1) {
innerTextArr.filter(item => !!item).forEach(item => {
$(container).before(`<div class="head head-${hn}">${item}</div>`);
// let container = toolbarCommon.getSelectionContainer(true);
// if (container == null) return;
// let innerTextArr = container.innerText.split("\n");
// if (innerTextArr.length >= 1) {
// innerTextArr.filter(item => !!item).forEach(item => {
// $(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;
}
// 最后把当前行移出掉
container.remove();
document.execCommand('styleWithCSS', false, false);
}
}

View File

@@ -4,7 +4,7 @@ import utilBase from '../util/util';
const $ = require("jquery");
export default {
createCodeListBlock() {
handleCodeList() {
let containerNow = window.getSelection().getRangeAt(0).commonAncestorContainer;
let divEle = this.findRootDomOnNotCode(containerNow);
if (divEle == null) return;

View File

@@ -0,0 +1,8 @@
import toolbarCommon from "./common";
export default {
handleStrikeThrough() {
toolbarCommon.selectionAddClass("strikethrough");
}
}

View File

@@ -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;
},
}

View File

@@ -0,0 +1,12 @@
/**
* 本文件内容拷贝自https://github.com/wangfupeng1988/wangEditor
* zyplayer-doc在此基础上有稍作修改
*/
import utilBase from './util'
export default {
// 获取粘贴的纯文本
getPasteText(e) {
},
}