diff --git a/src/Struct/Type.js b/src/Struct/Type.js index 5588d984..69f0f17d 100644 --- a/src/Struct/Type.js +++ b/src/Struct/Type.js @@ -22,6 +22,14 @@ export default class Type extends Item { this._y = null this._eventHandler = new EventHandler() } + _transact (f) { + const y = this._y + if (y !== null) { + y.transact(f) + } else { + f(y) + } + } observe (f) { this._eventHandler.addEventListener(f) } @@ -41,8 +49,9 @@ export default class Type extends Item { } // integrate map children const map = this._map - for (let [key, t] of map) { - map.delete(key) + this._map = new Map() + for (let t of map.values()) { + // TODO make sure that right elements are deleted! integrateChildren(y, t) } } diff --git a/src/Type/YArray.js b/src/Type/YArray.js index df7653d3..d90c9788 100644 --- a/src/Type/YArray.js +++ b/src/Type/YArray.js @@ -123,8 +123,7 @@ export default class YArray extends Type { } } insertAfter (left, content) { - const y = this._y - const apply = () => { + this._transact(y => { let right if (left === null) { right = this._start @@ -154,6 +153,8 @@ export default class YArray extends Type { c._integrate(y) } else if (left === null) { this._start = c + } else { + left._right = c } left = c } else { @@ -172,12 +173,7 @@ export default class YArray extends Type { if (prevJsonIns !== null && y !== null) { prevJsonIns._integrate(y) } - } - if (y !== null) { - y.transact(apply) - } else { - apply() - } + }) } insert (pos, content) { let left = null diff --git a/src/Type/YMap.js b/src/Type/YMap.js index 1c7b5fdd..8c76686b 100644 --- a/src/Type/YMap.js +++ b/src/Type/YMap.js @@ -35,16 +35,15 @@ export default class YMap extends Type { return map } delete (key) { - this._y.transact(() => { + this._transact((y) => { let c = this._map.get(key) - if (c !== undefined) { - c._delete(this._y) + if (y !== null && c !== undefined) { + c._delete(y) } }) } set (key, value) { - const y = this._y - y.transact(() => { + this._transact(y => { const old = this._map.get(key) || null if (old !== null) { if (old instanceof ItemJSON && old._content[0] === value) { @@ -52,7 +51,9 @@ export default class YMap extends Type { // break here return value } - old._delete(y) + if (y !== null) { + old._delete(y) + } } let v if (typeof value === 'function') { @@ -67,7 +68,11 @@ export default class YMap extends Type { v._right_origin = old v._parent = this v._parentSub = key - v._integrate(y) + if (y !== null) { + v._integrate(y) + } else { + this._map.set(key, v) + } }) return value } diff --git a/src/Type/YText.js b/src/Type/YText.js index f1ac0414..e5181571 100644 --- a/src/Type/YText.js +++ b/src/Type/YText.js @@ -24,14 +24,16 @@ export default class YText extends YArray { return strBuilder.join('') } insert (pos, text) { - this._y.transact(() => { + this._transact(y => { let left = null let right = this._start let count = 0 while (right !== null) { if (count <= pos && pos < count + right._length) { + const splitDiff = pos - count right = right._splitAt(this._y, pos - count) left = right._left + count += splitDiff break } count += right._length @@ -48,7 +50,13 @@ export default class YText extends YArray { item._right_origin = right item._parent = this item._content = text - item._integrate(this._y) + if (y !== null) { + item._integrate(this._y) + } else if (left === null) { + this._start = item + } else { + left._right = item + } }) } _logString () { diff --git a/src/Y.js b/src/Y.js index 7bdc0482..d05c3b9d 100644 --- a/src/Y.js +++ b/src/Y.js @@ -46,7 +46,7 @@ export default class Y extends NamedEventHandler { this._transaction = new Transaction(this) } try { - f() + f(this) } catch (e) { console.error(e) } diff --git a/test/y-xml.tests.js b/test/y-xml.tests.js index 7c838c55..8fd6cc6d 100644 --- a/test/y-xml.tests.js +++ b/test/y-xml.tests.js @@ -267,6 +267,26 @@ test('filter attribute', async function xml15 (t) { await compareUsers(t, users) }) +test('deep element insert', async function xml16 (t) { + var { users, xml0, xml1 } = await initArrays(t, { users: 3 }) + let dom0 = xml0.getDom() + let dom1 = xml1.getDom() + let deepElement = document.createElement('p') + let boldElement = document.createElement('b') + let attrElement = document.createElement('img') + attrElement.setAttribute('src', 'http:localhost:8080/nowhere') + boldElement.append(document.createTextNode('hi')) + deepElement.append(boldElement) + deepElement.append(attrElement) + dom0.append(deepElement) + console.log(dom0.outerHTML) + let str0 = dom0.outerHTML + await flushAll(t, users) + let str1 = dom1.outerHTML + t.compare(str0, str1, 'Dom string representation matches') + await compareUsers(t, users) +}) + // TODO: move elements var xmlTransactions = [ function attributeChange (t, user, chance) {