diff --git a/src/Connector.js b/src/Connector.js index b6d1f3f5..f8c76d03 100644 --- a/src/Connector.js +++ b/src/Connector.js @@ -132,6 +132,7 @@ export default class AbstractConnector { f() } this.whenSyncedListeners = [] + this.y.emit('synced') } } diff --git a/src/Type/YMap.js b/src/Type/YMap.js index ccab1010..03cd780f 100644 --- a/src/Type/YMap.js +++ b/src/Type/YMap.js @@ -34,6 +34,9 @@ export default class YMap extends Type { } return map } + keys () { + return this._map.keys() + } delete (key) { this._transact((y) => { let c = this._map.get(key) @@ -58,6 +61,7 @@ export default class YMap extends Type { let v if (typeof value === 'function') { v = new value() // eslint-disable-line new-cap + value = v } else if (value instanceof Item) { v = value } else { diff --git a/src/Type/y-xml/YXmlElement.js b/src/Type/y-xml/YXmlElement.js index 64eb7a6f..b38c4e64 100644 --- a/src/Type/y-xml/YXmlElement.js +++ b/src/Type/y-xml/YXmlElement.js @@ -11,7 +11,7 @@ export default class YXmlElement extends YXmlFragment { this._scrollElement = null if (typeof arg1 === 'string') { this.nodeName = arg1.toUpperCase() - } else if (arg1 != null && arg1.nodeType != null && arg1.nodeType === document.ELEMENT_NODE) { + } else if (arg1 != null && arg1.nodeType != null && arg1.nodeType === arg1.ELEMENT_NODE) { this.nodeName = arg1.nodeName this._setDom(arg1) } else { diff --git a/src/Type/y-xml/YXmlFragment.js b/src/Type/y-xml/YXmlFragment.js index ffa3f558..d1439ee5 100644 --- a/src/Type/y-xml/YXmlFragment.js +++ b/src/Type/y-xml/YXmlFragment.js @@ -17,9 +17,9 @@ function domToYXml (parent, doms) { } if (parent._domFilter(d, []) !== null) { let type - if (d.nodeType === document.TEXT_NODE) { + if (d.nodeType === d.TEXT_NODE) { type = new YXmlText(d) - } else if (d.nodeType === document.ELEMENT_NODE) { + } else if (d.nodeType === d.ELEMENT_NODE) { type = new YXmlFragment._YXmlElement(d, parent._domFilter) } else { throw new Error('Unsupported node!') diff --git a/src/Type/y-xml/YXmlText.js b/src/Type/y-xml/YXmlText.js index e8c48c18..c3d3f5db 100644 --- a/src/Type/y-xml/YXmlText.js +++ b/src/Type/y-xml/YXmlText.js @@ -5,7 +5,7 @@ export default class YXmlText extends YText { let dom = null let initialText = null if (arg1 != null) { - if (arg1.nodeType === document.TEXT_NODE) { + if (arg1.nodeType != null && arg1.nodeType === arg1.TEXT_NODE) { dom = arg1 initialText = dom.nodeValue } else if (typeof arg1 === 'string') { diff --git a/src/Util/NamedEventHandler.js b/src/Util/NamedEventHandler.js index cbb07c9d..8ba9d7aa 100644 --- a/src/Util/NamedEventHandler.js +++ b/src/Util/NamedEventHandler.js @@ -2,13 +2,24 @@ export default class NamedEventHandler { constructor () { this._eventListener = new Map() } - on (name, f) { - let fSet = this._eventListener.get(name) - if (fSet === undefined) { - fSet = new Set() - this._eventListener.set(name, fSet) + _getListener (name) { + let listeners = this._eventListener.get(name) + if (listeners === undefined) { + listeners = { + once: new Set(), + on: new Set() + } + this._eventListener.set(name, listeners) } - fSet.add(f) + return listeners + } + once (name, f) { + let listeners = this._getListener(name) + listeners.once.add(f) + } + on (name, f) { + let listeners = this._getListener(name) + listeners.on.add(f) } off (name, f) { if (name == null || f == null) { @@ -22,7 +33,9 @@ export default class NamedEventHandler { emit (name, ...args) { const listener = this._eventListener.get(name) if (listener !== undefined) { - listener.forEach(f => f.apply(null, args)) + listener.on.forEach(f => f.apply(null, args)) + listener.once.forEach(f => f.apply(null, args)) + listener.once = new Set() } else if (name === 'error') { console.error(args[0]) } diff --git a/src/Y.js b/src/Y.js index 746aeda9..045dc101 100644 --- a/src/Y.js +++ b/src/Y.js @@ -24,6 +24,7 @@ export default class Y extends NamedEventHandler { super() this._opts = opts this.userID = opts._userID != null ? opts._userID : generateUserID() + this.share = {} this.ds = new DeleteStore(this) this.os = new OperationStore(this) this.ss = new StateStore(this) @@ -71,7 +72,7 @@ export default class Y extends NamedEventHandler { get room () { return this._opts.connector.room } - get (name, TypeConstructor) { + define (name, TypeConstructor) { let id = new RootID(name, TypeConstructor) let type = this.os.get(id) if (type === null) { @@ -79,9 +80,18 @@ export default class Y extends NamedEventHandler { type._id = id type._parent = this type._integrate(this) + if (this.share[name] !== undefined) { + throw new Error('Type is already defined with a different constructor!') + } + } + if (this.share[name] === undefined) { + this.share[name] = type } return type } + get (name) { + return this.share[name] + } disconnect () { if (this.connected) { this.connected = false @@ -109,6 +119,13 @@ export default class Y extends NamedEventHandler { this.ds = null this.ss = null } + whenSynced () { + return new Promise(resolve => { + this.once('synced', () => { + resolve() + }) + }) + } } Y.extend = function extendYjs () {