编辑器增加撤销、重做功能开发
This commit is contained in:
@@ -16,7 +16,7 @@
|
|||||||
<template v-else-if="!!item.text">{{item.text}}</template>
|
<template v-else-if="!!item.text">{{item.text}}</template>
|
||||||
<br v-else/>
|
<br v-else/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="item.type=='locate'" :class="item.cls" @click.stop="domClick(item, $event)">
|
<div v-else-if="item.type=='locate'" :class="item.cls" :index="index" @click.stop="domClick(item, $event)">
|
||||||
<br/>
|
<br/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -91,7 +91,7 @@
|
|||||||
this.userInput.addEventListener('keydown', e => {
|
this.userInput.addEventListener('keydown', e => {
|
||||||
if (e.which == 13) {
|
if (e.which == 13) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.editDom.keyEnter(this.editorDom, this.editorRange);
|
this.editDom.keyEnter(this.editorDom, this.editorRange, this.undoRedo);
|
||||||
} else if (e.keyCode == 90 && e.ctrlKey) {
|
} else if (e.keyCode == 90 && e.ctrlKey) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this.undoRedo.undo();
|
this.undoRedo.undo();
|
||||||
@@ -164,6 +164,7 @@
|
|||||||
if (lastDom.type != 'locate') {
|
if (lastDom.type != 'locate') {
|
||||||
lastDom = new Dom('locate', 'locate');
|
lastDom = new Dom('locate', 'locate');
|
||||||
this.editorDom.push(lastDom);
|
this.editorDom.push(lastDom);
|
||||||
|
this.undoRedo.execute(2, this.editorDom.length - 1, JSON.stringify(lastDom), '');
|
||||||
}
|
}
|
||||||
setTimeout(() => event.target.lastChild.click(), 100);
|
setTimeout(() => event.target.lastChild.click(), 100);
|
||||||
},
|
},
|
||||||
@@ -220,10 +221,12 @@
|
|||||||
userInputDataChange() {
|
userInputDataChange() {
|
||||||
if (!this.userInputData) return;
|
if (!this.userInputData) return;
|
||||||
// 如果在最后一个div里面输入,则改为非最后一个,然后在最后再加一行
|
// 如果在最后一个div里面输入,则改为非最后一个,然后在最后再加一行
|
||||||
|
let domNew;
|
||||||
if (this.editDom.type == 'locate') {
|
if (this.editDom.type == 'locate') {
|
||||||
this.editDom.type = 'text';
|
this.editDom.type = 'text';
|
||||||
this.editDom.removeClass('locate');
|
this.editDom.removeClass('locate');
|
||||||
this.editorDom.push(new Dom('locate', 'locate'));
|
domNew = new Dom('locate', 'locate');
|
||||||
|
this.editorDom.push(domNew);
|
||||||
}
|
}
|
||||||
let beforeJson = JSON.stringify(this.editDom);
|
let beforeJson = JSON.stringify(this.editDom);
|
||||||
let oldText = this.editDom.text || '';
|
let oldText = this.editDom.text || '';
|
||||||
@@ -244,6 +247,10 @@
|
|||||||
let editDomNode = toolbarCommon.getRootDom(this.editDom.target);
|
let editDomNode = toolbarCommon.getRootDom(this.editDom.target);
|
||||||
let editIndex = parseInt(editDomNode.getAttribute("index"));
|
let editIndex = parseInt(editDomNode.getAttribute("index"));
|
||||||
this.undoRedo.execute(1, editIndex, beforeJson, afterJson);
|
this.undoRedo.execute(1, editIndex, beforeJson, afterJson);
|
||||||
|
// 如果在最后一个div里面输入,则改为非最后一个,然后在最后再加一行
|
||||||
|
if (!!domNew) {
|
||||||
|
this.undoRedo.execute(2, this.editorDom.length - 1, JSON.stringify(domNew), '');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
handleToolbarBold() {
|
handleToolbarBold() {
|
||||||
for (let i = this.editorRange.startDomIndex; i < this.editorRange.endDomIndex; i++) {
|
for (let i = this.editorRange.startDomIndex; i < this.editorRange.endDomIndex; i++) {
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// 构造函数
|
// 构造函数
|
||||||
import StyleRange from "./styleRange";
|
import StyleRange from "./styleRange";
|
||||||
|
import toolbarCommon from "../../editor/toolbar/common";
|
||||||
|
|
||||||
function Dom(type = 'text', cls = '', text = '', styleRange = []) {
|
function Dom(type = 'text', cls = '', text = '', styleRange = []) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
@@ -128,20 +129,21 @@ Dom.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
// 回车事件处理
|
// 回车事件处理
|
||||||
keyEnter(editorDom, editorRange) {
|
keyEnter(editorDom, editorRange, undoRedo) {
|
||||||
let nextText = '';
|
let nextText = '';
|
||||||
let oldText = this.text || '';
|
let oldText = this.text || '';
|
||||||
// 如果文字的中间位置点击,则把内容分割到两行
|
// 如果文字的中间位置点击,则把内容分割到两行
|
||||||
if (editorRange.startOffset < oldText.length) {
|
if (editorRange.startOffset < oldText.length) {
|
||||||
|
let beforeJson = JSON.stringify(this);
|
||||||
this.text = oldText.substring(0, editorRange.startOffset);
|
this.text = oldText.substring(0, editorRange.startOffset);
|
||||||
|
undoRedo.execute(1, editIndex, beforeJson, JSON.stringify(this));
|
||||||
nextText = oldText.substring(editorRange.startOffset, oldText.length);
|
nextText = oldText.substring(editorRange.startOffset, oldText.length);
|
||||||
}
|
}
|
||||||
for (let i = 0; i < editorDom.length; i++) {
|
let editDomNode = toolbarCommon.getRootDom(this.target);
|
||||||
if (this == editorDom[i]) {
|
let editIndex = parseInt(editDomNode.getAttribute("index"));
|
||||||
editorDom.splice(i + 1, 0, new Dom('text', this.cls, nextText));
|
let domNew = new Dom('text', this.cls, nextText);
|
||||||
break;
|
editorDom.splice(editIndex + 1, 0, domNew);
|
||||||
}
|
undoRedo.execute(2, editIndex + 1, JSON.stringify(domNew), '');
|
||||||
}
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import UndoInfo from "./undoInfo";
|
import UndoInfo from "./undoInfo";
|
||||||
import Dom from "./dom";
|
import Dom from "./dom";
|
||||||
|
import vue from '../../../main'
|
||||||
|
|
||||||
function UndoRedo(editorDom) {
|
function UndoRedo(editorDom) {
|
||||||
this.editorDom = editorDom;
|
this.editorDom = editorDom;
|
||||||
@@ -13,15 +14,19 @@ function UndoRedo(editorDom) {
|
|||||||
UndoRedo.prototype = {
|
UndoRedo.prototype = {
|
||||||
constructor: UndoRedo,
|
constructor: UndoRedo,
|
||||||
execute(type, index, before, after) {
|
execute(type, index, before, after) {
|
||||||
// 最多保留20步
|
// 忽略后面的操作步骤
|
||||||
if (this.undoRedoList.length >= 20) {
|
if (this.undoRedoIndex >= 0 && this.undoRedoIndex < this.undoRedoList.length - 1) {
|
||||||
|
this.undoRedoList.splice(this.undoRedoIndex, this.undoRedoList.length - this.undoRedoIndex);
|
||||||
|
}
|
||||||
|
// 最多保留50步
|
||||||
|
if (this.undoRedoList.length >= 50) {
|
||||||
this.undoRedoList.splice(0, 1);
|
this.undoRedoList.splice(0, 1);
|
||||||
}
|
}
|
||||||
this.undoRedoList.push(new UndoInfo(type, index, before, after));
|
this.undoRedoList.push(new UndoInfo(type, index, before, after));
|
||||||
this.undoRedoIndex = this.undoRedoList.length - 1;
|
this.undoRedoIndex = this.undoRedoList.length - 1;
|
||||||
},
|
},
|
||||||
undo() {
|
undo() {
|
||||||
if (this.undoRedoIndex < 0 || this.undoRedoIndex >= this.undoRedoList.length) {
|
if (this.undoRedoIndex >= this.undoRedoList.length) {
|
||||||
this.undoRedoIndex = this.undoRedoList.length - 1;
|
this.undoRedoIndex = this.undoRedoList.length - 1;
|
||||||
}
|
}
|
||||||
if (this.undoRedoIndex < 0) {
|
if (this.undoRedoIndex < 0) {
|
||||||
@@ -36,7 +41,7 @@ UndoRedo.prototype = {
|
|||||||
} else {
|
} else {
|
||||||
this.undoObjDomToEditor(undoInfo, changeContent);
|
this.undoObjDomToEditor(undoInfo, changeContent);
|
||||||
}
|
}
|
||||||
this.undoRedoIndex = Math.max(this.undoRedoIndex - 1, 0);
|
this.undoRedoIndex = Math.max(this.undoRedoIndex - 1, -1);
|
||||||
},
|
},
|
||||||
redo() {
|
redo() {
|
||||||
this.undoRedoIndex++;
|
this.undoRedoIndex++;
|
||||||
@@ -45,7 +50,8 @@ UndoRedo.prototype = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
let undoInfo = this.undoRedoList[this.undoRedoIndex];
|
let undoInfo = this.undoRedoList[this.undoRedoIndex];
|
||||||
let changeContent = JSON.parse(undoInfo.after);
|
let actionText = (undoInfo.type == 1) ? undoInfo.after : undoInfo.before;
|
||||||
|
let changeContent = JSON.parse(actionText);
|
||||||
if (changeContent instanceof Array) {
|
if (changeContent instanceof Array) {
|
||||||
changeContent.forEach(item => {
|
changeContent.forEach(item => {
|
||||||
this.redoObjDomToEditor(undoInfo, item);
|
this.redoObjDomToEditor(undoInfo, item);
|
||||||
@@ -59,16 +65,14 @@ UndoRedo.prototype = {
|
|||||||
if (undoInfo.type == 1) {
|
if (undoInfo.type == 1) {
|
||||||
// 1=修改 2=添加 3=删除
|
// 1=修改 2=添加 3=删除
|
||||||
if (this.editorDom.length > undoInfo.index) {
|
if (this.editorDom.length > undoInfo.index) {
|
||||||
this.editorDom[undoInfo.index] = dom;
|
vue.$set(this.editorDom, undoInfo.index, dom);
|
||||||
}
|
}
|
||||||
} else if (undoInfo.type == 2) {
|
} else if (undoInfo.type == 2) {
|
||||||
// 1=修改 2=添加 3=删除
|
// 1=修改 2=添加 3=删除
|
||||||
if (this.editorDom.length > undoInfo.index) {
|
if (this.editorDom.length == undoInfo.index) {
|
||||||
if (this.editorDom.length == undoInfo.index) {
|
this.editorDom.push(dom);
|
||||||
this.editorDom.push(dom);
|
} else if (this.editorDom.length > undoInfo.index) {
|
||||||
} else if (this.editorDom.length > undoInfo.index) {
|
this.editorDom.splice(undoInfo.index, 0, dom);
|
||||||
this.editorDom.splice(undoInfo.index, 0, dom);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (undoInfo.type == 3) {
|
} else if (undoInfo.type == 3) {
|
||||||
// 1=修改 2=添加 3=删除
|
// 1=修改 2=添加 3=删除
|
||||||
@@ -82,7 +86,7 @@ UndoRedo.prototype = {
|
|||||||
if (undoInfo.type == 1) {
|
if (undoInfo.type == 1) {
|
||||||
// 1=修改 2=添加 3=删除
|
// 1=修改 2=添加 3=删除
|
||||||
if (this.editorDom.length > undoInfo.index) {
|
if (this.editorDom.length > undoInfo.index) {
|
||||||
this.editorDom[undoInfo.index] = dom;
|
vue.$set(this.editorDom, undoInfo.index, dom);
|
||||||
}
|
}
|
||||||
} else if (undoInfo.type == 2) {
|
} else if (undoInfo.type == 2) {
|
||||||
// 1=修改 2=添加 3=删除
|
// 1=修改 2=添加 3=删除
|
||||||
|
|||||||
Reference in New Issue
Block a user