fixed issues with unbounded XmlText.toString
This commit is contained in:
parent
160c9ca1b7
commit
10cf4b44f8
@ -314,7 +314,7 @@ export class Item extends AbstractStruct {
|
|||||||
* bit2: countable
|
* bit2: countable
|
||||||
* bit3: deleted
|
* bit3: deleted
|
||||||
* bit4: mark - mark node as fast-search-marker
|
* 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
|
* @type {number} byte
|
||||||
*/
|
*/
|
||||||
this.info = this.content.isCountable() ? binary.BIT2 : 0
|
this.info = this.content.isCountable() ? binary.BIT2 : 0
|
||||||
|
@ -1260,13 +1260,13 @@ export const rangeDelta = (parent, start, end, snapshot, prevSnapshot, computeYC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
const computeDelta = () => {
|
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
|
// 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) {
|
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) {
|
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))) {
|
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')
|
currentAttributes.delete('ychange')
|
||||||
}
|
}
|
||||||
let s = /** @type {ContentString} */ (n.content).str
|
let s = /** @type {ContentString} */ (n.content).str
|
||||||
if (scope > 0) {
|
if (startOffset > 0) {
|
||||||
str += s.slice(scope)
|
str += s.slice(startOffset)
|
||||||
scope = 0
|
startOffset = 0
|
||||||
} else if (end !== null && end.client === n.id.client && end.clock >= n.id.clock && end.clock < n.id.clock + n.length) {
|
} 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
|
// we reached the end or range
|
||||||
const offset = n.id.clock + n.length - end.clock - 1
|
const endOffset = n.id.clock + n.length - end.clock - 1
|
||||||
str += s.slice(0, s.length + offset) // scope is negative
|
str += s.slice(0, s.length + endOffset) // scope is negative
|
||||||
packStr()
|
packStr()
|
||||||
break loop
|
break loop
|
||||||
} else if (scope == 0) {
|
} else if (startOffset == 0) {
|
||||||
str += s
|
str += s
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
@ -1328,6 +1328,9 @@ export const rangeDelta = (parent, start, end, snapshot, prevSnapshot, computeYC
|
|||||||
}
|
}
|
||||||
break
|
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
|
n = n.right
|
||||||
}
|
}
|
||||||
|
@ -682,7 +682,7 @@ export const testRemoteMapUpdate = tc => {
|
|||||||
/**
|
/**
|
||||||
* @param {t.TestCase} tc
|
* @param {t.TestCase} tc
|
||||||
*/
|
*/
|
||||||
const testTextBasic = tc => {
|
export const testTextBasic = tc => {
|
||||||
const { testConnector, text0, text1 } = init(tc, { users: 2 })
|
const { testConnector, text0, text1 } = init(tc, { users: 2 })
|
||||||
|
|
||||||
text0.insert(0, 'abcd') // 'abcd'
|
text0.insert(0, 'abcd') // 'abcd'
|
||||||
@ -701,6 +701,29 @@ const testTextBasic = tc => {
|
|||||||
t.compare(insert.toString(), 'be')
|
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
|
* @param {t.TestCase} tc
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user