fixed issues with unbounded XmlText.toString

This commit is contained in:
Bartosz Sypytkowski 2023-08-17 20:00:48 +02:00
parent 160c9ca1b7
commit 10cf4b44f8
3 changed files with 38 additions and 12 deletions

View File

@ -314,7 +314,7 @@ export class Item extends AbstractStruct {
* bit2: countable
* bit3: deleted
* bit4: mark - mark node as fast-search-marker
* bit5: linked - this item is linked by Weak Link references
* bit9: linked - this item is linked by Weak Link references
* @type {number} byte
*/
this.info = this.content.isCountable() ? binary.BIT2 : 0

View File

@ -1260,13 +1260,13 @@ export const rangeDelta = (parent, start, end, snapshot, prevSnapshot, computeYC
}
}
const computeDelta = () => {
// scope represents offset at current block from which we're intersted in picking string
// startOffset represents offset at current block from which we're intersted in picking string
// if it's -1 it means, we're out of scope and we should break at this point
let scope = start === null ? 0 : -1
let startOffset = start === null ? 0 : -1
loop: while (n !== null) {
if (scope < 0 && start !== null) {
if (startOffset < 0 && start !== null) {
if (start.client === n.id.client && start.clock >= n.id.clock && start.clock < n.id.clock + n.length) {
scope = n.id.clock + n.length - start.clock - 1
startOffset = start.clock - n.id.clock
}
}
if (isVisible(n, snapshot) || (prevSnapshot !== undefined && isVisible(n, prevSnapshot))) {
@ -1288,16 +1288,16 @@ export const rangeDelta = (parent, start, end, snapshot, prevSnapshot, computeYC
currentAttributes.delete('ychange')
}
let s = /** @type {ContentString} */ (n.content).str
if (scope > 0) {
str += s.slice(scope)
scope = 0
if (startOffset > 0) {
str += s.slice(startOffset)
startOffset = 0
} else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) {
// we reached the end or range
const offset = n.id.clock + n.length - end.clock - 1
str += s.slice(0, s.length + offset) // scope is negative
const endOffset = n.id.clock + n.length - end.clock - 1
str += s.slice(0, s.length + endOffset) // scope is negative
packStr()
break loop
} else if (scope == 0) {
} else if (startOffset == 0) {
str += s
}
break
@ -1328,6 +1328,9 @@ export const rangeDelta = (parent, start, end, snapshot, prevSnapshot, computeYC
}
break
}
} else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) {
// block may not passed visibility check, but we still need to verify boundaries
break;
}
n = n.right
}

View File

@ -682,7 +682,7 @@ export const testRemoteMapUpdate = tc => {
/**
* @param {t.TestCase} tc
*/
const testTextBasic = tc => {
export const testTextBasic = tc => {
const { testConnector, text0, text1 } = init(tc, { users: 2 })
text0.insert(0, 'abcd') // 'abcd'
@ -701,6 +701,29 @@ const testTextBasic = tc => {
t.compare(insert.toString(), 'be')
}
/**
* @param {t.TestCase} tc
*/
export const testXmlTextBasic = tc => {
const { testConnector, xml0, xml1 } = init(tc, { users: 2 })
const text0 = new Y.XmlText()
xml0.insert(0, [text0])
text0.insert(0, 'abcd') // 'abcd'
const link0 = text0.quote(1, 2) // quote: [bc]
t.compare(link0.toString(), 'bc')
text0.insert(2, 'ef') // 'abefcd', quote: [befc]
t.compare(link0.toString(), 'befc')
text0.delete(3, 3) // 'abe', quote: [be]
t.compare(link0.toString(), 'be')
text0.insertEmbed(3, link0) // 'abe[be]'
testConnector.flushAllMessages()
const text1 = /** @type {Y.XmlText} */ (xml1.get(0))
const delta = text1.toDelta()
const { insert } = delta[1] // YWeakLink
t.compare(insert.toString(), 'be')
}
/**
* @param {t.TestCase} tc
*/