mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
788 lines
26 KiB
788 lines
26 KiB
/**
|
|
* @license Angular v21.1.1
|
|
* (c) 2010-2026 Google LLC. https://angular.dev/
|
|
* License: MIT
|
|
*/
|
|
|
|
import { Attribute } from './_attribute-chunk.mjs';
|
|
|
|
const Property = {
|
|
JSACTION: '__jsaction',
|
|
OWNER: '__owner'
|
|
};
|
|
|
|
const parseCache = {};
|
|
function get(element) {
|
|
return element[Property.JSACTION];
|
|
}
|
|
function getDefaulted(element) {
|
|
const cache = get(element) ?? {};
|
|
set(element, cache);
|
|
return cache;
|
|
}
|
|
function set(element, actionMap) {
|
|
element[Property.JSACTION] = actionMap;
|
|
}
|
|
function getParsed(text) {
|
|
return parseCache[text];
|
|
}
|
|
function setParsed(text, parsed) {
|
|
parseCache[text] = parsed;
|
|
}
|
|
|
|
const EventType = {
|
|
AUXCLICK: 'auxclick',
|
|
CHANGE: 'change',
|
|
CLICK: 'click',
|
|
CLICKMOD: 'clickmod',
|
|
CLICKONLY: 'clickonly',
|
|
DBLCLICK: 'dblclick',
|
|
FOCUS: 'focus',
|
|
FOCUSIN: 'focusin',
|
|
BLUR: 'blur',
|
|
FOCUSOUT: 'focusout',
|
|
SUBMIT: 'submit',
|
|
KEYDOWN: 'keydown',
|
|
KEYPRESS: 'keypress',
|
|
KEYUP: 'keyup',
|
|
MOUSEUP: 'mouseup',
|
|
MOUSEDOWN: 'mousedown',
|
|
MOUSEOVER: 'mouseover',
|
|
MOUSEOUT: 'mouseout',
|
|
MOUSEENTER: 'mouseenter',
|
|
MOUSELEAVE: 'mouseleave',
|
|
MOUSEMOVE: 'mousemove',
|
|
POINTERUP: 'pointerup',
|
|
POINTERDOWN: 'pointerdown',
|
|
POINTEROVER: 'pointerover',
|
|
POINTEROUT: 'pointerout',
|
|
POINTERENTER: 'pointerenter',
|
|
POINTERLEAVE: 'pointerleave',
|
|
POINTERMOVE: 'pointermove',
|
|
POINTERCANCEL: 'pointercancel',
|
|
GOTPOINTERCAPTURE: 'gotpointercapture',
|
|
LOSTPOINTERCAPTURE: 'lostpointercapture',
|
|
ERROR: 'error',
|
|
LOAD: 'load',
|
|
UNLOAD: 'unload',
|
|
TOUCHSTART: 'touchstart',
|
|
TOUCHEND: 'touchend',
|
|
TOUCHMOVE: 'touchmove',
|
|
INPUT: 'input',
|
|
SCROLL: 'scroll',
|
|
TOGGLE: 'toggle',
|
|
CUSTOM: '_custom'
|
|
};
|
|
const MOUSE_SPECIAL_EVENT_TYPES = [EventType.MOUSEENTER, EventType.MOUSELEAVE, 'pointerenter', 'pointerleave'];
|
|
const BUBBLE_EVENT_TYPES = [EventType.CLICK, EventType.DBLCLICK, EventType.FOCUSIN, EventType.FOCUSOUT, EventType.KEYDOWN, EventType.KEYUP, EventType.KEYPRESS, EventType.MOUSEOVER, EventType.MOUSEOUT, EventType.SUBMIT, EventType.TOUCHSTART, EventType.TOUCHEND, EventType.TOUCHMOVE, 'touchcancel', 'auxclick', 'change', 'compositionstart', 'compositionupdate', 'compositionend', 'beforeinput', 'input', 'select', 'copy', 'cut', 'paste', 'mousedown', 'mouseup', 'wheel', 'contextmenu', 'dragover', 'dragenter', 'dragleave', 'drop', 'dragstart', 'dragend', 'pointerdown', 'pointermove', 'pointerup', 'pointercancel', 'pointerover', 'pointerout', 'gotpointercapture', 'lostpointercapture', 'ended', 'loadedmetadata', 'pagehide', 'pageshow', 'visibilitychange', 'beforematch'];
|
|
const CAPTURE_EVENT_TYPES = [EventType.FOCUS, EventType.BLUR, EventType.ERROR, EventType.LOAD, EventType.TOGGLE];
|
|
const isCaptureEventType = eventType => CAPTURE_EVENT_TYPES.indexOf(eventType) >= 0;
|
|
const EARLY_EVENT_TYPES = BUBBLE_EVENT_TYPES.concat(CAPTURE_EVENT_TYPES);
|
|
const isEarlyEventType = eventType => EARLY_EVENT_TYPES.indexOf(eventType) >= 0;
|
|
|
|
function getBrowserEventType(eventType) {
|
|
if (eventType === EventType.MOUSEENTER) {
|
|
return EventType.MOUSEOVER;
|
|
} else if (eventType === EventType.MOUSELEAVE) {
|
|
return EventType.MOUSEOUT;
|
|
} else if (eventType === EventType.POINTERENTER) {
|
|
return EventType.POINTEROVER;
|
|
} else if (eventType === EventType.POINTERLEAVE) {
|
|
return EventType.POINTEROUT;
|
|
}
|
|
return eventType;
|
|
}
|
|
function addEventListener(element, eventType, handler, passive) {
|
|
let capture = false;
|
|
if (isCaptureEventType(eventType)) {
|
|
capture = true;
|
|
}
|
|
const options = typeof passive === 'boolean' ? {
|
|
capture,
|
|
passive
|
|
} : capture;
|
|
element.addEventListener(eventType, handler, options);
|
|
return {
|
|
eventType,
|
|
handler,
|
|
capture,
|
|
passive
|
|
};
|
|
}
|
|
function removeEventListener(element, info) {
|
|
if (element.removeEventListener) {
|
|
const options = typeof info.passive === 'boolean' ? {
|
|
capture: info.capture
|
|
} : info.capture;
|
|
element.removeEventListener(info.eventType, info.handler, options);
|
|
} else if (element.detachEvent) {
|
|
element.detachEvent(`on${info.eventType}`, info.handler);
|
|
}
|
|
}
|
|
function preventDefault(e) {
|
|
e.preventDefault ? e.preventDefault() : e.returnValue = false;
|
|
}
|
|
let isMac = typeof navigator !== 'undefined' && /Macintosh/.test(navigator.userAgent);
|
|
function isMiddleClick(e) {
|
|
return (e.which === 2 || e.which == null && e.button === 4
|
|
);
|
|
}
|
|
function isModifiedClickEvent(e) {
|
|
return (isMac && e.metaKey || !isMac && e.ctrlKey || isMiddleClick(e) || e.shiftKey
|
|
);
|
|
}
|
|
function isMouseSpecialEvent(e, type, element) {
|
|
const related = e.relatedTarget;
|
|
return (e.type === EventType.MOUSEOVER && type === EventType.MOUSEENTER || e.type === EventType.MOUSEOUT && type === EventType.MOUSELEAVE || e.type === EventType.POINTEROVER && type === EventType.POINTERENTER || e.type === EventType.POINTEROUT && type === EventType.POINTERLEAVE) && (!related || related !== element && !element.contains(related));
|
|
}
|
|
function createMouseSpecialEvent(e, target) {
|
|
const copy = {};
|
|
for (const property in e) {
|
|
if (property === 'srcElement' || property === 'target') {
|
|
continue;
|
|
}
|
|
const key = property;
|
|
const value = e[key];
|
|
if (typeof value === 'function') {
|
|
continue;
|
|
}
|
|
copy[key] = value;
|
|
}
|
|
if (e.type === EventType.MOUSEOVER) {
|
|
copy['type'] = EventType.MOUSEENTER;
|
|
} else if (e.type === EventType.MOUSEOUT) {
|
|
copy['type'] = EventType.MOUSELEAVE;
|
|
} else if (e.type === EventType.POINTEROVER) {
|
|
copy['type'] = EventType.POINTERENTER;
|
|
} else {
|
|
copy['type'] = EventType.POINTERLEAVE;
|
|
}
|
|
copy['target'] = copy['srcElement'] = target;
|
|
copy['bubbles'] = false;
|
|
copy['_originalEvent'] = e;
|
|
return copy;
|
|
}
|
|
|
|
const isIos = typeof navigator !== 'undefined' && /iPhone|iPad|iPod/.test(navigator.userAgent);
|
|
class EventContractContainer {
|
|
element;
|
|
handlerInfos = [];
|
|
constructor(element) {
|
|
this.element = element;
|
|
}
|
|
addEventListener(eventType, getHandler, passive) {
|
|
if (isIos) {
|
|
this.element.style.cursor = 'pointer';
|
|
}
|
|
this.handlerInfos.push(addEventListener(this.element, eventType, getHandler(this.element), passive));
|
|
}
|
|
cleanUp() {
|
|
for (let i = 0; i < this.handlerInfos.length; i++) {
|
|
removeEventListener(this.element, this.handlerInfos[i]);
|
|
}
|
|
this.handlerInfos = [];
|
|
}
|
|
}
|
|
|
|
const Char = {
|
|
NAMESPACE_ACTION_SEPARATOR: '.',
|
|
EVENT_ACTION_SEPARATOR: ':'
|
|
};
|
|
|
|
function getEventType(eventInfo) {
|
|
return eventInfo.eventType;
|
|
}
|
|
function setEventType(eventInfo, eventType) {
|
|
eventInfo.eventType = eventType;
|
|
}
|
|
function getEvent(eventInfo) {
|
|
return eventInfo.event;
|
|
}
|
|
function setEvent(eventInfo, event) {
|
|
eventInfo.event = event;
|
|
}
|
|
function getTargetElement(eventInfo) {
|
|
return eventInfo.targetElement;
|
|
}
|
|
function setTargetElement(eventInfo, targetElement) {
|
|
eventInfo.targetElement = targetElement;
|
|
}
|
|
function getContainer(eventInfo) {
|
|
return eventInfo.eic;
|
|
}
|
|
function setContainer(eventInfo, container) {
|
|
eventInfo.eic = container;
|
|
}
|
|
function getTimestamp(eventInfo) {
|
|
return eventInfo.timeStamp;
|
|
}
|
|
function setTimestamp(eventInfo, timestamp) {
|
|
eventInfo.timeStamp = timestamp;
|
|
}
|
|
function getAction(eventInfo) {
|
|
return eventInfo.eia;
|
|
}
|
|
function setAction(eventInfo, actionName, actionElement) {
|
|
eventInfo.eia = [actionName, actionElement];
|
|
}
|
|
function unsetAction(eventInfo) {
|
|
eventInfo.eia = undefined;
|
|
}
|
|
function getActionElement(actionInfo) {
|
|
return actionInfo[1];
|
|
}
|
|
function getIsReplay(eventInfo) {
|
|
return eventInfo.eirp;
|
|
}
|
|
function setIsReplay(eventInfo, replay) {
|
|
eventInfo.eirp = replay;
|
|
}
|
|
function getResolved(eventInfo) {
|
|
return eventInfo.eir;
|
|
}
|
|
function setResolved(eventInfo, resolved) {
|
|
eventInfo.eir = resolved;
|
|
}
|
|
function cloneEventInfo(eventInfo) {
|
|
return {
|
|
eventType: eventInfo.eventType,
|
|
event: eventInfo.event,
|
|
targetElement: eventInfo.targetElement,
|
|
eic: eventInfo.eic,
|
|
eia: eventInfo.eia,
|
|
timeStamp: eventInfo.timeStamp,
|
|
eirp: eventInfo.eirp,
|
|
eiack: eventInfo.eiack,
|
|
eir: eventInfo.eir
|
|
};
|
|
}
|
|
function createEventInfoFromParameters(eventType, event, targetElement, container, timestamp, action, isReplay, a11yClickKey) {
|
|
return {
|
|
eventType,
|
|
event,
|
|
targetElement,
|
|
eic: container,
|
|
timeStamp: timestamp,
|
|
eia: action,
|
|
eirp: isReplay,
|
|
eiack: a11yClickKey
|
|
};
|
|
}
|
|
class EventInfoWrapper {
|
|
eventInfo;
|
|
constructor(eventInfo) {
|
|
this.eventInfo = eventInfo;
|
|
}
|
|
getEventType() {
|
|
return getEventType(this.eventInfo);
|
|
}
|
|
setEventType(eventType) {
|
|
setEventType(this.eventInfo, eventType);
|
|
}
|
|
getEvent() {
|
|
return getEvent(this.eventInfo);
|
|
}
|
|
setEvent(event) {
|
|
setEvent(this.eventInfo, event);
|
|
}
|
|
getTargetElement() {
|
|
return getTargetElement(this.eventInfo);
|
|
}
|
|
setTargetElement(targetElement) {
|
|
setTargetElement(this.eventInfo, targetElement);
|
|
}
|
|
getContainer() {
|
|
return getContainer(this.eventInfo);
|
|
}
|
|
setContainer(container) {
|
|
setContainer(this.eventInfo, container);
|
|
}
|
|
getTimestamp() {
|
|
return getTimestamp(this.eventInfo);
|
|
}
|
|
setTimestamp(timestamp) {
|
|
setTimestamp(this.eventInfo, timestamp);
|
|
}
|
|
getAction() {
|
|
const action = getAction(this.eventInfo);
|
|
if (!action) return undefined;
|
|
return {
|
|
name: action[0],
|
|
element: action[1]
|
|
};
|
|
}
|
|
setAction(action) {
|
|
if (!action) {
|
|
unsetAction(this.eventInfo);
|
|
return;
|
|
}
|
|
setAction(this.eventInfo, action.name, action.element);
|
|
}
|
|
getIsReplay() {
|
|
return getIsReplay(this.eventInfo);
|
|
}
|
|
setIsReplay(replay) {
|
|
setIsReplay(this.eventInfo, replay);
|
|
}
|
|
getResolved() {
|
|
return getResolved(this.eventInfo);
|
|
}
|
|
setResolved(resolved) {
|
|
setResolved(this.eventInfo, resolved);
|
|
}
|
|
clone() {
|
|
return new EventInfoWrapper(cloneEventInfo(this.eventInfo));
|
|
}
|
|
}
|
|
|
|
const EMPTY_ACTION_MAP = {};
|
|
const REGEXP_SEMICOLON = /\s*;\s*/;
|
|
const DEFAULT_EVENT_TYPE = EventType.CLICK;
|
|
class ActionResolver {
|
|
a11yClickSupport = false;
|
|
clickModSupport = true;
|
|
syntheticMouseEventSupport;
|
|
updateEventInfoForA11yClick = undefined;
|
|
preventDefaultForA11yClick = undefined;
|
|
populateClickOnlyAction = undefined;
|
|
constructor({
|
|
syntheticMouseEventSupport = false,
|
|
clickModSupport = true
|
|
} = {}) {
|
|
this.syntheticMouseEventSupport = syntheticMouseEventSupport;
|
|
this.clickModSupport = clickModSupport;
|
|
}
|
|
resolveEventType(eventInfo) {
|
|
if (this.clickModSupport && getEventType(eventInfo) === EventType.CLICK && isModifiedClickEvent(getEvent(eventInfo))) {
|
|
setEventType(eventInfo, EventType.CLICKMOD);
|
|
} else if (this.a11yClickSupport) {
|
|
this.updateEventInfoForA11yClick(eventInfo);
|
|
}
|
|
}
|
|
resolveAction(eventInfo) {
|
|
if (getResolved(eventInfo)) {
|
|
return;
|
|
}
|
|
this.populateAction(eventInfo, getTargetElement(eventInfo));
|
|
setResolved(eventInfo, true);
|
|
}
|
|
resolveParentAction(eventInfo) {
|
|
const action = getAction(eventInfo);
|
|
const actionElement = action && getActionElement(action);
|
|
unsetAction(eventInfo);
|
|
const parentNode = actionElement && this.getParentNode(actionElement);
|
|
if (!parentNode) {
|
|
return;
|
|
}
|
|
this.populateAction(eventInfo, parentNode);
|
|
}
|
|
populateAction(eventInfo, currentTarget) {
|
|
let actionElement = currentTarget;
|
|
while (actionElement && actionElement !== getContainer(eventInfo)) {
|
|
if (actionElement.nodeType === Node.ELEMENT_NODE) {
|
|
this.populateActionOnElement(actionElement, eventInfo);
|
|
}
|
|
if (getAction(eventInfo)) {
|
|
break;
|
|
}
|
|
actionElement = this.getParentNode(actionElement);
|
|
}
|
|
const action = getAction(eventInfo);
|
|
if (!action) {
|
|
return;
|
|
}
|
|
if (this.a11yClickSupport) {
|
|
this.preventDefaultForA11yClick(eventInfo);
|
|
}
|
|
if (this.syntheticMouseEventSupport) {
|
|
if (getEventType(eventInfo) === EventType.MOUSEENTER || getEventType(eventInfo) === EventType.MOUSELEAVE || getEventType(eventInfo) === EventType.POINTERENTER || getEventType(eventInfo) === EventType.POINTERLEAVE) {
|
|
if (isMouseSpecialEvent(getEvent(eventInfo), getEventType(eventInfo), getActionElement(action))) {
|
|
const copiedEvent = createMouseSpecialEvent(getEvent(eventInfo), getActionElement(action));
|
|
setEvent(eventInfo, copiedEvent);
|
|
setTargetElement(eventInfo, getActionElement(action));
|
|
} else {
|
|
unsetAction(eventInfo);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
getParentNode(element) {
|
|
const owner = element[Property.OWNER];
|
|
if (owner) {
|
|
return owner;
|
|
}
|
|
const parentNode = element.parentNode;
|
|
if (parentNode?.nodeName === '#document-fragment') {
|
|
return parentNode?.host ?? null;
|
|
}
|
|
return parentNode;
|
|
}
|
|
populateActionOnElement(actionElement, eventInfo) {
|
|
const actionMap = this.parseActions(actionElement);
|
|
const actionName = actionMap[getEventType(eventInfo)];
|
|
if (actionName !== undefined) {
|
|
setAction(eventInfo, actionName, actionElement);
|
|
}
|
|
if (this.a11yClickSupport) {
|
|
this.populateClickOnlyAction(actionElement, eventInfo, actionMap);
|
|
}
|
|
}
|
|
parseActions(actionElement) {
|
|
let actionMap = get(actionElement);
|
|
if (!actionMap) {
|
|
const jsactionAttribute = actionElement.getAttribute(Attribute.JSACTION);
|
|
if (!jsactionAttribute) {
|
|
actionMap = EMPTY_ACTION_MAP;
|
|
set(actionElement, actionMap);
|
|
} else {
|
|
actionMap = getParsed(jsactionAttribute);
|
|
if (!actionMap) {
|
|
actionMap = {};
|
|
const values = jsactionAttribute.split(REGEXP_SEMICOLON);
|
|
for (let idx = 0; idx < values.length; idx++) {
|
|
const value = values[idx];
|
|
if (!value) {
|
|
continue;
|
|
}
|
|
const colon = value.indexOf(Char.EVENT_ACTION_SEPARATOR);
|
|
const hasColon = colon !== -1;
|
|
const type = hasColon ? value.substr(0, colon).trim() : DEFAULT_EVENT_TYPE;
|
|
const action = hasColon ? value.substr(colon + 1).trim() : value;
|
|
actionMap[type] = action;
|
|
}
|
|
setParsed(jsactionAttribute, actionMap);
|
|
}
|
|
set(actionElement, actionMap);
|
|
}
|
|
}
|
|
return actionMap;
|
|
}
|
|
addA11yClickSupport(updateEventInfoForA11yClick, preventDefaultForA11yClick, populateClickOnlyAction) {
|
|
this.a11yClickSupport = true;
|
|
this.updateEventInfoForA11yClick = updateEventInfoForA11yClick;
|
|
this.preventDefaultForA11yClick = preventDefaultForA11yClick;
|
|
this.populateClickOnlyAction = populateClickOnlyAction;
|
|
}
|
|
}
|
|
|
|
var Restriction;
|
|
(function (Restriction) {
|
|
Restriction[Restriction["I_AM_THE_JSACTION_FRAMEWORK"] = 0] = "I_AM_THE_JSACTION_FRAMEWORK";
|
|
})(Restriction || (Restriction = {}));
|
|
|
|
class Dispatcher {
|
|
dispatchDelegate;
|
|
actionResolver;
|
|
eventReplayer;
|
|
eventReplayScheduled = false;
|
|
replayEventInfoWrappers = [];
|
|
constructor(dispatchDelegate, {
|
|
actionResolver,
|
|
eventReplayer
|
|
} = {}) {
|
|
this.dispatchDelegate = dispatchDelegate;
|
|
this.actionResolver = actionResolver;
|
|
this.eventReplayer = eventReplayer;
|
|
}
|
|
dispatch(eventInfo) {
|
|
const eventInfoWrapper = new EventInfoWrapper(eventInfo);
|
|
this.actionResolver?.resolveEventType(eventInfo);
|
|
this.actionResolver?.resolveAction(eventInfo);
|
|
const action = eventInfoWrapper.getAction();
|
|
if (action && shouldPreventDefaultBeforeDispatching(action.element, eventInfoWrapper)) {
|
|
preventDefault(eventInfoWrapper.getEvent());
|
|
}
|
|
if (this.eventReplayer && eventInfoWrapper.getIsReplay()) {
|
|
this.scheduleEventInfoWrapperReplay(eventInfoWrapper);
|
|
return;
|
|
}
|
|
this.dispatchDelegate(eventInfoWrapper);
|
|
}
|
|
scheduleEventInfoWrapperReplay(eventInfoWrapper) {
|
|
this.replayEventInfoWrappers.push(eventInfoWrapper);
|
|
if (this.eventReplayScheduled) {
|
|
return;
|
|
}
|
|
this.eventReplayScheduled = true;
|
|
Promise.resolve().then(() => {
|
|
this.eventReplayScheduled = false;
|
|
this.eventReplayer(this.replayEventInfoWrappers);
|
|
});
|
|
}
|
|
}
|
|
function shouldPreventDefaultBeforeDispatching(actionElement, eventInfoWrapper) {
|
|
return actionElement.tagName === 'A' && (eventInfoWrapper.getEventType() === EventType.CLICK || eventInfoWrapper.getEventType() === EventType.CLICKMOD);
|
|
}
|
|
|
|
const PROPAGATION_STOPPED_SYMBOL = /* @__PURE__ */Symbol.for('propagationStopped');
|
|
const EventPhase = {
|
|
REPLAY: 101
|
|
};
|
|
const PREVENT_DEFAULT_ERROR_MESSAGE_DETAILS = ' Because event replay occurs after browser dispatch, `preventDefault` would have no ' + 'effect. You can check whether an event is being replayed by accessing the event phase: ' + '`event.eventPhase === EventPhase.REPLAY`.';
|
|
const PREVENT_DEFAULT_ERROR_MESSAGE = `\`preventDefault\` called during event replay.`;
|
|
const COMPOSED_PATH_ERROR_MESSAGE_DETAILS = ' Because event replay occurs after browser ' + 'dispatch, `composedPath()` will be empty. Iterate parent nodes from `event.target` or ' + '`event.currentTarget` if you need to check elements in the event path.';
|
|
const COMPOSED_PATH_ERROR_MESSAGE = `\`composedPath\` called during event replay.`;
|
|
class EventDispatcher {
|
|
dispatchDelegate;
|
|
clickModSupport;
|
|
actionResolver;
|
|
dispatcher;
|
|
constructor(dispatchDelegate, clickModSupport = true) {
|
|
this.dispatchDelegate = dispatchDelegate;
|
|
this.clickModSupport = clickModSupport;
|
|
this.actionResolver = new ActionResolver({
|
|
clickModSupport
|
|
});
|
|
this.dispatcher = new Dispatcher(eventInfoWrapper => {
|
|
this.dispatchToDelegate(eventInfoWrapper);
|
|
}, {
|
|
actionResolver: this.actionResolver
|
|
});
|
|
}
|
|
dispatch(eventInfo) {
|
|
this.dispatcher.dispatch(eventInfo);
|
|
}
|
|
dispatchToDelegate(eventInfoWrapper) {
|
|
if (eventInfoWrapper.getIsReplay()) {
|
|
prepareEventForReplay(eventInfoWrapper);
|
|
}
|
|
prepareEventForBubbling(eventInfoWrapper);
|
|
while (eventInfoWrapper.getAction()) {
|
|
prepareEventForDispatch(eventInfoWrapper);
|
|
if (isCaptureEventType(eventInfoWrapper.getEventType()) && eventInfoWrapper.getAction().element !== eventInfoWrapper.getTargetElement()) {
|
|
return;
|
|
}
|
|
this.dispatchDelegate(eventInfoWrapper.getEvent(), eventInfoWrapper.getAction().name);
|
|
if (propagationStopped(eventInfoWrapper)) {
|
|
return;
|
|
}
|
|
this.actionResolver.resolveParentAction(eventInfoWrapper.eventInfo);
|
|
}
|
|
}
|
|
}
|
|
function prepareEventForBubbling(eventInfoWrapper) {
|
|
const event = eventInfoWrapper.getEvent();
|
|
const originalStopPropagation = eventInfoWrapper.getEvent().stopPropagation.bind(event);
|
|
const stopPropagation = () => {
|
|
event[PROPAGATION_STOPPED_SYMBOL] = true;
|
|
originalStopPropagation();
|
|
};
|
|
patchEventInstance(event, 'stopPropagation', stopPropagation);
|
|
patchEventInstance(event, 'stopImmediatePropagation', stopPropagation);
|
|
}
|
|
function propagationStopped(eventInfoWrapper) {
|
|
const event = eventInfoWrapper.getEvent();
|
|
return !!event[PROPAGATION_STOPPED_SYMBOL];
|
|
}
|
|
function prepareEventForReplay(eventInfoWrapper) {
|
|
const event = eventInfoWrapper.getEvent();
|
|
const target = eventInfoWrapper.getTargetElement();
|
|
const originalPreventDefault = event.preventDefault.bind(event);
|
|
patchEventInstance(event, 'target', target);
|
|
patchEventInstance(event, 'eventPhase', EventPhase.REPLAY);
|
|
patchEventInstance(event, 'preventDefault', () => {
|
|
originalPreventDefault();
|
|
throw new Error(PREVENT_DEFAULT_ERROR_MESSAGE + (ngDevMode ? PREVENT_DEFAULT_ERROR_MESSAGE_DETAILS : ''));
|
|
});
|
|
patchEventInstance(event, 'composedPath', () => {
|
|
throw new Error(COMPOSED_PATH_ERROR_MESSAGE + (ngDevMode ? COMPOSED_PATH_ERROR_MESSAGE_DETAILS : ''));
|
|
});
|
|
}
|
|
function prepareEventForDispatch(eventInfoWrapper) {
|
|
const event = eventInfoWrapper.getEvent();
|
|
const currentTarget = eventInfoWrapper.getAction()?.element;
|
|
if (currentTarget) {
|
|
patchEventInstance(event, 'currentTarget', currentTarget, {
|
|
configurable: true
|
|
});
|
|
}
|
|
}
|
|
function patchEventInstance(event, property, value, {
|
|
configurable = false
|
|
} = {}) {
|
|
Object.defineProperty(event, property, {
|
|
value,
|
|
configurable
|
|
});
|
|
}
|
|
function registerDispatcher$1(eventContract, dispatcher) {
|
|
eventContract.ecrd(eventInfo => {
|
|
dispatcher.dispatch(eventInfo);
|
|
}, Restriction.I_AM_THE_JSACTION_FRAMEWORK);
|
|
}
|
|
|
|
function createEarlyJsactionData(container) {
|
|
const q = [];
|
|
const d = eventInfo => {
|
|
q.push(eventInfo);
|
|
};
|
|
const h = event => {
|
|
d(createEventInfoFromParameters(event.type, event, event.target, container, Date.now()));
|
|
};
|
|
return {
|
|
c: container,
|
|
q,
|
|
et: [],
|
|
etc: [],
|
|
d,
|
|
h
|
|
};
|
|
}
|
|
function addEvents(earlyJsactionData, types, capture) {
|
|
for (let i = 0; i < types.length; i++) {
|
|
const eventType = types[i];
|
|
const eventTypes = capture ? earlyJsactionData.etc : earlyJsactionData.et;
|
|
eventTypes.push(eventType);
|
|
earlyJsactionData.c.addEventListener(eventType, earlyJsactionData.h, capture);
|
|
}
|
|
}
|
|
function getQueuedEventInfos(earlyJsactionData) {
|
|
return earlyJsactionData?.q ?? [];
|
|
}
|
|
function registerDispatcher(earlyJsactionData, dispatcher) {
|
|
if (!earlyJsactionData) {
|
|
return;
|
|
}
|
|
earlyJsactionData.d = dispatcher;
|
|
}
|
|
function removeAllEventListeners(earlyJsactionData) {
|
|
if (!earlyJsactionData) {
|
|
return;
|
|
}
|
|
removeEventListeners(earlyJsactionData.c, earlyJsactionData.et, earlyJsactionData.h);
|
|
removeEventListeners(earlyJsactionData.c, earlyJsactionData.etc, earlyJsactionData.h, true);
|
|
}
|
|
function removeEventListeners(container, eventTypes, earlyEventHandler, capture) {
|
|
for (let i = 0; i < eventTypes.length; i++) {
|
|
container.removeEventListener(eventTypes[i], earlyEventHandler, capture);
|
|
}
|
|
}
|
|
|
|
const MOUSE_SPECIAL_SUPPORT = false;
|
|
|
|
class EventContract {
|
|
static MOUSE_SPECIAL_SUPPORT = MOUSE_SPECIAL_SUPPORT;
|
|
containerManager;
|
|
eventHandlers = {};
|
|
browserEventTypeToExtraEventTypes = {};
|
|
dispatcher = null;
|
|
queuedEventInfos = [];
|
|
constructor(containerManager) {
|
|
this.containerManager = containerManager;
|
|
}
|
|
handleEvent(eventType, event, container) {
|
|
const eventInfo = createEventInfoFromParameters(eventType, event, event.target, container, Date.now());
|
|
this.handleEventInfo(eventInfo);
|
|
}
|
|
handleEventInfo(eventInfo) {
|
|
if (!this.dispatcher) {
|
|
setIsReplay(eventInfo, true);
|
|
this.queuedEventInfos?.push(eventInfo);
|
|
return;
|
|
}
|
|
this.dispatcher(eventInfo);
|
|
}
|
|
addEvent(eventType, prefixedEventType, passive) {
|
|
if (eventType in this.eventHandlers || !this.containerManager) {
|
|
return;
|
|
}
|
|
if (!EventContract.MOUSE_SPECIAL_SUPPORT && MOUSE_SPECIAL_EVENT_TYPES.indexOf(eventType) >= 0) {
|
|
return;
|
|
}
|
|
const eventHandler = (eventType, event, container) => {
|
|
this.handleEvent(eventType, event, container);
|
|
};
|
|
this.eventHandlers[eventType] = eventHandler;
|
|
const browserEventType = getBrowserEventType(prefixedEventType || eventType);
|
|
if (browserEventType !== eventType) {
|
|
const eventTypes = this.browserEventTypeToExtraEventTypes[browserEventType] || [];
|
|
eventTypes.push(eventType);
|
|
this.browserEventTypeToExtraEventTypes[browserEventType] = eventTypes;
|
|
}
|
|
this.containerManager.addEventListener(browserEventType, element => {
|
|
return event => {
|
|
eventHandler(eventType, event, element);
|
|
};
|
|
}, passive);
|
|
}
|
|
replayEarlyEvents(earlyJsactionData = window._ejsa) {
|
|
if (!earlyJsactionData) {
|
|
return;
|
|
}
|
|
this.replayEarlyEventInfos(earlyJsactionData.q);
|
|
removeAllEventListeners(earlyJsactionData);
|
|
delete window._ejsa;
|
|
}
|
|
replayEarlyEventInfos(earlyEventInfos) {
|
|
for (let i = 0; i < earlyEventInfos.length; i++) {
|
|
const earlyEventInfo = earlyEventInfos[i];
|
|
const eventTypes = this.getEventTypesForBrowserEventType(earlyEventInfo.eventType);
|
|
for (let j = 0; j < eventTypes.length; j++) {
|
|
const eventInfo = cloneEventInfo(earlyEventInfo);
|
|
setEventType(eventInfo, eventTypes[j]);
|
|
this.handleEventInfo(eventInfo);
|
|
}
|
|
}
|
|
}
|
|
getEventTypesForBrowserEventType(browserEventType) {
|
|
const eventTypes = [];
|
|
if (this.eventHandlers[browserEventType]) {
|
|
eventTypes.push(browserEventType);
|
|
}
|
|
if (this.browserEventTypeToExtraEventTypes[browserEventType]) {
|
|
eventTypes.push(...this.browserEventTypeToExtraEventTypes[browserEventType]);
|
|
}
|
|
return eventTypes;
|
|
}
|
|
handler(eventType) {
|
|
return this.eventHandlers[eventType];
|
|
}
|
|
cleanUp() {
|
|
this.containerManager?.cleanUp();
|
|
this.containerManager = null;
|
|
this.eventHandlers = {};
|
|
this.browserEventTypeToExtraEventTypes = {};
|
|
this.dispatcher = null;
|
|
this.queuedEventInfos = [];
|
|
}
|
|
registerDispatcher(dispatcher, restriction) {
|
|
this.ecrd(dispatcher, restriction);
|
|
}
|
|
ecrd(dispatcher, restriction) {
|
|
this.dispatcher = dispatcher;
|
|
if (this.queuedEventInfos?.length) {
|
|
for (let i = 0; i < this.queuedEventInfos.length; i++) {
|
|
this.handleEventInfo(this.queuedEventInfos[i]);
|
|
}
|
|
this.queuedEventInfos = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
function bootstrapAppScopedEarlyEventContract(container, appId, bubbleEventTypes, captureEventTypes, dataContainer = window) {
|
|
const earlyJsactionData = createEarlyJsactionData(container);
|
|
if (!dataContainer._ejsas) {
|
|
dataContainer._ejsas = {};
|
|
}
|
|
dataContainer._ejsas[appId] = earlyJsactionData;
|
|
addEvents(earlyJsactionData, bubbleEventTypes);
|
|
addEvents(earlyJsactionData, captureEventTypes, true);
|
|
}
|
|
function getAppScopedQueuedEventInfos(appId, dataContainer = window) {
|
|
return getQueuedEventInfos(dataContainer._ejsas?.[appId]);
|
|
}
|
|
function registerAppScopedDispatcher(restriction, appId, dispatcher, dataContainer = window) {
|
|
registerDispatcher(dataContainer._ejsas?.[appId], dispatcher);
|
|
}
|
|
function removeAllAppScopedEventListeners(appId, dataContainer = window) {
|
|
removeAllEventListeners(dataContainer._ejsas?.[appId]);
|
|
}
|
|
function clearAppScopedEarlyEventContract(appId, dataContainer = window) {
|
|
if (!dataContainer._ejsas) {
|
|
return;
|
|
}
|
|
dataContainer._ejsas[appId] = undefined;
|
|
}
|
|
|
|
export { Attribute, EventContract, EventContractContainer, EventDispatcher, EventInfoWrapper, EventPhase, bootstrapAppScopedEarlyEventContract, clearAppScopedEarlyEventContract, getDefaulted as getActionCache, getAppScopedQueuedEventInfos, isCaptureEventType, isEarlyEventType, registerAppScopedDispatcher, registerDispatcher$1 as registerDispatcher, removeAllAppScopedEventListeners };
|
|
//# sourceMappingURL=primitives-event-dispatch.mjs.map
|
|
|