fix event.path by using event.currentTarget

This commit is contained in:
Kevin Jahns 2017-11-08 17:31:12 -08:00
parent a08624c04e
commit 4f55e8c655
5 changed files with 67 additions and 27 deletions

View File

@ -16,7 +16,9 @@ window.onload = function () {
// Bind children of XmlFragment to the document.body
window.yXmlType.bindToDom(document.body)
}
window.undoManager = new Y.utils.UndoManager(window.yXmlType)
window.undoManager = new Y.utils.UndoManager(window.yXmlType, {
captureTimeout: 1000
})
document.onkeydown = function interceptUndoRedo (e) {
if (e.keyCode === 90 && e.ctrlKey) {

View File

@ -39,6 +39,32 @@ export default class Type extends Item {
this._eventHandler = new EventHandler()
this._deepEventHandler = new EventHandler()
}
getPathTo (type) {
if (type === this) {
return []
}
const path = []
const y = this._y
while (type._parent !== this && this._parent !== y) {
let parent = type._parent
if (type._parentSub !== null) {
path.push(type._parentSub)
} else {
// parent is array-ish
for (let [i, child] of parent) {
if (child === type) {
path.push(i)
break
}
}
}
type = parent
}
if (this._parent !== this) {
throw new Error('The type is not a child of this node')
}
return path
}
_callEventHandler (event) {
const changedParentTypes = this._y._transaction.changedParentTypes
this._eventHandler.callEventListeners(event)

View File

@ -2,6 +2,7 @@ import ID from './ID.js'
class ReverseOperation {
constructor (y) {
this.created = new Date()
const beforeState = y._transaction.beforeState
this.toState = new ID(y.userID, y.ss.getState(y.userID) - 1)
if (beforeState.has(y.userID)) {
@ -24,7 +25,9 @@ function isStructInScope (y, struct, scope) {
}
export default class UndoManager {
constructor (scope) {
constructor (scope, options = {}) {
this.options = options
options.captureTimeout = options.captureTimeout || 0
this._undoBuffer = []
this._redoBuffer = []
this._scope = scope
@ -36,7 +39,15 @@ export default class UndoManager {
if (!remote && (y._transaction.beforeState.has(y.userID) || y._transaction.deletedStructs.size > 0)) {
let reverseOperation = new ReverseOperation(y)
if (!this._undoing) {
this._undoBuffer.push(reverseOperation)
let lastUndoOp = this._undoBuffer.length > 0 ? this._undoBuffer[this._undoBuffer.length - 1] : null
if (lastUndoOp !== null && lastUndoOp.created - reverseOperation.created <= options.captureTimeout) {
console.log('appending', lastUndoOp, reverseOperation)
lastUndoOp.created = reverseOperation.created
lastUndoOp.toState = reverseOperation.toState
reverseOperation.deletedStructs.forEach(lastUndoOp.deletedStructs.add, lastUndoOp.deletedStructs)
} else {
this._undoBuffer.push(reverseOperation)
}
if (!this._redoing) {
this._redoBuffer = []
}
@ -47,6 +58,7 @@ export default class UndoManager {
})
}
undo () {
console.log('undoing')
this._undoing = true
this._applyReverseOperation(this._undoBuffer)
this._undoing = false

View File

@ -2,32 +2,27 @@
export default class YEvent {
constructor (target) {
this.target = target
this._path = null
this.currentTarget = target
}
get path () {
if (this._path !== null) {
return this._path
} else {
const path = []
let type = this.target
const y = type._y
while (type._parent !== y) {
let parent = type._parent
if (type._parentSub !== null) {
path.push(type._parentSub)
} else {
// parent is array-ish
for (let [i, child] of parent) {
if (child === type) {
path.push(i)
break
}
const path = []
let type = this.target
const y = type._y
while (type._parent !== this._currentTarget && type._parent !== y) {
let parent = type._parent
if (type._parentSub !== null) {
path.push(type._parentSub)
} else {
// parent is array-ish
for (let [i, child] of parent) {
if (child === type) {
path.push(i)
break
}
}
type = parent
}
this._path = path
return path
type = parent
}
return path
}
}

View File

@ -61,9 +61,14 @@ export default class Y extends NamedEventHandler {
})
this._transaction.changedParentTypes.forEach(function (events, type) {
if (!type._deleted) {
events = events.filter(event =>
!event.target._deleted
)
events = events
.filter(event =>
!event.target._deleted
)
events
.forEach(event => {
event.currentTarget = type
})
// we don't have to check for events.length
// because there is no way events is empty..
type._deepEventHandler.callEventListeners(events)