diff --git a/examples/html-editor/index.js b/examples/html-editor/index.js index 6766fed6..e2676340 100644 --- a/examples/html-editor/index.js +++ b/examples/html-editor/index.js @@ -1,4 +1,15 @@ -/* global Y */ +/* global Y, HTMLElement, customElements */ + +class MagicTable extends HTMLElement { + constructor () { + super() + var shadow = this.attachShadow({mode: 'open'}) + setTimeout(() => { + shadow.append(this.childNodes[0]) + }, 1000) + } +} +customElements.define('magic-table', MagicTable) // initialize a shared object. This function call returns a promise! let y = new Y({ @@ -17,17 +28,14 @@ window.onload = function () { window.yXmlType.bindToDom(document.body) } window.undoManager = new Y.utils.UndoManager(window.yXmlType, { - captureTimeout: 0 + captureTimeout: 500 }) document.onkeydown = function interceptUndoRedo (e) { if (e.keyCode === 90 && e.metaKey) { - console.log('uidtaren') if (!e.shiftKey) { - console.info('Undo!') window.undoManager.undo() } else { - console.info('Redo!') window.undoManager.redo() } e.preventDefault() diff --git a/rollup.browser.js b/rollup.browser.js index 083f0406..4eade0e4 100644 --- a/rollup.browser.js +++ b/rollup.browser.js @@ -5,9 +5,13 @@ import commonjs from 'rollup-plugin-commonjs' var pkg = require('./package.json') export default { - entry: 'src/Y.js', - moduleName: 'Y', - format: 'umd', + input: 'src/Y.js', + name: 'Y', + sourcemap: true, + output: { + file: 'y.js', + format: 'umd' + }, plugins: [ nodeResolve({ main: true, @@ -32,8 +36,6 @@ export default { } }) ], - dest: 'y.js', - sourceMap: true, banner: ` /** * ${pkg.name} - ${pkg.description} diff --git a/rollup.node.js b/rollup.node.js index 1a795945..6d24306f 100644 --- a/rollup.node.js +++ b/rollup.node.js @@ -3,9 +3,13 @@ import commonjs from 'rollup-plugin-commonjs' var pkg = require('./package.json') export default { - entry: 'src/y-dist.cjs.js', - moduleName: 'Y', - format: 'cjs', + input: 'src/y-dist.cjs.js', + nameame: 'Y', + sourcemap: true, + output: { + file: 'y.node.js', + format: 'cjs' + }, plugins: [ nodeResolve({ main: true, @@ -14,8 +18,6 @@ export default { }), commonjs() ], - dest: 'y.node.js', - sourceMap: true, banner: ` /** * ${pkg.name} - ${pkg.description} diff --git a/rollup.test.js b/rollup.test.js index c74129e6..bb69a58f 100644 --- a/rollup.test.js +++ b/rollup.test.js @@ -3,9 +3,13 @@ import commonjs from 'rollup-plugin-commonjs' import multiEntry from 'rollup-plugin-multi-entry' export default { - entry: 'test/y-xml.tests.js', - moduleName: 'y-tests', - format: 'umd', + input: 'test/y-xml.tests.js', + name: 'y-tests', + sourcemap: true, + output: { + file: 'y.test.js', + format: 'umd' + }, plugins: [ nodeResolve({ main: true, @@ -14,7 +18,5 @@ export default { }), commonjs(), multiEntry() - ], - dest: 'y.test.js', - sourceMap: true + ] } diff --git a/src/Struct/Type.js b/src/Struct/Type.js index 6d7c4d1b..60828f9b 100644 --- a/src/Struct/Type.js +++ b/src/Struct/Type.js @@ -65,9 +65,9 @@ export default class Type extends Item { } return path } - _callEventHandler (event) { - const changedParentTypes = this._y._transaction.changedParentTypes - this._eventHandler.callEventListeners(event) + _callEventHandler (transaction, event) { + const changedParentTypes = transaction.changedParentTypes + this._eventHandler.callEventListeners(transaction, event) let type = this while (type !== this._y) { let events = changedParentTypes.get(type) diff --git a/src/Type/YArray.js b/src/Type/YArray.js index d277327f..7e6766a2 100644 --- a/src/Type/YArray.js +++ b/src/Type/YArray.js @@ -12,8 +12,8 @@ class YArrayEvent extends YEvent { } export default class YArray extends Type { - _callObserver (parentSubs, remote) { - this._callEventHandler(new YArrayEvent(this, remote)) + _callObserver (transaction, parentSubs, remote) { + this._callEventHandler(transaction, new YArrayEvent(this, remote)) } get (pos) { let n = this._start diff --git a/src/Type/YMap.js b/src/Type/YMap.js index f1403340..b8a666c7 100644 --- a/src/Type/YMap.js +++ b/src/Type/YMap.js @@ -13,8 +13,8 @@ class YMapEvent extends YEvent { } export default class YMap extends Type { - _callObserver (parentSubs, remote) { - this._callEventHandler(new YMapEvent(this, parentSubs, remote)) + _callObserver (transaction, parentSubs, remote) { + this._callEventHandler(transaction, new YMapEvent(this, parentSubs, remote)) } toJSON () { const map = {} diff --git a/src/Type/y-xml/YXmlFragment.js b/src/Type/y-xml/YXmlFragment.js index dfe0873d..d514e9c5 100644 --- a/src/Type/y-xml/YXmlFragment.js +++ b/src/Type/y-xml/YXmlFragment.js @@ -142,8 +142,8 @@ export default class YXmlFragment extends YArray { xml.setDomFilter(f) }) } - _callObserver (parentSubs, remote) { - this._callEventHandler(new YXmlEvent(this, parentSubs, remote)) + _callObserver (transaction, parentSubs, remote) { + this._callEventHandler(transaction, new YXmlEvent(this, parentSubs, remote)) } toString () { return this.map(xml => xml.toString()).join('') diff --git a/src/Type/y-xml/selection.js b/src/Type/y-xml/selection.js index d3cbd413..44e11885 100644 --- a/src/Type/y-xml/selection.js +++ b/src/Type/y-xml/selection.js @@ -7,7 +7,7 @@ let relativeSelection = null export let beforeTransactionSelectionFixer if (typeof getSelection !== 'undefined') { - beforeTransactionSelectionFixer = function _beforeTransactionSelectionFixer (y, remote) { + beforeTransactionSelectionFixer = function _beforeTransactionSelectionFixer (y, transaction, remote) { if (!remote) { return } @@ -30,7 +30,7 @@ if (typeof getSelection !== 'undefined') { beforeTransactionSelectionFixer = function _fakeBeforeTransactionSelectionFixer () {} } -export function afterTransactionSelectionFixer (y, remote) { +export function afterTransactionSelectionFixer (y, transaction, remote) { if (relativeSelection === null || !remote) { return } diff --git a/src/Type/y-xml/utils.js b/src/Type/y-xml/utils.js index 77599702..a362b75e 100644 --- a/src/Type/y-xml/utils.js +++ b/src/Type/y-xml/utils.js @@ -138,8 +138,13 @@ export function applyChangesFromDom (dom) { export function reflectChangesOnDom (events) { // Make sure that no filtered attributes are applied to the structure // if they were, delete them + /* events.forEach(event => { const target = event.target + if (event.attributesChanged === undefined) { + // event.target is Y.XmlText + return + } const keys = this._domFilter(target.nodeName, Array.from(event.attributesChanged)) if (keys === null) { target._delete() @@ -156,6 +161,7 @@ export function reflectChangesOnDom (events) { }) } }) + */ this._mutualExclude(() => { events.forEach(event => { const yxml = event.target diff --git a/src/Util/EventHandler.js b/src/Util/EventHandler.js index 1928adac..ab3dbe4c 100644 --- a/src/Util/EventHandler.js +++ b/src/Util/EventHandler.js @@ -17,7 +17,7 @@ export default class EventHandler { removeAllEventListeners () { this.eventListeners = [] } - callEventListeners (event) { + callEventListeners (transaction, event) { for (var i = 0; i < this.eventListeners.length; i++) { try { const f = this.eventListeners[i] diff --git a/src/Util/UndoManager.js b/src/Util/UndoManager.js index 6efc76ea..a7ad9820 100644 --- a/src/Util/UndoManager.js +++ b/src/Util/UndoManager.js @@ -1,16 +1,16 @@ import ID from './ID.js' class ReverseOperation { - constructor (y) { + constructor (y, transaction) { this.created = new Date() - const beforeState = y._transaction.beforeState + const beforeState = transaction.beforeState this.toState = new ID(y.userID, y.ss.getState(y.userID) - 1) if (beforeState.has(y.userID)) { this.fromState = new ID(y.userID, beforeState.get(y.userID)) } else { this.fromState = this.toState } - this.deletedStructs = y._transaction.deletedStructs + this.deletedStructs = transaction.deletedStructs } } @@ -70,9 +70,9 @@ export default class UndoManager { this._redoing = false const y = scope._y this.y = y - y.on('afterTransaction', (y, remote) => { - if (!remote && y._transaction.changedParentTypes.has(scope)) { - let reverseOperation = new ReverseOperation(y) + y.on('afterTransaction', (y, transaction, remote) => { + if (!remote && transaction.changedParentTypes.has(scope)) { + let reverseOperation = new ReverseOperation(y, transaction) if (!this._undoing) { let lastUndoOp = this._undoBuffer.length > 0 ? this._undoBuffer[this._undoBuffer.length - 1] : null if (lastUndoOp !== null && reverseOperation.created - lastUndoOp.created <= options.captureTimeout) { diff --git a/src/Y.js b/src/Y.js index 6cdf6e74..67fc7d60 100644 --- a/src/Y.js +++ b/src/Y.js @@ -15,6 +15,7 @@ import YMap from './Type/YMap.js' import YText from './Type/YText.js' import { YXmlFragment, YXmlElement, YXmlText } from './Type/y-xml/y-xml.js' import BinaryDecoder from './Binary/Decoder.js' +import { getRelativePosition, fromRelativePosition } from './Util/relativePosition.js' import debug from 'debug' import Transaction from './Transaction.js' @@ -44,8 +45,8 @@ export default class Y extends NamedEventHandler { transact (f, remote = false) { let initialCall = this._transaction === null if (initialCall) { - this.emit('beforeTransaction', this, remote) this._transaction = new Transaction(this) + this.emit('beforeTransaction', this, this._transaction, remote) } try { f(this) @@ -53,13 +54,15 @@ export default class Y extends NamedEventHandler { console.error(e) } if (initialCall) { + const transaction = this._transaction + this._transaction = null // emit change events on changed types - this._transaction.changedTypes.forEach(function (subs, type) { + transaction.changedTypes.forEach(function (subs, type) { if (!type._deleted) { - type._callObserver(subs, remote) + type._callObserver(transaction, subs, remote) } }) - this._transaction.changedParentTypes.forEach(function (events, type) { + transaction.changedParentTypes.forEach(function (events, type) { if (!type._deleted) { events = events .filter(event => @@ -71,12 +74,11 @@ export default class Y extends NamedEventHandler { }) // we don't have to check for events.length // because there is no way events is empty.. - type._deepEventHandler.callEventListeners(events) + type._deepEventHandler.callEventListeners(transaction, events) } }) // when all changes & events are processed, emit afterTransaction event - this.emit('afterTransaction', this, remote) - this._transaction = null + this.emit('afterTransaction', this, transaction, remote) } } // fake _start for root properties (y.set('name', type)) @@ -168,7 +170,9 @@ Y.XmlText = YXmlText Y.utils = { BinaryDecoder, - UndoManager + UndoManager, + getRelativePosition, + fromRelativePosition } Y.debug = debug