UNPKG

azure-devops-ui

Version:

React components for building web UI in Azure DevOps

138 lines (137 loc) 5.74 kB
export class EventGroup { constructor(parent) { this.id = EventGroup.uniqueId++; this.isDisposed = false; this.parent = parent; this.eventRecords = []; } static raise(target, eventName, eventArgs, bubbleEvent) { let returnValue; if (EventGroup.isElement(target)) { const event = document.createEvent("HTMLEvents"); event.initEvent(eventName, bubbleEvent || false, true); Object.assign(event, eventArgs); } else { while (target && returnValue !== false) { let events = target.__events__; let eventRecords = events ? events[eventName] : null; if (eventRecords) { for (let id in eventRecords) { if (eventRecords.hasOwnProperty(id)) { let eventRecordList = eventRecords[id]; for (let listIndex = 0; returnValue !== false && listIndex < eventRecordList.length; listIndex++) { let record = eventRecordList[listIndex]; if (record.objectCallback) { returnValue = record.objectCallback.call(record.parent, eventArgs); } } } } } target = bubbleEvent ? target.parent : null; } } return returnValue; } static isElement(target) { return !!target && (!!target.addEventListener || (typeof HTMLElement !== "undefined" && target instanceof HTMLElement)); } dispose() { if (!this.isDisposed) { this.isDisposed = true; this.off(); this.parent = null; } } on(target, eventName, callback) { if (eventName.indexOf(",") > -1) { let events = eventName.split(/[,]+/); for (let event in events) { this.on(target, event, callback); } } else { let parent = this.parent; let eventRecord = { target: target, eventName: eventName, parent: parent, callback: callback }; if (!target.__events__) { target.__events__ = {}; } let events = target.__events__; if (!events[eventName]) { events[eventName] = {}; } if (!events[eventName][this.id]) { events[eventName][this.id] = []; } events[eventName][this.id].push(eventRecord); if (EventGroup.isElement(target)) { let processElementEvent = (...args) => { if (this.isDisposed) { return; } let result = callback.apply(parent, args); if (result === false && args[0]) { let e = args[0]; e.preventDefault && e.preventDefault(); e.stopPropagation && e.stopPropagation(); e.cancelBubble = true; } return result; }; eventRecord.elementCallback = processElementEvent; if (target.addEventListener) { target.addEventListener(eventName, processElementEvent); } } else { let processObjectEvent = (...args) => { if (this.isDisposed) { return; } return callback.apply(parent, args); }; eventRecord.objectCallback = processObjectEvent; } this.eventRecords.push(eventRecord); } } off(target, eventName, callback) { // For instead of foreach for (let i = 0; i < this.eventRecords.length; i++) { let eventRecord = this.eventRecords[i]; if ((!target || target === eventRecord.target) && (!eventName || eventName === eventRecord.eventName) && (!callback || callback === eventRecord.callback)) { let events = eventRecord.target.__events__; let targetArrayLookup = events[eventRecord.eventName]; let targetArray = targetArrayLookup ? targetArrayLookup[this.id] : null; if (targetArray) { if (targetArray.length === 1 || !callback) { delete events[eventRecord.eventName][this.id]; } else { targetArray.splice(targetArray.indexOf(eventRecord), 1); } // If there's no more event IDs attached, remove the eventName if (Object.keys(events[eventRecord.eventName]).length === 0) { delete events[eventRecord.eventName]; } } if (eventRecord.elementCallback) { eventRecord.target.removeEventListener(eventRecord.eventName, eventRecord.elementCallback, eventRecord.options); } this.eventRecords.splice(i--, 1); } } } raise(eventName, eventArgs, bubbleEvent) { return EventGroup.raise(this.parent, eventName, eventArgs, bubbleEvent); } } EventGroup.uniqueId = 0;