1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 | 507× 507× 507× 3× 3× 3910× 3907× 3× 3× 4× 4× 4× 2× 3× 3× 3× 3× 3× | import { isEqual, forEach, isArray, TreeIndex } from '../util' class PathEventProxy { constructor(doc) { this.listeners = new TreeIndex.Arrays() this._list = [] this.doc = doc } on(path, method, context) { this._add(context, path, method) } // proxy.off(this) // proxy.off(this, path) // proxy.off(this, path, this.onPropertyUpdate) off(context, path, method) { this._remove(context, path, method) } connect(listener, path, method) { console.warn('DEPRECATED: use proxy.on(path, this.onPropertyChange, this) instead') this.on(path, method, listener) } disconnect(listener) { console.warn('DEPRECATED: use proxy.off(this) instead') this.off(listener) } onDocumentChanged(change, info, doc) { // stop if no listeners registered if (this._list.length === 0) { return } var listeners = this.listeners forEach(change.updated, function(_, pathStr) { var scopedListeners = listeners.get(pathStr.split(',')) Eif (isArray(scopedListeners)) scopedListeners = scopedListeners.slice(0) forEach(scopedListeners, function(entry) { entry.method.call(entry.listener, change, info, doc) }) }) } _add(listener, path, method) { Iif (!method) { throw new Error('Invalid argument: expected function but got ' + method) } var entry = { listener: listener, path: path, method: method } this.listeners.add(path, entry) this._list.push(entry) } _remove(listener, path, method) { for (var i = 0; i < this._list.length; i++) { var item = this._list[i] var match = ( (!path || isEqual(item.path, path)) && (!listener || item.listener === listener) && (!method || item.method !== method) ) if (match) { var entry = this._list[i] this._list.splice(i, 1) this.listeners.remove(entry.path, entry) } } } } export default PathEventProxy |