planning
All checks were successful
Publish To Prod / deploy_and_publish (push) Successful in 35s

This commit is contained in:
2024-10-14 09:15:30 +02:00
parent bcba00a730
commit 6e64e138e2
21059 changed files with 2317811 additions and 1 deletions

View File

@@ -0,0 +1,94 @@
import eventOptionsKey from './eventOptionsKey';
function ensureCanMutateNextEventHandlers(eventHandlers) {
if (eventHandlers.handlers === eventHandlers.nextHandlers) {
// eslint-disable-next-line no-param-reassign
eventHandlers.nextHandlers = eventHandlers.handlers.slice();
}
}
export default function TargetEventHandlers(target) {
this.target = target;
this.events = {};
}
TargetEventHandlers.prototype.getEventHandlers = function getEventHandlers(eventName, options) {
const key = `${eventName} ${eventOptionsKey(options)}`;
if (!this.events[key]) {
this.events[key] = {
handlers: [],
handleEvent: undefined,
};
this.events[key].nextHandlers = this.events[key].handlers;
}
return this.events[key];
};
TargetEventHandlers.prototype.handleEvent = function handleEvent(eventName, options, event) {
const eventHandlers = this.getEventHandlers(eventName, options);
eventHandlers.handlers = eventHandlers.nextHandlers;
eventHandlers.handlers.forEach((handler) => {
if (handler) {
// We need to check for presence here because a handler function may
// cause later handlers to get removed. This can happen if you for
// instance have a waypoint that unmounts another waypoint as part of an
// onEnter/onLeave handler.
handler(event);
}
});
};
TargetEventHandlers.prototype.add = function add(eventName, listener, options) {
// options has already been normalized at this point.
const eventHandlers = this.getEventHandlers(eventName, options);
ensureCanMutateNextEventHandlers(eventHandlers);
if (eventHandlers.nextHandlers.length === 0) {
eventHandlers.handleEvent = this.handleEvent.bind(this, eventName, options);
this.target.addEventListener(
eventName,
eventHandlers.handleEvent,
options,
);
}
eventHandlers.nextHandlers.push(listener);
let isSubscribed = true;
const unsubscribe = () => {
if (!isSubscribed) {
return;
}
isSubscribed = false;
ensureCanMutateNextEventHandlers(eventHandlers);
const index = eventHandlers.nextHandlers.indexOf(listener);
eventHandlers.nextHandlers.splice(index, 1);
if (eventHandlers.nextHandlers.length === 0) {
// All event handlers have been removed, so we want to remove the event
// listener from the target node.
if (this.target) {
// There can be a race condition where the target may no longer exist
// when this function is called, e.g. when a React component is
// unmounting. Guarding against this prevents the following error:
//
// Cannot read property 'removeEventListener' of undefined
this.target.removeEventListener(
eventName,
eventHandlers.handleEvent,
options,
);
}
eventHandlers.handleEvent = undefined;
}
};
return unsubscribe;
};

6
node_modules/consolidated-events/src/canUseDOM.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
const CAN_USE_DOM = !!(
(typeof window !== 'undefined' &&
window.document && window.document.createElement)
);
export default CAN_USE_DOM;

View File

@@ -0,0 +1,39 @@
import canUseDOM from './canUseDOM';
// Adapted from Modernizr
// https://github.com/Modernizr/Modernizr/blob/acb3f0d9/feature-detects/dom/passiveeventlisteners.js#L26-L37
function testPassiveEventListeners() {
if (!canUseDOM) {
return false;
}
if (!window.addEventListener || !window.removeEventListener || !Object.defineProperty) {
return false;
}
let supportsPassiveOption = false;
try {
const opts = Object.defineProperty({}, 'passive', {
// eslint-disable-next-line getter-return
get() {
supportsPassiveOption = true;
},
});
const noop = () => {};
window.addEventListener('testPassiveEventSupport', noop, opts);
window.removeEventListener('testPassiveEventSupport', noop, opts);
} catch (e) {
// do nothing
}
return supportsPassiveOption;
}
let memoized;
export default function canUsePassiveEventListeners() {
if (memoized === undefined) {
memoized = testPassiveEventListeners();
}
return memoized;
}

View File

@@ -0,0 +1,30 @@
/* eslint-disable no-bitwise */
/**
* Generate a unique key for any set of event options
*/
export default function eventOptionsKey(normalizedEventOptions) {
if (!normalizedEventOptions) {
return 0;
}
// If the browser does not support passive event listeners, the normalized
// event options will be a boolean.
if (normalizedEventOptions === true) {
return 100;
}
// At this point, the browser supports passive event listeners, so we expect
// the event options to be an object with possible properties of capture,
// passive, and once.
//
// We want to consistently return the same value, regardless of the order of
// these properties, so let's use binary maths to assign each property to a
// bit, and then add those together (with an offset to account for the
// booleans at the beginning of this function).
const capture = normalizedEventOptions.capture << 0;
const passive = normalizedEventOptions.passive << 1;
const once = normalizedEventOptions.once << 2;
return capture + passive + once;
}

14
node_modules/consolidated-events/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
import normalizeEventOptions from './normalizeEventOptions';
import TargetEventHandlers from './TargetEventHandlers';
const EVENT_HANDLERS_KEY = '__consolidated_events_handlers__';
// eslint-disable-next-line import/prefer-default-export
export function addEventListener(target, eventName, listener, options) {
if (!target[EVENT_HANDLERS_KEY]) {
// eslint-disable-next-line no-param-reassign
target[EVENT_HANDLERS_KEY] = new TargetEventHandlers(target);
}
const normalizedEventOptions = normalizeEventOptions(options);
return target[EVENT_HANDLERS_KEY].add(eventName, listener, normalizedEventOptions);
}

View File

@@ -0,0 +1,17 @@
import canUsePassiveEventListeners from './canUsePassiveEventListeners';
export default function normalizeEventOptions(eventOptions) {
if (!eventOptions) {
return undefined;
}
if (!canUsePassiveEventListeners()) {
// If the browser does not support the passive option, then it is expecting
// a boolean for the options argument to specify whether it should use
// capture or not. In more modern browsers, this is passed via the `capture`
// option, so let's just hoist that value up.
return !!eventOptions.capture;
}
return eventOptions;
}