From 6df152c4ec101815b65d58c69dea502108d3add6 Mon Sep 17 00:00:00 2001 From: Kevin Jahns Date: Fri, 19 Nov 2021 18:54:27 +0100 Subject: [PATCH] proper iteration through arrays (for mappings, toJSON, ..) --- src/utils/ListIterator.js | 15 ++++++++++++++- tests/y-array.tests.js | 3 ++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/utils/ListIterator.js b/src/utils/ListIterator.js index 6c1c3dac..b38f743e 100644 --- a/src/utils/ListIterator.js +++ b/src/utils/ListIterator.js @@ -18,6 +18,7 @@ const lengthExceeded = error.create('Length exceeded!') /** * @todo rename to walker? + * @todo check that inserting character one after another always reuses ListIterators */ export class ListIterator { /** @@ -214,6 +215,7 @@ export class ListIterator { * @param {function(T, T): T} concat */ _slice (tr, len, value, slice, concat) { + this.index += len while (len > 0 && !this.reachedEnd) { while (this.nextItem && this.nextItem.countable && !this.reachedEnd && len > 0) { if (!this.nextItem.deleted) { @@ -240,6 +242,9 @@ export class ListIterator { this.forward(tr, 0) } } + if (len < 0) { + this.index -= len + } return value } @@ -297,6 +302,7 @@ export class ListIterator { this.nextItem = getItemCleanStart(tr, createID(itemid.client, itemid.clock + this.rel)) this.rel = 0 } + const sm = this.type._searchMarker const parent = this.type const store = tr.doc.store const ownClientId = tr.doc.clientID @@ -362,6 +368,10 @@ export class ListIterator { } else { this.nextItem = right } + if (sm) { + updateMarkerChanges(tr, sm, this.index, content.length) + } + this.index += content.length } /** @@ -406,9 +416,12 @@ export class ListIterator { return this }, next: () => { + if (this.reachedEnd) { + return { done: true } + } const [value] = this.slice(tr, 1) return { - done: value == null, + done: false, value: value } } diff --git a/tests/y-array.tests.js b/tests/y-array.tests.js index b19750ce..eaf085e3 100644 --- a/tests/y-array.tests.js +++ b/tests/y-array.tests.js @@ -1,4 +1,4 @@ -import { init, compare, applyRandomTests, Doc } from './testHelper.js' // eslint-disable-line +import { init, compare, applyRandomTests, Doc, AbstractType } from './testHelper.js' // eslint-disable-line import * as Y from '../src/index.js' import * as t from 'lib0/testing' @@ -473,6 +473,7 @@ const arrayTransactions = [ yarray.insert(pos, content) oldContent.splice(pos, 0, ...content) t.compareArrays(yarray.toArray(), oldContent) // we want to make sure that fastSearch markers insert at the correct position + t.compare(yarray.toJSON(), yarray.toArray().map(x => x instanceof AbstractType ? x.toJSON() : x)) }, function insertTypeArray (user, gen) { const yarray = user.getArray('array')