observeDeep receives array of events
This commit is contained in:
parent
c453593ee7
commit
e5f289506f
@ -40,10 +40,16 @@ export default class Type extends Item {
|
|||||||
this._deepEventHandler = new EventHandler()
|
this._deepEventHandler = new EventHandler()
|
||||||
}
|
}
|
||||||
_callEventHandler (event) {
|
_callEventHandler (event) {
|
||||||
|
const changedParentTypes = this._y._transaction.changedParentTypes
|
||||||
this._eventHandler.callEventListeners(event)
|
this._eventHandler.callEventListeners(event)
|
||||||
let type = this
|
let type = this
|
||||||
while (type !== this._y) {
|
while (type !== this._y) {
|
||||||
type._deepEventHandler.callEventListeners(event)
|
let events = changedParentTypes.get(type)
|
||||||
|
if (events === undefined) {
|
||||||
|
events = []
|
||||||
|
changedParentTypes.set(type, events)
|
||||||
|
}
|
||||||
|
events.push(event)
|
||||||
type = type._parent
|
type = type._parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ export default class Transaction {
|
|||||||
this.changedTypes = new Map()
|
this.changedTypes = new Map()
|
||||||
this.deletedStructs = new Set()
|
this.deletedStructs = new Set()
|
||||||
this.beforeState = new Map()
|
this.beforeState = new Map()
|
||||||
|
this.changedParentTypes = new Map()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,6 +98,14 @@ export default class YMap extends Type {
|
|||||||
return v._content[v._content.length - 1]
|
return v._content[v._content.length - 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
has (key) {
|
||||||
|
let v = this._map.get(key)
|
||||||
|
if (v === undefined || v._deleted) {
|
||||||
|
return false
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
_logString () {
|
_logString () {
|
||||||
const left = this._left !== null ? this._left._lastId : null
|
const left = this._left !== null ? this._left._lastId : null
|
||||||
const origin = this._origin !== null ? this._origin._lastId : null
|
const origin = this._origin !== null ? this._origin._lastId : null
|
||||||
|
@ -135,90 +135,92 @@ export function applyChangesFromDom (dom) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function reflectChangesOnDom (event) {
|
export function reflectChangesOnDom (events) {
|
||||||
const yxml = event.target
|
this._mutualExclude(() => {
|
||||||
const dom = yxml._dom
|
events.forEach(event => {
|
||||||
if (dom != null) {
|
const yxml = event.target
|
||||||
this._mutualExclude(() => {
|
const dom = yxml._dom
|
||||||
// TODO: do this once before applying stuff
|
if (dom != null) {
|
||||||
// let anchorViewPosition = getAnchorViewPosition(yxml._scrollElement)
|
// TODO: do this once before applying stuff
|
||||||
if (yxml.constructor === YXmlText) {
|
// let anchorViewPosition = getAnchorViewPosition(yxml._scrollElement)
|
||||||
yxml._dom.nodeValue = yxml.toString()
|
if (yxml.constructor === YXmlText) {
|
||||||
} else {
|
yxml._dom.nodeValue = yxml.toString()
|
||||||
// update attributes
|
} else {
|
||||||
event.attributesChanged.forEach(attributeName => {
|
// update attributes
|
||||||
const value = yxml.getAttribute(attributeName)
|
event.attributesChanged.forEach(attributeName => {
|
||||||
if (value === undefined) {
|
const value = yxml.getAttribute(attributeName)
|
||||||
dom.removeAttribute(attributeName)
|
if (value === undefined) {
|
||||||
} else {
|
dom.removeAttribute(attributeName)
|
||||||
dom.setAttribute(attributeName, value)
|
} else {
|
||||||
}
|
dom.setAttribute(attributeName, value)
|
||||||
})
|
}
|
||||||
if (event.childListChanged) {
|
|
||||||
// create fragment of undeleted nodes
|
|
||||||
const fragment = document.createDocumentFragment()
|
|
||||||
yxml.forEach(function (t) {
|
|
||||||
fragment.append(t.getDom())
|
|
||||||
})
|
})
|
||||||
// remove remainding nodes
|
if (event.childListChanged) {
|
||||||
let lastChild = dom.lastChild
|
// create fragment of undeleted nodes
|
||||||
while (lastChild !== null) {
|
const fragment = document.createDocumentFragment()
|
||||||
dom.removeChild(lastChild)
|
yxml.forEach(function (t) {
|
||||||
lastChild = dom.lastChild
|
fragment.append(t.getDom())
|
||||||
|
})
|
||||||
|
// remove remainding nodes
|
||||||
|
let lastChild = dom.lastChild
|
||||||
|
while (lastChild !== null) {
|
||||||
|
dom.removeChild(lastChild)
|
||||||
|
lastChild = dom.lastChild
|
||||||
|
}
|
||||||
|
// insert fragment of undeleted nodes
|
||||||
|
dom.append(fragment)
|
||||||
}
|
}
|
||||||
// insert fragment of undeleted nodes
|
|
||||||
dom.append(fragment)
|
|
||||||
}
|
}
|
||||||
}
|
/* TODO: smartscrolling
|
||||||
/* TODO: smartscrolling
|
.. else if (event.type === 'childInserted' || event.type === 'insert') {
|
||||||
.. else if (event.type === 'childInserted' || event.type === 'insert') {
|
let nodes = event.values
|
||||||
let nodes = event.values
|
for (let i = nodes.length - 1; i >= 0; i--) {
|
||||||
for (let i = nodes.length - 1; i >= 0; i--) {
|
let node = nodes[i]
|
||||||
let node = nodes[i]
|
node.setDomFilter(yxml._domFilter)
|
||||||
node.setDomFilter(yxml._domFilter)
|
node.enableSmartScrolling(yxml._scrollElement)
|
||||||
node.enableSmartScrolling(yxml._scrollElement)
|
let dom = node.getDom()
|
||||||
let dom = node.getDom()
|
let fixPosition = null
|
||||||
let fixPosition = null
|
let nextDom = null
|
||||||
let nextDom = null
|
if (yxml._content.length > event.index + i + 1) {
|
||||||
if (yxml._content.length > event.index + i + 1) {
|
nextDom = yxml.get(event.index + i + 1).getDom()
|
||||||
nextDom = yxml.get(event.index + i + 1).getDom()
|
}
|
||||||
}
|
yxml._dom.insertBefore(dom, nextDom)
|
||||||
yxml._dom.insertBefore(dom, nextDom)
|
if (anchorViewPosition === null) {
|
||||||
if (anchorViewPosition === null) {
|
// nop
|
||||||
// nop
|
} else if (anchorViewPosition.anchor !== null) {
|
||||||
} else if (anchorViewPosition.anchor !== null) {
|
// no scrolling when current selection
|
||||||
// no scrolling when current selection
|
if (!dom.contains(anchorViewPosition.anchor) && !anchorViewPosition.anchor.contains(dom)) {
|
||||||
if (!dom.contains(anchorViewPosition.anchor) && !anchorViewPosition.anchor.contains(dom)) {
|
fixPosition = anchorViewPosition
|
||||||
|
}
|
||||||
|
} else if (getBoundingClientRect(dom).top <= 0) {
|
||||||
|
// adjust scrolling if modified element is out of view,
|
||||||
|
// there is no anchor element, and the browser did not adjust scrollTop (this is checked later)
|
||||||
fixPosition = anchorViewPosition
|
fixPosition = anchorViewPosition
|
||||||
}
|
}
|
||||||
} else if (getBoundingClientRect(dom).top <= 0) {
|
fixScrollPosition(yxml._scrollElement, fixPosition)
|
||||||
// adjust scrolling if modified element is out of view,
|
|
||||||
// there is no anchor element, and the browser did not adjust scrollTop (this is checked later)
|
|
||||||
fixPosition = anchorViewPosition
|
|
||||||
}
|
}
|
||||||
fixScrollPosition(yxml._scrollElement, fixPosition)
|
} else if (event.type === 'childRemoved' || event.type === 'delete') {
|
||||||
}
|
for (let i = event.values.length - 1; i >= 0; i--) {
|
||||||
} else if (event.type === 'childRemoved' || event.type === 'delete') {
|
let dom = event.values[i]._dom
|
||||||
for (let i = event.values.length - 1; i >= 0; i--) {
|
let fixPosition = null
|
||||||
let dom = event.values[i]._dom
|
if (anchorViewPosition === null) {
|
||||||
let fixPosition = null
|
// nop
|
||||||
if (anchorViewPosition === null) {
|
} else if (anchorViewPosition.anchor !== null) {
|
||||||
// nop
|
// no scrolling when current selection
|
||||||
} else if (anchorViewPosition.anchor !== null) {
|
if (!dom.contains(anchorViewPosition.anchor) && !anchorViewPosition.anchor.contains(dom)) {
|
||||||
// no scrolling when current selection
|
fixPosition = anchorViewPosition
|
||||||
if (!dom.contains(anchorViewPosition.anchor) && !anchorViewPosition.anchor.contains(dom)) {
|
}
|
||||||
|
} else if (getBoundingClientRect(dom).top <= 0) {
|
||||||
|
// adjust scrolling if modified element is out of view,
|
||||||
|
// there is no anchor element, and the browser did not adjust scrollTop (this is checked later)
|
||||||
fixPosition = anchorViewPosition
|
fixPosition = anchorViewPosition
|
||||||
}
|
}
|
||||||
} else if (getBoundingClientRect(dom).top <= 0) {
|
dom.remove()
|
||||||
// adjust scrolling if modified element is out of view,
|
fixScrollPosition(yxml._scrollElement, fixPosition)
|
||||||
// there is no anchor element, and the browser did not adjust scrollTop (this is checked later)
|
|
||||||
fixPosition = anchorViewPosition
|
|
||||||
}
|
}
|
||||||
dom.remove()
|
|
||||||
fixScrollPosition(yxml._scrollElement, fixPosition)
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
})
|
})
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
@ -2,26 +2,32 @@
|
|||||||
export default class YEvent {
|
export default class YEvent {
|
||||||
constructor (target) {
|
constructor (target) {
|
||||||
this.target = target
|
this.target = target
|
||||||
|
this._path = null
|
||||||
}
|
}
|
||||||
get path () {
|
get path () {
|
||||||
const path = []
|
if (this._path !== null) {
|
||||||
let type = this.target
|
return this._path
|
||||||
const y = type._y
|
} else {
|
||||||
while (type._parent !== y) {
|
const path = []
|
||||||
let parent = type._parent
|
let type = this.target
|
||||||
if (type._parentSub !== null) {
|
const y = type._y
|
||||||
path.push(type._parentSub)
|
while (type._parent !== y) {
|
||||||
} else {
|
let parent = type._parent
|
||||||
// parent is array-ish
|
if (type._parentSub !== null) {
|
||||||
for (let [i, child] of parent) {
|
path.push(type._parentSub)
|
||||||
if (child === type) {
|
} else {
|
||||||
path.push(i)
|
// parent is array-ish
|
||||||
break
|
for (let [i, child] of parent) {
|
||||||
|
if (child === type) {
|
||||||
|
path.push(i)
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
type = parent
|
||||||
}
|
}
|
||||||
type = parent
|
this._path = path
|
||||||
|
return path
|
||||||
}
|
}
|
||||||
return path
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
14
src/Y.js
14
src/Y.js
@ -55,7 +55,19 @@ export default class Y extends NamedEventHandler {
|
|||||||
if (initialCall) {
|
if (initialCall) {
|
||||||
// emit change events on changed types
|
// emit change events on changed types
|
||||||
this._transaction.changedTypes.forEach(function (subs, type) {
|
this._transaction.changedTypes.forEach(function (subs, type) {
|
||||||
type._callObserver(subs, remote)
|
if (!type._deleted) {
|
||||||
|
type._callObserver(subs, remote)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this._transaction.changedParentTypes.forEach(function (events, type) {
|
||||||
|
if (!type._deleted) {
|
||||||
|
events = events.filter(event =>
|
||||||
|
!event.target._deleted
|
||||||
|
)
|
||||||
|
// we don't have to check for events.length
|
||||||
|
// because there is no way events is empty..
|
||||||
|
type._deepEventHandler.callEventListeners(events)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
// when all changes & events are processed, emit afterTransaction event
|
// when all changes & events are processed, emit afterTransaction event
|
||||||
this.emit('afterTransaction', this, remote)
|
this.emit('afterTransaction', this, remote)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user