fix(ot & paste)

This commit is contained in:
yanmao 2021-11-04 02:47:11 +08:00
parent 23d9205ec4
commit cb435b8317
5 changed files with 69 additions and 12 deletions

View File

@ -44,7 +44,6 @@ export default class Paste {
const defaultStyle = this.getDefaultStyle();
const { inline } = this.engine;
const nodeApi = this.engine.node;
// 第一轮预处理,主要处理 span 节点
$(fragment).traverse((node) => {
// 跳过Card
if (node.isCard() || fragment === node.fragment) {
@ -97,9 +96,32 @@ export default class Paste {
if (nodeApi.isBlock(node, this.schema)) {
this.engine.block.brToBlock(node);
}
} else {
let text = node.text();
if (/\s/.test(text)) {
text = text.replace(/\s/g, ' ');
node.text(text);
}
if (/\u200b/.test(text)) {
let isRemove = true;
const next = node.next();
const prev = node.prev();
const parent = node.parent();
if (parent && nodeApi.isMark(parent, this.schema))
isRemove = false;
else if (parent && nodeApi.isInline(parent, this.schema))
isRemove = false;
else if (next && nodeApi.isInline(next, this.schema))
isRemove = false;
else if (prev && nodeApi.isInline(prev, this.schema))
isRemove = false;
if (isRemove) {
text = text.replace(/\u200b/g, '');
node.text(text);
}
}
}
});
// 第二轮处理
$(fragment).traverse((node) => {
let parent = node.parent();
// 跳过已被删除的节点
@ -228,7 +250,25 @@ export default class Paste {
// 处理嵌套
let nodeParent = parent;
const handleBlock = (node: NodeInterface) => {
if (
nodeParent &&
!nodeParent.fragment &&
nodeApi.isBlock(node, this.schema) &&
nodeApi.isBlock(nodeParent, this.schema) &&
!this.schema.isAllowIn(nodeParent.name, node.name)
) {
const children = node.children();
nodeApi.unwrap(node);
children.each((_, index) => {
handleBlock(children.eq(index)!);
});
}
};
handleBlock(node);
while (
node.length > 0 &&
nodeParent &&
!nodeParent.fragment &&
nodeApi.isBlock(node, this.schema) &&
@ -244,6 +284,7 @@ export default class Paste {
// mark 相同的嵌套
nodeParent = parent;
while (
node.length > 0 &&
nodeParent &&
nodeApi.isMark(nodeParent, this.schema) &&
nodeApi.isMark(node, this.schema)

View File

@ -854,6 +854,15 @@ class NodeModel implements NodeModelInterface {
) {
childNode.append($('<br />'));
}
if (
this.editor.node.isBlock(childNode) &&
childNode.children().length === 1 &&
childNode.first()?.isText() &&
this.isEmptyWithTrim(childNode)
) {
childNode.html('<br />');
}
this.removeSide(childNode);
childNode = nextNode;
}

View File

@ -207,7 +207,11 @@ class Producer extends EventEmitter2 {
const oldPath = path.slice();
ops.forEach((op) => {
for (let p = 0; p < path!.length; p++) {
for (
let p = 0;
p < path!.length && op.p.length < path!.length;
p++
) {
if (('li' in op || 'ld' in op) && op.p.length === p + 1) {
if (op.p[p] <= path![p]) {
if ('li' in op) oldPath[p] = oldPath[p] - 1;

View File

@ -143,12 +143,7 @@ export const isReverseOp = (op: Op, next: Op) => {
// 节点增加和删除
if (insertOp.li && deleteNext.ld) {
return (
isEqual(insertOp.li, deleteNext.ld) &&
(isEqual(op.p, next.p) ||
isReversePath(op.p, next.p) ||
isReversePath(next.p, op.p))
);
return isEqual(insertOp.li, deleteNext.ld) && isEqual(op.p, next.p);
}
if (deleteOp.ld && insertNext.li) {
@ -202,6 +197,8 @@ export const updateIndex = (
export const opsSort = (ops: Op[]) => {
ops.sort((op1, op2) => {
let diff = 0;
if (isCursorOp(op1)) return 1;
if (isCursorOp(op2)) return -1;
for (let p = 0; p < op1.p.length; p++) {
const v1 = op1.p[p];
// od oi 最后一个参数是属性名称
@ -234,8 +231,12 @@ export const opsSort = (ops: Op[]) => {
return -1;
}
// 如果删除节点比增加的节点索引小,排在加入节点前面
if (diff < 1 && 'ld' in op1 && 'li' in op2) return -1;
if ('ld' in op1 && 'li' in op2) return -1;
if ('li' in op1 && 'ld' in op2) return 1;
if (diff < 1 && 'ld' in op1 && 'si' in op2) return 1;
if (diff > 0 && 'ld' in op1 && 'si' in op2) return -1;
if (diff < 1 && 'si' in op1 && 'ld' in op2) return 1;
if (diff > 0 && 'si' in op1 && 'ld' in op2) return -1;
const isLi = 'li' in op1 && 'li' in op2;
const isLd = 'ld' in op1 && 'ld' in op2;
// 都是新增节点,越小排越前面

View File

@ -126,6 +126,7 @@ class Parser implements ParserInterface {
const { rule } = value;
oldRules.push(rule);
const { name, attributes, style } = value.node;
delete attributes['data-id'];
const newNode = $(`<${name} />`);
nodeApi.setAttributes(newNode, {
...attributes,
@ -285,7 +286,8 @@ class Parser implements ParserInterface {
if (
parent &&
nodeApi.isBlock(parent, schema) &&
parent.children().length === 1
parent.children().length === 1 &&
child.children().length === 0
) {
const newChild = $('<br />');
child.before(newChild);