I want to sync two XMLFragments but with some conditions. I can do deep observe and check if an XMLElement has a particular attribute by which its content should not be synced. I can applyDelta to another XMLFragment but I need to find a proper XMLElement in it. Is there kind of path to XMLElement to find it in XMLFragment?
Shared types can’t be partially synced. It is necessary that you apply all changes from remote peers.
So, if you don’t want certain information to propagate, do not put it in a shared type.
This is not synchronization in the full sense of the word. I mean I do it in my way how another XmlFragment should be changed. I have two similar structures (actually it is a table in prosemirror editor), but there are XmlElements with ids (table cells) which should be synced, I do it like this:
yFragment.observeDeep((yxmlEvent, transaction) => {
if (!transaction.local) return;
(transaction.changed as any).forEach((value, key: Y.XmlElement) => {
const findParentWithSyncId = (
key: Y.XmlElement | undefined
): string | undefined => {
const parent = key.parent as Y.XmlElement | undefined;
const dataSyncId = parent?.getAttribute("sync-id");
if (dataSyncId) return dataSyncId;
return findParentWithSyncId(parent);
};
const parentSyncId = findParentWithSyncId(key);
if (parentSyncId) {
for (const yItem of Array.from(
yFragmentAlternative.createTreeWalker(
(yxml: any) =>
(yxml as Y.XmlElement).getAttribute("sync-id") ===
parentSyncId
)
)) {
// here I get XmlElement with the same Id
}
});
}
});
},
});
So I can find XmlElement in an alternative XmlFragment, but it can have multiple XmlText elements or nested XmlElements, so I cannot applyDelta directly, I need to know which XmlText or XmlElement has been changes.
I see here a couple of solutions:
- Iterate through XmlElement’s children to find element by indexes, but first I need to know the path of the original XmlElement or XmlText than has been changed.
- Find and observe all elements with sync-id instead of the whole XmlFragment, but I have doubts about performance.
Any idea?
BTW, is there a way to replace XMLElement children? I do it like this for now:
yAltCellElement.delete(0, yAltCellElement.length);
yCell.forEach((yItem, key) => {
yAltCellElement.insert(key, [yItem.clone()]);
});
But it lags, and shows both content (inserted and deleted content) for a millisecond.