import isArray from 'shared/isArray';
import {runWithFiberInDEV} from 'react-reconciler/src/ReactCurrentFiber';
let hasError = false;
let caughtError = null;
export let getFiberCurrentPropsFromNode = null;
export let getInstanceFromNode = null;
export let getNodeFromInstance = null;
export function setComponentTree(
getFiberCurrentPropsFromNodeImpl,
getInstanceFromNodeImpl,
getNodeFromInstanceImpl,
) {
getFiberCurrentPropsFromNode = getFiberCurrentPropsFromNodeImpl;
getInstanceFromNode = getInstanceFromNodeImpl;
getNodeFromInstance = getNodeFromInstanceImpl;
if (__DEV__) {
if (!getNodeFromInstance || !getInstanceFromNode) {
console.error(
'Injected ' +
'module is missing getNodeFromInstance or getInstanceFromNode.',
);
}
}
}
function validateEventDispatches(event) {
if (__DEV__) {
const dispatchListeners = event._dispatchListeners;
const dispatchInstances = event._dispatchInstances;
const listenersIsArr = isArray(dispatchListeners);
const listenersLen = listenersIsArr
? dispatchListeners.length
: dispatchListeners
? 1
: 0;
const instancesIsArr = isArray(dispatchInstances);
const instancesLen = instancesIsArr
? dispatchInstances.length
: dispatchInstances
? 1
: 0;
if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
console.error('EventPluginUtils: Invalid `event`.');
}
}
}
export function executeDispatch(event, listener, inst) {
event.currentTarget = getNodeFromInstance(inst);
try {
listener(event);
} catch (error) {
if (!hasError) {
hasError = true;
caughtError = error;
} else {
}
}
event.currentTarget = null;
}
export function executeDispatchesInOrder(event) {
const dispatchListeners = event._dispatchListeners;
const dispatchInstances = event._dispatchInstances;
if (__DEV__) {
validateEventDispatches(event);
}
if (isArray(dispatchListeners)) {
for (let i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
}
const listener = dispatchListeners[i];
const instance = dispatchInstances[i];
if (__DEV__ && instance !== null) {
runWithFiberInDEV(instance, executeDispatch, event, listener, instance);
} else {
executeDispatch(event, listener, instance);
}
}
} else if (dispatchListeners) {
const listener = dispatchListeners;
const instance = dispatchInstances;
if (__DEV__ && instance !== null) {
runWithFiberInDEV(instance, executeDispatch, event, listener, instance);
} else {
executeDispatch(event, listener, instance);
}
}
event._dispatchListeners = null;
event._dispatchInstances = null;
}
function executeDispatchesInOrderStopAtTrueImpl(event) {
const dispatchListeners = event._dispatchListeners;
const dispatchInstances = event._dispatchInstances;
if (__DEV__) {
validateEventDispatches(event);
}
if (isArray(dispatchListeners)) {
for (let i = 0; i < dispatchListeners.length; i++) {
if (event.isPropagationStopped()) {
break;
}
if (dispatchListeners[i](event, dispatchInstances[i])) {
return dispatchInstances[i];
}
}
} else if (dispatchListeners) {
if (dispatchListeners(event, dispatchInstances)) {
return dispatchInstances;
}
}
return null;
}
export function executeDispatchesInOrderStopAtTrue(event) {
const ret = executeDispatchesInOrderStopAtTrueImpl(event);
event._dispatchInstances = null;
event._dispatchListeners = null;
return ret;
}
export function executeDirectDispatch(event) {
if (__DEV__) {
validateEventDispatches(event);
}
const dispatchListener = event._dispatchListeners;
const dispatchInstance = event._dispatchInstances;
if (isArray(dispatchListener)) {
throw new Error('Invalid `event`.');
}
event.currentTarget = dispatchListener
? getNodeFromInstance(dispatchInstance)
: null;
const res = dispatchListener ? dispatchListener(event) : null;
event.currentTarget = null;
event._dispatchListeners = null;
event._dispatchInstances = null;
return res;
}
export function hasDispatches(event) {
return !!event._dispatchListeners;
}
export function rethrowCaughtError() {
if (hasError) {
const error = caughtError;
hasError = false;
caughtError = null;
throw error;
}
}