diff --git a/src/utils/RelativePosition.js b/src/utils/RelativePosition.js index 214fc6f0..cba65996 100644 --- a/src/utils/RelativePosition.js +++ b/src/utils/RelativePosition.js @@ -9,7 +9,7 @@ import { ContentType, followRedone, getItem, - ID, Doc, AbstractType // eslint-disable-line + StructStore, ID, Doc, AbstractType, // eslint-disable-line } from '../internals.js' import * as encoding from 'lib0/encoding' @@ -256,6 +256,18 @@ export const readRelativePosition = decoder => { */ export const decodeRelativePosition = uint8Array => readRelativePosition(decoding.createDecoder(uint8Array)) +/** + * @param {StructStore} store + * @param {ID} id + */ +const getItemWithOffset = (store, id) => { + const item = getItem(store, id) + const diff = id.clock - item.id.clock + return { + item, diff + } +} + /** * Transform a relative position to an absolute position. * @@ -286,7 +298,7 @@ export const createAbsolutePositionFromRelativePosition = (rpos, doc, followUndo if (getState(store, rightID.client) <= rightID.clock) { return null } - const res = followUndoneDeletions ? followRedone(store, rightID) : { item: getItem(store, rightID), diff: 0 } + const res = followUndoneDeletions ? followRedone(store, rightID) : getItemWithOffset(store, rightID) const right = res.item if (!(right instanceof Item)) { return null diff --git a/tests/relativePositions.tests.js b/tests/relativePositions.tests.js index ab86168b..75e7088d 100644 --- a/tests/relativePositions.tests.js +++ b/tests/relativePositions.tests.js @@ -85,6 +85,26 @@ export const testRelativePositionCase6 = tc => { checkRelativePositions(ytext) } +/** + * Testing https://github.com/yjs/yjs/issues/657 + * + * @param {t.TestCase} tc + */ +export const testRelativePositionCase7 = tc => { + const docA = new Y.Doc() + const textA = docA.getText('text') + textA.insert(0, 'abcde') + // Create a relative position at index 2 in 'textA' + const relativePosition = Y.createRelativePositionFromTypeIndex(textA, 2) + // Verify that the absolutes positions on 'docA' are the same + const absolutePositionWithFollow = + Y.createAbsolutePositionFromRelativePosition(relativePosition, docA, true) + const absolutePositionWithoutFollow = + Y.createAbsolutePositionFromRelativePosition(relativePosition, docA, false) + t.assert(absolutePositionWithFollow?.index === 2) + t.assert(absolutePositionWithoutFollow?.index === 2) +} + /** * @param {t.TestCase} tc */