mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-06-06 06:49:09 +08:00
Summary: This PR removes the need for having the `providesModule` tags in all the modules in the repository. It configures Flow, Jest and Metro to get the module names from the filenames (`Libraries/Animated/src/nodes/AnimatedInterpolation.js` => `AnimatedInterpolation`) * Checked the Flow configuration by running flow on the project root (no errors): ``` yarn flow ``` * Checked the Jest configuration by running the tests with a clean cache: ``` yarn jest --clearCache && yarn test ``` * Checked the Metro configuration by starting the server with a clean cache and requesting some bundles: ``` yarn run start --reset-cache curl 'localhost:8081/IntegrationTests/AccessibilityManagerTest.bundle?platform=android' curl 'localhost:8081/Libraries/Alert/Alert.bundle?platform=ios' ``` [INTERNAL] [FEATURE] [All] - Removed providesModule from all modules and configured tools. Closes https://github.com/facebook/react-native/pull/18995 Reviewed By: mjesun Differential Revision: D7729509 Pulled By: rubennorte fbshipit-source-id: 892f760a05ce1fddb088ff0cd2e97e521fb8e825
194 lines
5.1 KiB
JavaScript
194 lines
5.1 KiB
JavaScript
/**
|
|
* Copyright (c) 2015-present, Facebook, Inc.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*
|
|
* @flow
|
|
* @format
|
|
*/
|
|
'use strict';
|
|
|
|
const AnimatedValue = require('./nodes/AnimatedValue');
|
|
const NativeAnimatedHelper = require('./NativeAnimatedHelper');
|
|
const ReactNative = require('ReactNative');
|
|
|
|
const invariant = require('fbjs/lib/invariant');
|
|
const {shouldUseNativeDriver} = require('./NativeAnimatedHelper');
|
|
|
|
export type Mapping = {[key: string]: Mapping} | AnimatedValue;
|
|
export type EventConfig = {
|
|
listener?: ?Function,
|
|
useNativeDriver?: boolean,
|
|
};
|
|
|
|
function attachNativeEvent(
|
|
viewRef: any,
|
|
eventName: string,
|
|
argMapping: Array<?Mapping>,
|
|
) {
|
|
// Find animated values in `argMapping` and create an array representing their
|
|
// key path inside the `nativeEvent` object. Ex.: ['contentOffset', 'x'].
|
|
const eventMappings = [];
|
|
|
|
const traverse = (value, path) => {
|
|
if (value instanceof AnimatedValue) {
|
|
value.__makeNative();
|
|
|
|
eventMappings.push({
|
|
nativeEventPath: path,
|
|
animatedValueTag: value.__getNativeTag(),
|
|
});
|
|
} else if (typeof value === 'object') {
|
|
for (const key in value) {
|
|
traverse(value[key], path.concat(key));
|
|
}
|
|
}
|
|
};
|
|
|
|
invariant(
|
|
argMapping[0] && argMapping[0].nativeEvent,
|
|
'Native driven events only support animated values contained inside `nativeEvent`.',
|
|
);
|
|
|
|
// Assume that the event containing `nativeEvent` is always the first argument.
|
|
traverse(argMapping[0].nativeEvent, []);
|
|
|
|
const viewTag = ReactNative.findNodeHandle(viewRef);
|
|
|
|
eventMappings.forEach(mapping => {
|
|
NativeAnimatedHelper.API.addAnimatedEventToView(
|
|
viewTag,
|
|
eventName,
|
|
mapping,
|
|
);
|
|
});
|
|
|
|
return {
|
|
detach() {
|
|
eventMappings.forEach(mapping => {
|
|
NativeAnimatedHelper.API.removeAnimatedEventFromView(
|
|
viewTag,
|
|
eventName,
|
|
mapping.animatedValueTag,
|
|
);
|
|
});
|
|
},
|
|
};
|
|
}
|
|
|
|
class AnimatedEvent {
|
|
_argMapping: Array<?Mapping>;
|
|
_listeners: Array<Function> = [];
|
|
_callListeners: Function;
|
|
_attachedEvent: ?{
|
|
detach: () => void,
|
|
};
|
|
__isNative: boolean;
|
|
|
|
constructor(argMapping: Array<?Mapping>, config?: EventConfig = {}) {
|
|
this._argMapping = argMapping;
|
|
if (config.listener) {
|
|
this.__addListener(config.listener);
|
|
}
|
|
this._callListeners = this._callListeners.bind(this);
|
|
this._attachedEvent = null;
|
|
this.__isNative = shouldUseNativeDriver(config);
|
|
|
|
if (__DEV__) {
|
|
this._validateMapping();
|
|
}
|
|
}
|
|
|
|
__addListener(callback: Function): void {
|
|
this._listeners.push(callback);
|
|
}
|
|
|
|
__removeListener(callback: Function): void {
|
|
this._listeners = this._listeners.filter(listener => listener !== callback);
|
|
}
|
|
|
|
__attach(viewRef: any, eventName: string) {
|
|
invariant(
|
|
this.__isNative,
|
|
'Only native driven events need to be attached.',
|
|
);
|
|
|
|
this._attachedEvent = attachNativeEvent(
|
|
viewRef,
|
|
eventName,
|
|
this._argMapping,
|
|
);
|
|
}
|
|
|
|
__detach(viewTag: any, eventName: string) {
|
|
invariant(
|
|
this.__isNative,
|
|
'Only native driven events need to be detached.',
|
|
);
|
|
|
|
this._attachedEvent && this._attachedEvent.detach();
|
|
}
|
|
|
|
__getHandler() {
|
|
if (this.__isNative) {
|
|
return this._callListeners;
|
|
}
|
|
|
|
return (...args: any) => {
|
|
const traverse = (recMapping, recEvt, key) => {
|
|
if (typeof recEvt === 'number' && recMapping instanceof AnimatedValue) {
|
|
recMapping.setValue(recEvt);
|
|
} else if (typeof recMapping === 'object') {
|
|
for (const mappingKey in recMapping) {
|
|
/* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This
|
|
* comment suppresses an error when upgrading Flow's support for
|
|
* React. To see the error delete this comment and run Flow. */
|
|
traverse(recMapping[mappingKey], recEvt[mappingKey], mappingKey);
|
|
}
|
|
}
|
|
};
|
|
|
|
if (!this.__isNative) {
|
|
this._argMapping.forEach((mapping, idx) => {
|
|
traverse(mapping, args[idx], 'arg' + idx);
|
|
});
|
|
}
|
|
this._callListeners(...args);
|
|
};
|
|
}
|
|
|
|
_callListeners(...args) {
|
|
this._listeners.forEach(listener => listener(...args));
|
|
}
|
|
|
|
_validateMapping() {
|
|
const traverse = (recMapping, recEvt, key) => {
|
|
if (typeof recEvt === 'number') {
|
|
invariant(
|
|
recMapping instanceof AnimatedValue,
|
|
'Bad mapping of type ' +
|
|
typeof recMapping +
|
|
' for key ' +
|
|
key +
|
|
', event value must map to AnimatedValue',
|
|
);
|
|
return;
|
|
}
|
|
invariant(
|
|
typeof recMapping === 'object',
|
|
'Bad mapping of type ' + typeof recMapping + ' for key ' + key,
|
|
);
|
|
invariant(
|
|
typeof recEvt === 'object',
|
|
'Bad event of type ' + typeof recEvt + ' for key ' + key,
|
|
);
|
|
for (const mappingKey in recMapping) {
|
|
traverse(recMapping[mappingKey], recEvt[mappingKey], mappingKey);
|
|
}
|
|
};
|
|
}
|
|
}
|
|
|
|
module.exports = {AnimatedEvent, attachNativeEvent};
|