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 // Bind children of XmlFragment to the document.body
window.yXmlType.bindToDom(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) { document.onkeydown = function interceptUndoRedo (e) {
if (e.keyCode === 90 && e.ctrlKey) { if (e.keyCode === 90 && e.ctrlKey) {

View File

@ -39,6 +39,32 @@ export default class Type extends Item {
this._eventHandler = new EventHandler() this._eventHandler = new EventHandler()
this._deepEventHandler = 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) { _callEventHandler (event) {
const changedParentTypes = this._y._transaction.changedParentTypes const changedParentTypes = this._y._transaction.changedParentTypes
this._eventHandler.callEventListeners(event) this._eventHandler.callEventListeners(event)

View File

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

View File

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

View File

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