fix #481 - calculate path correctly when parents are moved
This commit is contained in:
		
							parent
							
								
									7ced59c847
								
							
						
					
					
						commit
						5b16071380
					
				@ -8,6 +8,7 @@ import {
 | 
			
		||||
import * as set from 'lib0/set'
 | 
			
		||||
import * as array from 'lib0/array'
 | 
			
		||||
import { addsStruct } from './Transaction.js'
 | 
			
		||||
import { ListCursor } from './ListCursor.js'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * YEvent describes the changes on a YType.
 | 
			
		||||
@ -62,7 +63,7 @@ export class YEvent {
 | 
			
		||||
   */
 | 
			
		||||
  get path () {
 | 
			
		||||
    // @ts-ignore _item is defined because target is integrated
 | 
			
		||||
    return getPathTo(this.currentTarget, this.target)
 | 
			
		||||
    return getPathTo(this.currentTarget, this.target, this.transaction)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
@ -297,12 +298,13 @@ export class YEvent {
 | 
			
		||||
 *
 | 
			
		||||
 * @param {AbstractType<any>} parent
 | 
			
		||||
 * @param {AbstractType<any>} child target
 | 
			
		||||
 * @param {Transaction} tr
 | 
			
		||||
 * @return {Array<string|number>} Path to the target
 | 
			
		||||
 *
 | 
			
		||||
 * @private
 | 
			
		||||
 * @function
 | 
			
		||||
 */
 | 
			
		||||
const getPathTo = (parent, child) => {
 | 
			
		||||
const getPathTo = (parent, child, tr) => {
 | 
			
		||||
  const path = []
 | 
			
		||||
  while (child._item !== null && child !== parent) {
 | 
			
		||||
    if (child._item.parentSub !== null) {
 | 
			
		||||
@ -310,15 +312,11 @@ const getPathTo = (parent, child) => {
 | 
			
		||||
      path.unshift(child._item.parentSub)
 | 
			
		||||
    } else {
 | 
			
		||||
      // parent is array-ish
 | 
			
		||||
      let i = 0
 | 
			
		||||
      let c = /** @type {AbstractType<any>} */ (child._item.parent)._start
 | 
			
		||||
      while (c !== child._item && c !== null) {
 | 
			
		||||
        if (!c.deleted) {
 | 
			
		||||
          i++
 | 
			
		||||
      const c = new ListCursor(/** @type {AbstractType<any>} */ (child._item.parent))
 | 
			
		||||
      while (c.nextItem != null && !c.reachedEnd && c.nextItem !== child._item) {
 | 
			
		||||
        c.forward(tr, (c.nextItem.countable && !c.nextItem.deleted) ? c.nextItem.length : 0, true)
 | 
			
		||||
      }
 | 
			
		||||
        c = c.right
 | 
			
		||||
      }
 | 
			
		||||
      path.unshift(i)
 | 
			
		||||
      path.unshift(c.index)
 | 
			
		||||
    }
 | 
			
		||||
    child = /** @type {AbstractType<any>} */ (child._item.parent)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,56 @@
 | 
			
		||||
import { init, compare, applyRandomTests, Doc, AbstractType, TestConnector, Item } from './testHelper.js' // eslint-disable-line
 | 
			
		||||
import { init, compare, applyRandomTests, Doc, Item } from './testHelper.js' // eslint-disable-line
 | 
			
		||||
 | 
			
		||||
import * as Y from '../src/index.js'
 | 
			
		||||
import * as t from 'lib0/testing'
 | 
			
		||||
import * as prng from 'lib0/prng'
 | 
			
		||||
import * as math from 'lib0/math'
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * path should be correct when moving item - see yjs#481
 | 
			
		||||
 *
 | 
			
		||||
 * @param {t.TestCase} tc
 | 
			
		||||
 */
 | 
			
		||||
export const testArrayMovePathIssue481 = tc => {
 | 
			
		||||
  const { users, testConnector, array0, array1 } = init(tc, { users: 2 })
 | 
			
		||||
  array0.observeDeep(events => {
 | 
			
		||||
    events.forEach(event => {
 | 
			
		||||
      if (event.path.length > 0) {
 | 
			
		||||
        /**
 | 
			
		||||
         * @type {any}
 | 
			
		||||
         */
 | 
			
		||||
        let target = event.currentTarget
 | 
			
		||||
        event.path.forEach(p => {
 | 
			
		||||
          target = target.get(p)
 | 
			
		||||
        })
 | 
			
		||||
        t.assert(target === event.target)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  })
 | 
			
		||||
  array0.push([
 | 
			
		||||
    ['a', '1.1'],
 | 
			
		||||
    ['b', '2.2'],
 | 
			
		||||
    ['c', '3.1'],
 | 
			
		||||
    ['d', '4.1'],
 | 
			
		||||
    ['e', '5.1']
 | 
			
		||||
  ].map(e => Y.Array.from(e)))
 | 
			
		||||
  testConnector.flushAllMessages()
 | 
			
		||||
  users[1].transact(() => {
 | 
			
		||||
    array1.get(1).insert(0, ['0'])
 | 
			
		||||
    array1.move(1, 0)
 | 
			
		||||
  })
 | 
			
		||||
  testConnector.flushAllMessages()
 | 
			
		||||
  users[1].transact(() => {
 | 
			
		||||
    array1.get(3).insert(0, ['1'])
 | 
			
		||||
    array1.move(3, 4)
 | 
			
		||||
  })
 | 
			
		||||
  testConnector.flushAllMessages()
 | 
			
		||||
  users[1].transact(() => {
 | 
			
		||||
    array1.get(2).insert(0, ['2'])
 | 
			
		||||
    array1.move(2, array1.length)
 | 
			
		||||
  })
 | 
			
		||||
  testConnector.flushAllMessages()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * foreach has correct index - see yjs#485
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user