2016-03-25 06:40:52 +08:00
|
|
|
/**
|
2018-09-08 06:11:23 +08:00
|
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
2016-03-25 06:40:52 +08:00
|
|
|
*
|
2017-09-25 04:48:13 +08:00
|
|
|
* This source code is licensed under the MIT license found in the
|
|
|
|
|
* LICENSE file in the root directory of this source tree.
|
2016-03-25 06:40:52 +08:00
|
|
|
*
|
|
|
|
|
* @flow
|
|
|
|
|
*/
|
|
|
|
|
|
2019-08-14 22:32:42 +08:00
|
|
|
import type {AnyNativeEvent} from 'legacy-events/PluginModuleType';
|
2019-09-24 02:21:10 +08:00
|
|
|
import type {EventSystemFlags} from 'legacy-events/EventSystemFlags';
|
2020-03-13 05:48:29 +08:00
|
|
|
import {accumulateDirectDispatches} from 'legacy-events/EventPropagators';
|
2019-08-14 22:32:42 +08:00
|
|
|
import type {TopLevelType} from 'legacy-events/TopLevelEventTypes';
|
|
|
|
|
import SyntheticEvent from 'legacy-events/SyntheticEvent';
|
2019-05-23 15:23:54 +08:00
|
|
|
import invariant from 'shared/invariant';
|
|
|
|
|
|
|
|
|
|
// Module provided by RN:
|
|
|
|
|
import {ReactNativeViewConfigRegistry} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface';
|
2020-03-13 05:48:29 +08:00
|
|
|
import accumulateInto from 'legacy-events/accumulateInto';
|
|
|
|
|
import getListener from 'legacy-events/getListener';
|
2020-03-22 06:22:01 +08:00
|
|
|
import {traverseTwoPhase} from 'react-reconciler/src/ReactTreeTraversal';
|
2020-03-13 05:48:29 +08:00
|
|
|
import forEachAccumulated from 'legacy-events/forEachAccumulated';
|
2019-05-23 15:23:54 +08:00
|
|
|
|
|
|
|
|
const {
|
2018-04-10 10:42:23 +08:00
|
|
|
customBubblingEventTypes,
|
|
|
|
|
customDirectEventTypes,
|
2019-05-23 15:23:54 +08:00
|
|
|
} = ReactNativeViewConfigRegistry;
|
2016-03-25 06:40:52 +08:00
|
|
|
|
2020-03-13 05:48:29 +08:00
|
|
|
// Start of inline: the below functions were inlined from
|
|
|
|
|
// EventPropagator.js, as they deviated from ReactDOM's newer
|
|
|
|
|
// implementations.
|
|
|
|
|
function listenerAtPhase(inst, event, propagationPhase: PropagationPhases) {
|
|
|
|
|
const registrationName =
|
|
|
|
|
event.dispatchConfig.phasedRegistrationNames[propagationPhase];
|
|
|
|
|
return getListener(inst, registrationName);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function accumulateDirectionalDispatches(inst, phase, event) {
|
|
|
|
|
if (__DEV__) {
|
|
|
|
|
if (!inst) {
|
|
|
|
|
console.error('Dispatching inst must not be null');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
const listener = listenerAtPhase(inst, event, phase);
|
|
|
|
|
if (listener) {
|
|
|
|
|
event._dispatchListeners = accumulateInto(
|
|
|
|
|
event._dispatchListeners,
|
|
|
|
|
listener,
|
|
|
|
|
);
|
|
|
|
|
event._dispatchInstances = accumulateInto(event._dispatchInstances, inst);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function accumulateTwoPhaseDispatchesSingle(event) {
|
|
|
|
|
if (event && event.dispatchConfig.phasedRegistrationNames) {
|
|
|
|
|
traverseTwoPhase(event._targetInst, accumulateDirectionalDispatches, event);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function accumulateTwoPhaseDispatches(events) {
|
|
|
|
|
forEachAccumulated(events, accumulateTwoPhaseDispatchesSingle);
|
|
|
|
|
}
|
|
|
|
|
// End of inline
|
|
|
|
|
type PropagationPhases = 'bubbled' | 'captured';
|
|
|
|
|
|
2017-09-15 05:55:32 +08:00
|
|
|
const ReactNativeBridgeEventPlugin = {
|
2019-06-05 20:21:13 +08:00
|
|
|
eventTypes: {},
|
2016-03-25 06:40:52 +08:00
|
|
|
|
|
|
|
|
extractEvents: function(
|
2018-05-15 17:38:50 +08:00
|
|
|
topLevelType: TopLevelType,
|
2018-06-30 03:51:48 +08:00
|
|
|
targetInst: null | Object,
|
2017-11-15 09:48:40 +08:00
|
|
|
nativeEvent: AnyNativeEvent,
|
2019-11-12 03:22:41 +08:00
|
|
|
nativeEventTarget: null | Object,
|
2019-10-03 01:31:15 +08:00
|
|
|
eventSystemFlags: EventSystemFlags,
|
2016-03-25 06:40:52 +08:00
|
|
|
): ?Object {
|
2018-02-22 05:47:17 +08:00
|
|
|
if (targetInst == null) {
|
|
|
|
|
// Probably a node belonging to another renderer's tree.
|
|
|
|
|
return null;
|
|
|
|
|
}
|
2017-09-15 05:55:32 +08:00
|
|
|
const bubbleDispatchConfig = customBubblingEventTypes[topLevelType];
|
|
|
|
|
const directDispatchConfig = customDirectEventTypes[topLevelType];
|
2017-09-07 06:34:02 +08:00
|
|
|
invariant(
|
|
|
|
|
bubbleDispatchConfig || directDispatchConfig,
|
|
|
|
|
'Unsupported top level event type "%s" dispatched',
|
|
|
|
|
topLevelType,
|
|
|
|
|
);
|
2017-09-15 05:55:32 +08:00
|
|
|
const event = SyntheticEvent.getPooled(
|
2016-03-25 06:40:52 +08:00
|
|
|
bubbleDispatchConfig || directDispatchConfig,
|
2016-03-31 05:35:46 +08:00
|
|
|
targetInst,
|
|
|
|
|
nativeEvent,
|
2017-03-14 08:05:18 +08:00
|
|
|
nativeEventTarget,
|
2016-03-25 06:40:52 +08:00
|
|
|
);
|
|
|
|
|
if (bubbleDispatchConfig) {
|
2017-11-05 19:58:36 +08:00
|
|
|
accumulateTwoPhaseDispatches(event);
|
2016-03-25 06:40:52 +08:00
|
|
|
} else if (directDispatchConfig) {
|
2017-11-05 19:58:36 +08:00
|
|
|
accumulateDirectDispatches(event);
|
2016-03-25 06:40:52 +08:00
|
|
|
} else {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
return event;
|
2016-04-19 07:11:31 +08:00
|
|
|
},
|
2016-03-25 06:40:52 +08:00
|
|
|
};
|
|
|
|
|
|
2017-11-03 03:50:03 +08:00
|
|
|
export default ReactNativeBridgeEventPlugin;
|