AbstractItem.mergeWith helper outsourced into separate function

This commit is contained in:
Kevin Jahns 2019-04-24 18:10:33 +02:00
parent 45237571b7
commit 1d0f9faa91
8 changed files with 62 additions and 57 deletions

View File

@ -9,6 +9,7 @@
"test": "npm run dist && PRODUCTION=1 node ./dist/tests.js --repitition-time 50 --production",
"test-exhaustive": "npm run lint && npm run dist && node ./dist/tests.js --repitition-time 10000",
"dist": "rm -rf dist examples/build && rollup -c",
"serve-examples": "concurrently 'npm run watch' 'serve examples'",
"watch": "rollup -wc",
"lint": "standard && tsc",
"docs": "rm -rf docs; jsdoc --configure ./.jsdoc.json --verbose --readme ./README.v13.md --package ./package.json || true",

View File

@ -27,6 +27,22 @@ import * as maplib from 'lib0/map.js'
import * as set from 'lib0/set.js'
import * as binary from 'lib0/binary.js'
/**
* @param {AbstractItem} left
* @param {AbstractItem} right
* @return {boolean} If true, right is removed from the linked list and should be discarded
*/
export const mergeItemWith = (left, right) => {
if (compareIDs(right.origin, left.lastId) && left.right === right && compareIDs(left.rightOrigin, right.rightOrigin)) {
left.right = right.right
if (left.right !== null) {
left.right.left = left
}
return true
}
return false
}
/**
* Split leftItem into two items
* @param {Transaction} transaction
@ -376,22 +392,6 @@ export class AbstractItem extends AbstractStruct {
throw new Error('unimplemented')
}
/**
* @param {AbstractItem} right
* @return {boolean}
*
* @private
*/
mergeWith (right) {
if (compareIDs(right.origin, this.lastId) && this.right === right && compareIDs(this.rightOrigin, right.rightOrigin)) {
this.right = right.right
if (this.right !== null) {
this.right.left = this
}
return true
}
return false
}
/**
* Mark this Item as deleted.
*

View File

@ -7,6 +7,7 @@ import {
GC,
splitItem,
addToDeleteSet,
mergeItemWith,
Y, StructStore, Transaction, ID, AbstractType // eslint-disable-line
} from '../internals.js'
@ -78,7 +79,7 @@ export class ItemDeleted extends AbstractItem {
* @return {boolean}
*/
mergeWith (right) {
if (super.mergeWith(right)) {
if (mergeItemWith(this, right)) {
this._len += right._len
return true
}

View File

@ -6,6 +6,7 @@ import {
splitItem,
changeItemRefOffset,
GC,
mergeItemWith,
Transaction, StructStore, Y, ID, AbstractType // eslint-disable-line
} from '../internals.js'
@ -74,7 +75,7 @@ export class ItemJSON extends AbstractItem {
* @return {boolean}
*/
mergeWith (right) {
if (super.mergeWith(right)) {
if (mergeItemWith(this, right)) {
this.content = this.content.concat(right.content)
return true
}

View File

@ -6,6 +6,7 @@ import {
splitItem,
changeItemRefOffset,
GC,
mergeItemWith,
Transaction, StructStore, Y, ID, AbstractType // eslint-disable-line
} from '../internals.js'
@ -73,7 +74,7 @@ export class ItemString extends AbstractItem {
* @return {boolean}
*/
mergeWith (right) {
if (super.mergeWith(right)) {
if (mergeItemWith(this, right)) {
this.string += right.string
return true
}

View File

@ -657,10 +657,6 @@ export class YText extends AbstractType {
callTypeObservers(this, transaction, new YTextEvent(this, transaction))
}
toDom () {
return document.createTextNode(this.toString())
}
/**
* Returns the unformatted string representation of this YText type.
*
@ -682,40 +678,6 @@ export class YText extends AbstractType {
return str
}
toDomString () {
// @ts-ignore
return this.toDelta().map(delta => {
const nestedNodes = []
for (let nodeName in delta.attributes) {
const attrs = []
for (let key in delta.attributes[nodeName]) {
attrs.push({ key, value: delta.attributes[nodeName][key] })
}
// sort attributes to get a unique order
attrs.sort((a, b) => a.key < b.key ? -1 : 1)
nestedNodes.push({ nodeName, attrs })
}
// sort node order to get a unique order
nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1)
// now convert to dom string
let str = ''
for (let i = 0; i < nestedNodes.length; i++) {
const node = nestedNodes[i]
str += `<${node.nodeName}`
for (let j = 0; j < node.attrs.length; j++) {
const attr = node.attrs[i]
str += ` ${attr.key}="${attr.value}"`
}
str += '>'
}
str += delta.insert
for (let i = nestedNodes.length - 1; i >= 0; i--) {
str += `</${nestedNodes[i].nodeName}>`
}
return str
})
}
/**
* Apply a {@link Delta} on this shared YText type.
*

View File

@ -31,6 +31,41 @@ export class YXmlText extends YText {
}
return dom
}
toDomString () {
// @ts-ignore
return this.toDelta().map(delta => {
const nestedNodes = []
for (let nodeName in delta.attributes) {
const attrs = []
for (let key in delta.attributes[nodeName]) {
attrs.push({ key, value: delta.attributes[nodeName][key] })
}
// sort attributes to get a unique order
attrs.sort((a, b) => a.key < b.key ? -1 : 1)
nestedNodes.push({ nodeName, attrs })
}
// sort node order to get a unique order
nestedNodes.sort((a, b) => a.nodeName < b.nodeName ? -1 : 1)
// now convert to dom string
let str = ''
for (let i = 0; i < nestedNodes.length; i++) {
const node = nestedNodes[i]
str += `<${node.nodeName}`
for (let j = 0; j < node.attrs.length; j++) {
const attr = node.attrs[i]
str += ` ${attr.key}="${attr.value}"`
}
str += '>'
}
str += delta.insert
for (let i = nestedNodes.length - 1; i >= 0; i--) {
str += `</${nestedNodes[i].nodeName}>`
}
return str
}).join('')
}
/**
* @param {encoding.Encoder} encoder
*

View File

@ -241,6 +241,10 @@ export const createAbsolutePositionFromCursor = (cursor, y) => {
if (tname !== null) {
type = y.get(tname)
} else if (typeID !== null) {
if (getState(store, typeID.client) <= typeID.clock) {
// type does not exist yet
return null
}
const struct = getItemType(store, typeID)
if (struct instanceof ItemType) {
type = struct.type