fix: 反推操作 characterData 类型的 op 会出现path不准确

This commit is contained in:
yanmao 2022-01-13 20:15:52 +08:00
parent 61701b64ca
commit fa0f4c1d6d
5 changed files with 52 additions and 22 deletions

View File

@ -441,10 +441,11 @@ class NodeEntry implements NodeInterface {
on<R = any, F extends EventListener<R> = EventListener<R>>(
eventType: string,
listener: F,
rewrite?: boolean | undefined,
): NodeInterface {
this.each((node, i) => {
node.addEventListener(eventType, listener, false);
if (this.events[i]) this.events[i].on(eventType, listener);
if (this.events[i]) this.events[i].on(eventType, listener, rewrite);
});
return this;
}

View File

@ -359,7 +359,8 @@ class Producer extends EventEmitter2 {
} else if (type === 'characterData') {
if (!isValueString) {
if (
typeof getValue(this.doc?.data, oldPath) === 'string' &&
typeof getValue(this.doc?.data, oldPath, rootId) ===
'string' &&
(record['text-data'] || target['data']).length > 0
) {
const newOp = {
@ -407,6 +408,7 @@ class Producer extends EventEmitter2 {
const pathValue = getValue(
this.doc?.data,
op.oldPath || [],
op.id,
);
if (pathValue !== undefined) {
const childIds = op.childIds || [];
@ -763,7 +765,11 @@ class Producer extends EventEmitter2 {
let emitOps: Op[] = [];
ops.forEach((op) => {
if ('path' in op && op.newValue !== undefined) {
const pathValue = getValue(this.doc?.data, op.oldPath || []);
const pathValue = getValue(
this.doc?.data,
op.oldPath || [],
op.id,
);
const newOps = this.textToOps(
[...op.path!],
pathValue,

View File

@ -20,6 +20,7 @@ import {
} from 'sharedb';
import {
DATA_ELEMENT,
DATA_ID,
DATA_TRANSIENT_ATTRIBUTES,
DATA_TRANSIENT_ELEMENT,
UI,
@ -243,10 +244,6 @@ export const opsSort = (ops: Op[]) => {
if ('sd' in op2) {
return 0;
}
// sd 小于ld就放在前面
if ('ld' in op2) {
return diff;
}
return -1;
}
// 属性删除,排在节点删除最前面
@ -398,11 +395,28 @@ export const toJSON0 = (
return;
};
export const getValue = (data: any, path: Path) => {
/**
* json中的值
* @param data json
* @param path
* @param id id
* @returns
*/
export const getValue = (data: any, path: Path, id?: string) => {
if (path.length === 0) return data;
let value = data;
let hasValue = !id;
for (let i = 0; i < path.length && value !== undefined; i++) {
value = value[path[i]];
if (
!hasValue &&
id &&
Array.isArray(value) &&
value.length > 0 &&
value[1][DATA_ID] === id
) {
hasValue = true;
}
}
return value;
return hasValue ? value : undefined;
};

View File

@ -285,6 +285,7 @@ export interface NodeInterface {
on<R = any, F extends EventListener<R> = EventListener<R>>(
eventType: string,
listener: F,
rewrite?: boolean | undefined,
): NodeInterface;
/**

View File

@ -190,19 +190,27 @@ class CollapseComponent implements CollapseComponentInterface {
node.attributes({
'data-name': escape(name),
});
node.on('click', (event: MouseEvent) => {
if (!key) return;
event.stopPropagation();
event.preventDefault();
if (onSelect) onSelect(event, data);
});
node.on('mouseenter', () => {
if (!key) return;
this.root
?.find('.data-mention-item-active')
.removeClass('data-mention-item-active');
node.addClass('data-mention-item-active');
});
node.on(
'click',
(event: MouseEvent) => {
if (!key) return;
event.stopPropagation();
event.preventDefault();
if (onSelect) onSelect(event, data);
},
true,
);
node.on(
'mouseenter',
() => {
if (!key) return;
this.root
?.find('.data-mention-item-active')
.removeClass('data-mention-item-active');
node.addClass('data-mention-item-active');
},
true,
);
return node;
};