fix(ot & paste)
This commit is contained in:
parent
23d9205ec4
commit
cb435b8317
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
// 都是新增节点,越小排越前面
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue