fixed pos.rel cases
This commit is contained in:
		
							parent
							
								
									40c3be1732
								
							
						
					
					
						commit
						2a33507c00
					
				@ -55,11 +55,19 @@ export const useSearchMarker = (tr, yarray, index, f) => {
 | 
				
			|||||||
    searchMarker.push(fsm)
 | 
					    searchMarker.push(fsm)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  const diff = fsm.index - index
 | 
					  const diff = fsm.index - index
 | 
				
			||||||
 | 
					  // @todo create fresh marker if diff > index
 | 
				
			||||||
  if (diff > 0) {
 | 
					  if (diff > 0) {
 | 
				
			||||||
    fsm.backward(tr, diff)
 | 
					    fsm.backward(tr, diff)
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    fsm.forward(tr, -diff)
 | 
					    fsm.forward(tr, -diff)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  // @todo remove this tests
 | 
				
			||||||
 | 
					  const otherTesting = new ListIterator(yarray)
 | 
				
			||||||
 | 
					  otherTesting.forward(tr, index)
 | 
				
			||||||
 | 
					  if (otherTesting.nextItem !== fsm.nextItem || otherTesting.index !== fsm.index || otherTesting.reachedEnd !== fsm.reachedEnd) {
 | 
				
			||||||
 | 
					    throw new Error('udtirane')
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const result = f(fsm)
 | 
					  const result = f(fsm)
 | 
				
			||||||
  if (fsm.reachedEnd) {
 | 
					  if (fsm.reachedEnd) {
 | 
				
			||||||
    fsm.reachedEnd = false
 | 
					    fsm.reachedEnd = false
 | 
				
			||||||
@ -93,7 +101,7 @@ export const useSearchMarker = (tr, yarray, index, f) => {
 | 
				
			|||||||
 * @param {Array<ListIterator>} searchMarker
 | 
					 * @param {Array<ListIterator>} searchMarker
 | 
				
			||||||
 * @param {number} index
 | 
					 * @param {number} index
 | 
				
			||||||
 * @param {number} len If insertion, len is positive. If deletion, len is negative.
 | 
					 * @param {number} len If insertion, len is positive. If deletion, len is negative.
 | 
				
			||||||
 * @param {ListIterator} origSearchMarker Do not update this searchmarker because it is the one we used to manipulate.
 | 
					 * @param {ListIterator|null} origSearchMarker Do not update this searchmarker because it is the one we used to manipulate. @todo !=null for improved perf in ytext
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
export const updateMarkerChanges = (searchMarker, index, len, origSearchMarker) => {
 | 
					export const updateMarkerChanges = (searchMarker, index, len, origSearchMarker) => {
 | 
				
			||||||
  for (let i = searchMarker.length - 1; i >= 0; i--) {
 | 
					  for (let i = searchMarker.length - 1; i >= 0; i--) {
 | 
				
			||||||
 | 
				
			|||||||
@ -27,6 +27,7 @@ import {
 | 
				
			|||||||
  updateMarkerChanges,
 | 
					  updateMarkerChanges,
 | 
				
			||||||
  ContentType,
 | 
					  ContentType,
 | 
				
			||||||
  useSearchMarker,
 | 
					  useSearchMarker,
 | 
				
			||||||
 | 
					  findIndexCleanStart,
 | 
				
			||||||
  ListIterator, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, ID, Doc, Item, Snapshot, Transaction // eslint-disable-line
 | 
					  ListIterator, UpdateDecoderV1, UpdateDecoderV2, UpdateEncoderV1, UpdateEncoderV2, ID, Doc, Item, Snapshot, Transaction // eslint-disable-line
 | 
				
			||||||
} from '../internals.js'
 | 
					} from '../internals.js'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -127,9 +128,27 @@ const findPosition = (transaction, parent, index) => {
 | 
				
			|||||||
  const currentAttributes = new Map()
 | 
					  const currentAttributes = new Map()
 | 
				
			||||||
  if (parent._searchMarker) {
 | 
					  if (parent._searchMarker) {
 | 
				
			||||||
    return useSearchMarker(transaction, parent, index, listIter => {
 | 
					    return useSearchMarker(transaction, parent, index, listIter => {
 | 
				
			||||||
 | 
					      let left, right
 | 
				
			||||||
 | 
					      if (listIter.rel > 0) {
 | 
				
			||||||
 | 
					        // must exist because rel > 0
 | 
				
			||||||
 | 
					        const nextItem = /** @type {Item} */ (listIter.nextItem)
 | 
				
			||||||
 | 
					        if (listIter.rel === nextItem.length) {
 | 
				
			||||||
 | 
					          left = nextItem
 | 
				
			||||||
 | 
					          right = left.right
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          const structs = /** @type {Array<Item|GC>} */ (transaction.doc.store.clients.get(nextItem.id.client))
 | 
				
			||||||
 | 
					          const after = /** @type {Item} */ (structs[findIndexCleanStart(transaction, structs, nextItem.id.clock + listIter.rel)])
 | 
				
			||||||
 | 
					          listIter.nextItem = after
 | 
				
			||||||
 | 
					          listIter.rel = 0
 | 
				
			||||||
 | 
					          left = listIter.left
 | 
				
			||||||
 | 
					          right = listIter.right
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        left = listIter.left
 | 
				
			||||||
 | 
					        right = listIter.right
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      // @todo this should simply split if .rel > 0
 | 
					      // @todo this should simply split if .rel > 0
 | 
				
			||||||
      const pos = new ItemTextListPosition(listIter.left, listIter.right, listIter.index, currentAttributes)
 | 
					      return new ItemTextListPosition(left, right, index, currentAttributes)
 | 
				
			||||||
      return findNextPosition(transaction, pos, index - listIter.index + listIter.rel)
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
  } else {
 | 
					  } else {
 | 
				
			||||||
    const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes)
 | 
					    const pos = new ItemTextListPosition(null, parent._start, 0, currentAttributes)
 | 
				
			||||||
@ -266,7 +285,7 @@ const insertText = (transaction, parent, currPos, text, attributes) => {
 | 
				
			|||||||
  const content = text.constructor === String ? new ContentString(/** @type {string} */ (text)) : (text instanceof AbstractType ? new ContentType(text) : new ContentEmbed(text))
 | 
					  const content = text.constructor === String ? new ContentString(/** @type {string} */ (text)) : (text instanceof AbstractType ? new ContentType(text) : new ContentEmbed(text))
 | 
				
			||||||
  let { left, right, index } = currPos
 | 
					  let { left, right, index } = currPos
 | 
				
			||||||
  if (parent._searchMarker) {
 | 
					  if (parent._searchMarker) {
 | 
				
			||||||
    updateMarkerChanges(transaction, parent._searchMarker, currPos.index, content.getLength())
 | 
					    updateMarkerChanges(parent._searchMarker, currPos.index, content.getLength(), null)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content)
 | 
					  right = new Item(createID(ownClientId, getState(doc.store, ownClientId)), left, left && left.lastId, right, right && right.id, parent, null, content)
 | 
				
			||||||
  right.integrate(transaction, 0)
 | 
					  right.integrate(transaction, 0)
 | 
				
			||||||
@ -471,7 +490,7 @@ const deleteText = (transaction, currPos, length) => {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
  const parent = /** @type {AbstractType<any>} */ (/** @type {Item} */ (currPos.left || currPos.right).parent)
 | 
					  const parent = /** @type {AbstractType<any>} */ (/** @type {Item} */ (currPos.left || currPos.right).parent)
 | 
				
			||||||
  if (parent._searchMarker) {
 | 
					  if (parent._searchMarker) {
 | 
				
			||||||
    updateMarkerChanges(transaction, parent._searchMarker, currPos.index, -startLength + length)
 | 
					    updateMarkerChanges(parent._searchMarker, currPos.index, -startLength + length, null)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  return currPos
 | 
					  return currPos
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -162,13 +162,18 @@ export class ListIterator {
 | 
				
			|||||||
  /**
 | 
					  /**
 | 
				
			||||||
   * @param {Transaction} tr
 | 
					   * @param {Transaction} tr
 | 
				
			||||||
   * @param {number} len
 | 
					   * @param {number} len
 | 
				
			||||||
 | 
					   * @return {ListIterator}
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  backward (tr, len) {
 | 
					  backward (tr, len) {
 | 
				
			||||||
    if (this.index - len < 0) {
 | 
					    if (this.index - len < 0) {
 | 
				
			||||||
      throw lengthExceeded
 | 
					      throw lengthExceeded
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    let item = this.nextItem && this.nextItem.left
 | 
					 | 
				
			||||||
    this.index -= len
 | 
					    this.index -= len
 | 
				
			||||||
 | 
					    if (this.rel > len) {
 | 
				
			||||||
 | 
					      this.rel -= len
 | 
				
			||||||
 | 
					      return this
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    let item = this.nextItem && this.nextItem.left
 | 
				
			||||||
    if (this.rel) {
 | 
					    if (this.rel) {
 | 
				
			||||||
      len -= this.rel
 | 
					      len -= this.rel
 | 
				
			||||||
      this.rel = 0
 | 
					      this.rel = 0
 | 
				
			||||||
@ -177,8 +182,10 @@ export class ListIterator {
 | 
				
			|||||||
      if (item.countable && !item.deleted && item.moved === this.currMove) {
 | 
					      if (item.countable && !item.deleted && item.moved === this.currMove) {
 | 
				
			||||||
        len -= item.length
 | 
					        len -= item.length
 | 
				
			||||||
        if (len < 0) {
 | 
					        if (len < 0) {
 | 
				
			||||||
          this.rel = item.length + len
 | 
					          this.rel = -len
 | 
				
			||||||
          len = 0
 | 
					          len = 0
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (len === 0) {
 | 
				
			||||||
          break
 | 
					          break
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      } else if (item.content.constructor === ContentMove && item.moved === this.currMove) {
 | 
					      } else if (item.content.constructor === ContentMove && item.moved === this.currMove) {
 | 
				
			||||||
@ -201,8 +208,7 @@ export class ListIterator {
 | 
				
			|||||||
      }
 | 
					      }
 | 
				
			||||||
      item = item.left
 | 
					      item = item.left
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    this.index -= len
 | 
					    this.nextItem = item
 | 
				
			||||||
    this.nextItem = item && item.right
 | 
					 | 
				
			||||||
    return this
 | 
					    return this
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -373,6 +373,29 @@ export const compare = users => {
 | 
				
			|||||||
    t.compare(Y.encodeStateVector(users[i]), Y.encodeStateVector(users[i + 1]))
 | 
					    t.compare(Y.encodeStateVector(users[i]), Y.encodeStateVector(users[i + 1]))
 | 
				
			||||||
    compareDS(Y.createDeleteSetFromStructStore(users[i].store), Y.createDeleteSetFromStructStore(users[i + 1].store))
 | 
					    compareDS(Y.createDeleteSetFromStructStore(users[i].store), Y.createDeleteSetFromStructStore(users[i + 1].store))
 | 
				
			||||||
    compareStructStores(users[i].store, users[i + 1].store)
 | 
					    compareStructStores(users[i].store, users[i + 1].store)
 | 
				
			||||||
 | 
					    // test list-iterator
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      const user = users[0]
 | 
				
			||||||
 | 
					      user.transact(tr => {
 | 
				
			||||||
 | 
					        const type = user.getArray('array')
 | 
				
			||||||
 | 
					        Y.useSearchMarker(tr, type, type.length, walker => {
 | 
				
			||||||
 | 
					          for (let i = type.length; i >= 0; i--) {
 | 
				
			||||||
 | 
					            const otherWalker = new Y.ListIterator(type)
 | 
				
			||||||
 | 
					            otherWalker.forward(tr, walker.index)
 | 
				
			||||||
 | 
					            otherWalker.forward(tr, 0)
 | 
				
			||||||
 | 
					            walker.forward(tr, 0)
 | 
				
			||||||
 | 
					            t.assert(walker.index === i)
 | 
				
			||||||
 | 
					            t.assert(walker.left === otherWalker.left)
 | 
				
			||||||
 | 
					            t.assert(walker.right === otherWalker.right)
 | 
				
			||||||
 | 
					            t.assert(walker.nextItem === otherWalker.nextItem)
 | 
				
			||||||
 | 
					            t.assert(walker.reachedEnd === otherWalker.reachedEnd)
 | 
				
			||||||
 | 
					            if (i > 0) {
 | 
				
			||||||
 | 
					              walker.backward(tr, 1)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
  users.map(u => u.destroy())
 | 
					  users.map(u => u.destroy())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user