Spaces:
Running
Running
| /* ngraph.events @ anvaka/ngraph.events (BSD-3-Clause) © Andrei Kashcha. Vendored 0-CDN; ESM source wrapped as UMD global `ngraphEvents`. */ | |
| (function(root,factory){if(typeof module==='object'&&module.exports){module.exports=factory();}else if(typeof define==='function'&&define.amd){define([],factory);}else{root.ngraphEvents=factory();}}(typeof self!=='undefined'?self:this,function(){ | |
| function eventify(subject) { | |
| validateSubject(subject); | |
| const eventsStorage = createEventsStorage(subject); | |
| subject.on = eventsStorage.on; | |
| subject.off = eventsStorage.off; | |
| subject.fire = eventsStorage.fire; | |
| return subject; | |
| } | |
| function createEventsStorage(subject) { | |
| // Store all event listeners to this hash. Key is event name, value is array | |
| // of callback records. | |
| // | |
| // A callback record consists of callback function and its optional context: | |
| // { 'eventName' => [{callback: function, ctx: object}] } | |
| let registeredEvents = Object.create(null); | |
| return { | |
| on: function (eventName, callback, ctx) { | |
| if (typeof callback !== 'function') { | |
| throw new Error('callback is expected to be a function'); | |
| } | |
| let handlers = registeredEvents[eventName]; | |
| if (!handlers) { | |
| handlers = registeredEvents[eventName] = []; | |
| } | |
| handlers.push({ callback: callback, ctx: ctx }); | |
| return subject; | |
| }, | |
| off: function (eventName, callback) { | |
| const wantToRemoveAll = (typeof eventName === 'undefined'); | |
| if (wantToRemoveAll) { | |
| // Killing old events storage should be enough in this case: | |
| registeredEvents = Object.create(null); | |
| return subject; | |
| } | |
| if (registeredEvents[eventName]) { | |
| const deleteAllCallbacksForEvent = (typeof callback !== 'function'); | |
| if (deleteAllCallbacksForEvent) { | |
| delete registeredEvents[eventName]; | |
| } else { | |
| const callbacks = registeredEvents[eventName]; | |
| for (let i = 0; i < callbacks.length; ++i) { | |
| if (callbacks[i].callback === callback) { | |
| callbacks.splice(i, 1); | |
| } | |
| } | |
| } | |
| } | |
| return subject; | |
| }, | |
| fire: function (eventName) { | |
| const callbacks = registeredEvents[eventName]; | |
| if (!callbacks) { | |
| return subject; | |
| } | |
| let fireArguments; | |
| if (arguments.length > 1) { | |
| // copy all args after eventName | |
| fireArguments = Array.prototype.slice.call(arguments, 1); | |
| } | |
| for (let i = 0; i < callbacks.length; ++i) { | |
| const callbackInfo = callbacks[i]; | |
| callbackInfo.callback.apply(callbackInfo.ctx, fireArguments); | |
| } | |
| return subject; | |
| } | |
| }; | |
| } | |
| function validateSubject(subject) { | |
| if (!subject) { | |
| throw new Error('Eventify cannot use falsy object as events subject'); | |
| } | |
| const reservedWords = ['on', 'fire', 'off']; | |
| for (let i = 0; i < reservedWords.length; ++i) { | |
| if (subject.hasOwnProperty(reservedWords[i])) { | |
| throw new Error("Subject cannot be eventified, since it already has property '" + reservedWords[i] + "'"); | |
| } | |
| } | |
| } | |
| return eventify; | |
| })); | |