in src/lib/api/event.recorder.ts [198:296]
export function createListenHandler(
_document: Document,
prebootData: PrebootData,
eventSelector: EventSelector,
appData: PrebootAppData
): EventListener {
const CARET_EVENTS = ['keyup', 'keydown', 'focusin', 'mouseup', 'mousedown'];
const CARET_NODES = ['INPUT', 'TEXTAREA'];
// Support: IE 9-11 only
// IE uses a prefixed `matches` version
const matches = _document.documentElement.matches ||
(_document.documentElement as any).msMatchesSelector;
const opts = prebootData.opts;
return function(event: DomEvent) {
const node: Element = event.target;
// a delegated handlers on document is used so we need to check if
// event target matches a desired selector
if (!matches.call(node, eventSelector.selector)) {
return;
}
const root = appData.root;
const eventName = event.type;
// if no node or no event name, just return
if (!node || !eventName) {
return;
}
// if key codes set for eventSelector, then don't do anything if event
// doesn't include key
const keyCodes = eventSelector.keyCodes;
if (keyCodes && keyCodes.length) {
const matchingKeyCodes = keyCodes.filter(keyCode => event.which === keyCode);
// if there are not matches (i.e. key entered NOT one of the key codes)
// then don't do anything
if (!matchingKeyCodes.length) {
return;
}
}
// if for a given set of events we are preventing default, do that
if (eventSelector.preventDefault) {
event.preventDefault();
}
// if an action handler passed in, use that
if (eventSelector.action) {
eventSelector.action(node, event);
}
// get the node key for a given node
const nodeKey = getNodeKeyForPreboot({ root: root, node: node });
// record active node
if (CARET_EVENTS.indexOf(eventName) >= 0) {
// if it's an caret node, get the selection for the active node
const isCaretNode = CARET_NODES.indexOf(node.tagName ? node.tagName : '') >= 0;
prebootData.activeNode = {
root: root,
node: node,
nodeKey: nodeKey,
selection: isCaretNode ? getSelection(node as HTMLInputElement) : undefined
};
} else if (eventName !== 'change' && eventName !== 'focusout') {
prebootData.activeNode = undefined;
}
// if overlay is not disabled and we are freezing the UI
if (opts && !opts.disableOverlay && eventSelector.freeze) {
const overlay = root.overlay as HTMLElement;
// show the overlay
overlay.style.display = 'block';
// hide the overlay after 10 seconds just in case preboot.complete() never
// called
setTimeout(() => {
overlay.style.display = 'none';
}, 10000);
}
// we will record events for later replay unless explicitly marked as
// doNotReplay
if (eventSelector.replay) {
appData.events.push({
node,
nodeKey,
event,
name: eventName
});
}
};
}