|
| 1 | +"use strict"; |
| 2 | + |
| 3 | +let sequenceCount = 0; |
| 4 | +const eventLogGroups = {}; |
| 5 | +const Uint8Array = window.Uint8Array; |
| 6 | +const TimeRanges = window.TimeRanges; |
| 7 | + |
| 8 | +function stringify(value, replacer, space) { |
| 9 | + try { |
| 10 | + return truncate(JSON.stringify(value, replacer || stringifyReplacer(value), space), 100000); |
| 11 | + } catch (error) { |
| 12 | + return `[${error}]`; |
| 13 | + } |
| 14 | +} |
| 15 | + |
| 16 | +function truncate(str, length) { |
| 17 | + return (str && str.length) > length ? (str.substr(0, length) + |
| 18 | + '\n... Event truncated due to length (see console for complete output)') : str; |
| 19 | +} |
| 20 | + |
| 21 | +function stringifyReplacer(parentValue) { |
| 22 | + const references = []; |
| 23 | + const safeResults = []; |
| 24 | + let complexity = 0; |
| 25 | + return function stringifyKeyValue(key, value) { |
| 26 | + if (typeof value === 'object') { |
| 27 | + if (value === null || value instanceof Date || value instanceof RegExp) { |
| 28 | + return value; |
| 29 | + } |
| 30 | + if (!!Uint8Array && value instanceof Uint8Array) { |
| 31 | + // Stub values of Arrays with more than 1000 items |
| 32 | + let str = ('' + value); |
| 33 | + str = (str.length > 40 ? (str.substr(0, 40) + '...(see console)') : str); |
| 34 | + return `Uint8Array(${value.length}) [${str}]`; |
| 35 | + } |
| 36 | + if (!!TimeRanges && value instanceof TimeRanges) { |
| 37 | + const ranges = []; |
| 38 | + for (let i = 0; i < value.length; i++) { |
| 39 | + ranges[i] = `start(${i}) = ${value.start(i)} end(${i}) = ${value.end(i)}`; |
| 40 | + } |
| 41 | + return `TimeRanges(${value.length}) [${ranges}]`; |
| 42 | + } |
| 43 | + if (value === parentValue && complexity > 0) { |
| 44 | + return '<parent object>'; |
| 45 | + } |
| 46 | + const referenceIndex = references.indexOf(value); |
| 47 | + if (referenceIndex !== -1) { |
| 48 | + // Duplicate reference found |
| 49 | + const safe = safeResults[referenceIndex]; |
| 50 | + if (safe) { |
| 51 | + return safe; |
| 52 | + } |
| 53 | + try { |
| 54 | + // Test for circular references |
| 55 | + JSON.stringify(value); |
| 56 | + } catch (error) { |
| 57 | + return (safeResults[referenceIndex] = '<' + value + '...(see console)>'); |
| 58 | + } |
| 59 | + safeResults[referenceIndex] = value; |
| 60 | + } |
| 61 | + if (complexity++ > 10000) { |
| 62 | + return '<complexity exceeded>'; |
| 63 | + } |
| 64 | + references.push(value); |
| 65 | + return value; |
| 66 | + } |
| 67 | + if (typeof value === 'function') { |
| 68 | + return `${value}`; |
| 69 | + } |
| 70 | + return value; |
| 71 | + }; |
| 72 | +} |
| 73 | + |
| 74 | +function createEventSequenceElement(eventGroup) { |
| 75 | + const element = document.createElement('div'); |
| 76 | + element.classList.add('sequence', `mode-${eventGroup}`); |
| 77 | + element.setAttribute('data-sequence', `${sequenceCount++}`); |
| 78 | + return element; |
| 79 | +} |
| 80 | + |
| 81 | +function appendSequenceElement(container, element) { |
| 82 | + container.appendChild(element); |
| 83 | +} |
| 84 | + |
| 85 | +function textContentGrouped(inEvent, group) { |
| 86 | + if (group) { |
| 87 | + return `${inEvent} (${group[inEvent]})`; |
| 88 | + } |
| 89 | + return inEvent; |
| 90 | +} |
| 91 | + |
| 92 | +function appendEvent(container, currentEventType, currentEventGroup, data) { |
| 93 | + const div = document.createElement('div'); |
| 94 | + div.classList.add('group-' + currentEventGroup, 'event-' + currentEventType, 'pre'); |
| 95 | + div.textContent = textContentGrouped(currentEventType); |
| 96 | + div.setAttribute('title', `${currentEventGroup} event "${currentEventType}"`); |
| 97 | + div.setAttribute('tabindex', '0'); |
| 98 | + const theData = Object.assign({}, data); |
| 99 | + div.onclick = div.onkeyup = function(e) { |
| 100 | + if (e && e.keyCode && e.keyCode !== 13) { |
| 101 | + return; |
| 102 | + } |
| 103 | + |
| 104 | + console.log(theData); |
| 105 | + div.textContent = ((div.expanded = !div.expanded)) ? |
| 106 | + textContentExpanded(currentEventType, [theData]) : textContentGrouped(currentEventType); |
| 107 | + if (e) { |
| 108 | + e.preventDefault(); |
| 109 | + } |
| 110 | + return [theData]; |
| 111 | + }; |
| 112 | + container.appendChild(div); |
| 113 | + return div; |
| 114 | +} |
| 115 | + |
| 116 | +function textContentExpanded(inEvent, allData) { |
| 117 | + return `${inEvent} (${allData.map((item, i) => |
| 118 | + (allData.length > 1 ? `[${i}] = ` : '') + stringify(item, null, 4)).join('\n')})`; |
| 119 | +} |
| 120 | + |
| 121 | +function incrementEvent(group, currentEventType, currentEventGroup, div, datum) { |
| 122 | + group[currentEventType]++; |
| 123 | + div.textContent = textContentGrouped(currentEventType, group); |
| 124 | + const logPreviousEvents = div.onclick; |
| 125 | + const scopedDatum = Object.assign({}, datum); |
| 126 | + div.onclick = div.onkeyup = function(e) { |
| 127 | + if (e && e.keyCode && e.keyCode !== 13) { |
| 128 | + return; |
| 129 | + } |
| 130 | + |
| 131 | + const allData = logPreviousEvents(); |
| 132 | + allData.push(scopedDatum); |
| 133 | + console.log(scopedDatum); |
| 134 | + div.textContent = (div.expanded) ? textContentExpanded(currentEventType, allData) : textContentGrouped(currentEventType, group); |
| 135 | + if (e) { |
| 136 | + e.preventDefault(); |
| 137 | + } |
| 138 | + return allData; |
| 139 | + }; |
| 140 | +} |
| 141 | + |
| 142 | +function getGenericEventHandler() { |
| 143 | + const logContainer = document.querySelector('#eventsLog'); |
| 144 | + let currentEventGroup = ''; |
| 145 | + let currentEventType = ''; |
| 146 | + let lastEvent = ''; |
| 147 | + let lastGroup; |
| 148 | + const genericEventHandler = function(e, type, eventGroup) { |
| 149 | + currentEventGroup = eventGroup; |
| 150 | + currentEventType = type; |
| 151 | + |
| 152 | + let group = eventLogGroups[eventGroup]; |
| 153 | + if (!group || group !== lastGroup) { |
| 154 | + const beforeReadyElement = createEventSequenceElement(currentEventGroup); |
| 155 | + appendSequenceElement(logContainer, beforeReadyElement); |
| 156 | + group = eventLogGroups[currentEventGroup] = { |
| 157 | + eventGroup: currentEventGroup, |
| 158 | + event: currentEventType, |
| 159 | + container: logContainer, |
| 160 | + eventElement: beforeReadyElement |
| 161 | + }; |
| 162 | + lastGroup = lastGroup || group; |
| 163 | + } |
| 164 | + if (lastEvent === currentEventType && !(/^(?:meta|hlsBufferAppend)/).test(currentEventType)) { |
| 165 | + incrementEvent(group, currentEventType, currentEventGroup, group.pre, e); |
| 166 | + } else { |
| 167 | + const eventElement = createEventSequenceElement(currentEventGroup); |
| 168 | + group[currentEventType] = 1; |
| 169 | + group.eventElement = eventElement; |
| 170 | + group.lastEventGroup = currentEventGroup; |
| 171 | + group.pre = appendEvent(eventElement, currentEventType, currentEventGroup, e); |
| 172 | + appendSequenceElement(group.container, eventElement); |
| 173 | + } |
| 174 | + lastEvent = currentEventType; |
| 175 | + lastGroup = group; |
| 176 | + }; |
| 177 | + |
| 178 | + return genericEventHandler; |
| 179 | +} |
| 180 | + |
| 181 | +window.getGenericEventHandler = getGenericEventHandler; |
0 commit comments