yeet
This commit is contained in:
87
node_modules/react-native/Libraries/Utilities/Appearance.js
generated
vendored
Normal file
87
node_modules/react-native/Libraries/Utilities/Appearance.js
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import EventEmitter from '../vendor/emitter/EventEmitter';
|
||||
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
|
||||
import NativeAppearance, {
|
||||
type AppearancePreferences,
|
||||
type ColorSchemeName,
|
||||
} from './NativeAppearance';
|
||||
import invariant from 'invariant';
|
||||
import {isAsyncDebugging} from './DebugEnvironment';
|
||||
|
||||
type AppearanceListener = (preferences: AppearancePreferences) => void;
|
||||
const eventEmitter = new EventEmitter();
|
||||
|
||||
if (NativeAppearance) {
|
||||
const nativeEventEmitter = new NativeEventEmitter(NativeAppearance);
|
||||
nativeEventEmitter.addListener(
|
||||
'appearanceChanged',
|
||||
(newAppearance: AppearancePreferences) => {
|
||||
const {colorScheme} = newAppearance;
|
||||
invariant(
|
||||
colorScheme === 'dark' ||
|
||||
colorScheme === 'light' ||
|
||||
colorScheme == null,
|
||||
"Unrecognized color scheme. Did you mean 'dark' or 'light'?",
|
||||
);
|
||||
eventEmitter.emit('change', {colorScheme});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
/**
|
||||
* Note: Although color scheme is available immediately, it may change at any
|
||||
* time. Any rendering logic or styles that depend on this should try to call
|
||||
* this function on every render, rather than caching the value (for example,
|
||||
* using inline styles rather than setting a value in a `StyleSheet`).
|
||||
*
|
||||
* Example: `const colorScheme = Appearance.getColorScheme();`
|
||||
*
|
||||
* @returns {?ColorSchemeName} Value for the color scheme preference.
|
||||
*/
|
||||
getColorScheme(): ?ColorSchemeName {
|
||||
if (__DEV__) {
|
||||
if (isAsyncDebugging) {
|
||||
// Hard code light theme when using the async debugger as
|
||||
// sync calls aren't supported
|
||||
return 'light';
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
|
||||
const nativeColorScheme: ?string =
|
||||
NativeAppearance == null
|
||||
? null
|
||||
: NativeAppearance.getColorScheme() || null;
|
||||
invariant(
|
||||
nativeColorScheme === 'dark' ||
|
||||
nativeColorScheme === 'light' ||
|
||||
nativeColorScheme == null,
|
||||
"Unrecognized color scheme. Did you mean 'dark' or 'light'?",
|
||||
);
|
||||
return nativeColorScheme;
|
||||
},
|
||||
/**
|
||||
* Add an event handler that is fired when appearance preferences change.
|
||||
*/
|
||||
addChangeListener(listener: AppearanceListener): void {
|
||||
eventEmitter.addListener('change', listener);
|
||||
},
|
||||
/**
|
||||
* Remove an event handler.
|
||||
*/
|
||||
removeChangeListener(listener: AppearanceListener): void {
|
||||
eventEmitter.removeListener('change', listener);
|
||||
},
|
||||
};
|
116
node_modules/react-native/Libraries/Utilities/BackHandler.android.js
generated
vendored
Normal file
116
node_modules/react-native/Libraries/Utilities/BackHandler.android.js
generated
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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';
|
||||
|
||||
import NativeDeviceEventManager from '../../Libraries/NativeModules/specs/NativeDeviceEventManager';
|
||||
import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
|
||||
|
||||
const DEVICE_BACK_EVENT = 'hardwareBackPress';
|
||||
|
||||
type BackPressEventName = 'backPress' | 'hardwareBackPress';
|
||||
|
||||
const _backPressSubscriptions = [];
|
||||
|
||||
RCTDeviceEventEmitter.addListener(DEVICE_BACK_EVENT, function() {
|
||||
for (let i = _backPressSubscriptions.length - 1; i >= 0; i--) {
|
||||
if (_backPressSubscriptions[i]()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
BackHandler.exitApp();
|
||||
});
|
||||
|
||||
/**
|
||||
* Detect hardware button presses for back navigation.
|
||||
*
|
||||
* Android: Detect hardware back button presses, and programmatically invoke the default back button
|
||||
* functionality to exit the app if there are no listeners or if none of the listeners return true.
|
||||
*
|
||||
* tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented:
|
||||
* programmatically disable menu button handling
|
||||
* functionality to exit the app if there are no listeners or if none of the listeners return true.)
|
||||
*
|
||||
* iOS: Not applicable.
|
||||
*
|
||||
* The event subscriptions are called in reverse order (i.e. last registered subscription first),
|
||||
* and if one subscription returns true then subscriptions registered earlier will not be called.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```javascript
|
||||
* BackHandler.addEventListener('hardwareBackPress', function() {
|
||||
* // this.onMainScreen and this.goBack are just examples, you need to use your own implementation here
|
||||
* // Typically you would use the navigator here to go to the last state.
|
||||
*
|
||||
* if (!this.onMainScreen()) {
|
||||
* this.goBack();
|
||||
* return true;
|
||||
* }
|
||||
* return false;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
type TBackHandler = {|
|
||||
+exitApp: () => void,
|
||||
+addEventListener: (
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
) => {remove: () => void, ...},
|
||||
+removeEventListener: (
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
) => void,
|
||||
|};
|
||||
const BackHandler: TBackHandler = {
|
||||
exitApp: function(): void {
|
||||
if (!NativeDeviceEventManager) {
|
||||
return;
|
||||
}
|
||||
|
||||
NativeDeviceEventManager.invokeDefaultBackPressHandler();
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an event handler. Supported events:
|
||||
*
|
||||
* - `hardwareBackPress`: Fires when the Android hardware back button is pressed or when the
|
||||
* tvOS menu button is pressed.
|
||||
*/
|
||||
addEventListener: function(
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
): {remove: () => void, ...} {
|
||||
if (_backPressSubscriptions.indexOf(handler) === -1) {
|
||||
_backPressSubscriptions.push(handler);
|
||||
}
|
||||
return {
|
||||
remove: (): void => BackHandler.removeEventListener(eventName, handler),
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes the event handler.
|
||||
*/
|
||||
removeEventListener: function(
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
): void {
|
||||
if (_backPressSubscriptions.indexOf(handler) !== -1) {
|
||||
_backPressSubscriptions.splice(
|
||||
_backPressSubscriptions.indexOf(handler),
|
||||
1,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = BackHandler;
|
123
node_modules/react-native/Libraries/Utilities/BackHandler.ios.js
generated
vendored
Normal file
123
node_modules/react-native/Libraries/Utilities/BackHandler.ios.js
generated
vendored
Normal file
@ -0,0 +1,123 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
// On Apple TV, this implements back navigation using the TV remote's menu button.
|
||||
// On iOS, this just implements a stub.
|
||||
|
||||
'use strict';
|
||||
|
||||
const Platform = require('./Platform');
|
||||
const TVEventHandler = require('../Components/AppleTV/TVEventHandler');
|
||||
|
||||
type BackPressEventName = 'backPress' | 'hardwareBackPress';
|
||||
|
||||
function emptyFunction(): void {}
|
||||
|
||||
/**
|
||||
* Detect hardware button presses for back navigation.
|
||||
*
|
||||
* Android: Detect hardware back button presses, and programmatically invoke the default back button
|
||||
* functionality to exit the app if there are no listeners or if none of the listeners return true.
|
||||
*
|
||||
* tvOS: Detect presses of the menu button on the TV remote. (Still to be implemented:
|
||||
* programmatically disable menu button handling
|
||||
* functionality to exit the app if there are no listeners or if none of the listeners return true.)
|
||||
*
|
||||
* iOS: Not applicable.
|
||||
*
|
||||
* The event subscriptions are called in reverse order (i.e. last registered subscription first),
|
||||
* and if one subscription returns true then subscriptions registered earlier will not be called.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```javascript
|
||||
* BackHandler.addEventListener('hardwareBackPress', function() {
|
||||
* // this.onMainScreen and this.goBack are just examples, you need to use your own implementation here
|
||||
* // Typically you would use the navigator here to go to the last state.
|
||||
*
|
||||
* if (!this.onMainScreen()) {
|
||||
* this.goBack();
|
||||
* return true;
|
||||
* }
|
||||
* return false;
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
type TBackHandler = {|
|
||||
+exitApp: () => void,
|
||||
+addEventListener: (
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
) => {remove: () => void, ...},
|
||||
+removeEventListener: (
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
) => void,
|
||||
|};
|
||||
|
||||
let BackHandler: TBackHandler;
|
||||
|
||||
if (Platform.isTV) {
|
||||
const _tvEventHandler = new TVEventHandler();
|
||||
const _backPressSubscriptions = new Set();
|
||||
|
||||
_tvEventHandler.enable(this, function(cmp, evt) {
|
||||
if (evt && evt.eventType === 'menu') {
|
||||
let invokeDefault = true;
|
||||
const subscriptions = Array.from(
|
||||
_backPressSubscriptions.values(),
|
||||
).reverse();
|
||||
|
||||
for (let i = 0; i < subscriptions.length; ++i) {
|
||||
if (subscriptions[i]()) {
|
||||
invokeDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invokeDefault) {
|
||||
BackHandler.exitApp();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
BackHandler = {
|
||||
exitApp: emptyFunction,
|
||||
|
||||
addEventListener: function(
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
): {remove: () => void, ...} {
|
||||
_backPressSubscriptions.add(handler);
|
||||
return {
|
||||
remove: () => BackHandler.removeEventListener(eventName, handler),
|
||||
};
|
||||
},
|
||||
|
||||
removeEventListener: function(
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
): void {
|
||||
_backPressSubscriptions.delete(handler);
|
||||
},
|
||||
};
|
||||
} else {
|
||||
BackHandler = {
|
||||
exitApp: emptyFunction,
|
||||
addEventListener(_eventName: BackPressEventName, _handler: Function) {
|
||||
return {
|
||||
remove: emptyFunction,
|
||||
};
|
||||
},
|
||||
removeEventListener(_eventName: BackPressEventName, _handler: Function) {},
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = BackHandler;
|
21
node_modules/react-native/Libraries/Utilities/DebugEnvironment.js
generated
vendored
Normal file
21
node_modules/react-native/Libraries/Utilities/DebugEnvironment.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export let isAsyncDebugging: boolean = false;
|
||||
|
||||
if (__DEV__) {
|
||||
// These native interfaces don't exist in asynchronous debugging environments.
|
||||
isAsyncDebugging =
|
||||
!global.nativeExtensions &&
|
||||
!global.nativeCallSyncHook &&
|
||||
!global.RN$Bridgeless;
|
||||
}
|
65
node_modules/react-native/Libraries/Utilities/DevSettings.js
generated
vendored
Normal file
65
node_modules/react-native/Libraries/Utilities/DevSettings.js
generated
vendored
Normal file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
import NativeDevSettings from '../NativeModules/specs/NativeDevSettings';
|
||||
import NativeEventEmitter from '../EventEmitter/NativeEventEmitter';
|
||||
|
||||
class DevSettings extends NativeEventEmitter {
|
||||
_menuItems: Map<string, () => mixed>;
|
||||
|
||||
constructor() {
|
||||
super(NativeDevSettings);
|
||||
|
||||
this._menuItems = new Map();
|
||||
}
|
||||
|
||||
addMenuItem(title: string, handler: () => mixed) {
|
||||
// Make sure items are not added multiple times. This can
|
||||
// happen when hot reloading the module that registers the
|
||||
// menu items. The title is used as the id which means we
|
||||
// don't support multiple items with the same name.
|
||||
const oldHandler = this._menuItems.get(title);
|
||||
if (oldHandler != null) {
|
||||
this.removeListener('didPressMenuItem', oldHandler);
|
||||
} else {
|
||||
NativeDevSettings.addMenuItem(title);
|
||||
}
|
||||
|
||||
this._menuItems.set(title, handler);
|
||||
this.addListener('didPressMenuItem', event => {
|
||||
if (event.title === title) {
|
||||
handler();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
reload(reason: string) {
|
||||
if (typeof NativeDevSettings.reloadWithReason === 'function') {
|
||||
NativeDevSettings.reloadWithReason(reason || 'Uncategorized from JS');
|
||||
} else {
|
||||
NativeDevSettings.reload();
|
||||
}
|
||||
}
|
||||
|
||||
onFastRefresh() {
|
||||
if (typeof NativeDevSettings.onFastRefresh === 'function') {
|
||||
NativeDevSettings.onFastRefresh();
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add other dev setting methods exposed by the native module.
|
||||
}
|
||||
|
||||
// Avoid including the full `NativeDevSettings` class in prod.
|
||||
class NoopDevSettings {
|
||||
addMenuItem(title: string, handler: () => mixed) {}
|
||||
reload() {}
|
||||
}
|
||||
|
||||
module.exports = __DEV__ ? new DevSettings() : new NoopDevSettings();
|
15
node_modules/react-native/Libraries/Utilities/DeviceInfo.js
generated
vendored
Normal file
15
node_modules/react-native/Libraries/Utilities/DeviceInfo.js
generated
vendored
Normal file
@ -0,0 +1,15 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import NativeDeviceInfo from './NativeDeviceInfo';
|
||||
|
||||
module.exports = NativeDeviceInfo;
|
142
node_modules/react-native/Libraries/Utilities/Dimensions.js
generated
vendored
Normal file
142
node_modules/react-native/Libraries/Utilities/Dimensions.js
generated
vendored
Normal file
@ -0,0 +1,142 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import EventEmitter from '../vendor/emitter/EventEmitter';
|
||||
import RCTDeviceEventEmitter from '../EventEmitter/RCTDeviceEventEmitter';
|
||||
import NativeDeviceInfo, {
|
||||
type DisplayMetrics,
|
||||
type DimensionsPayload,
|
||||
} from './NativeDeviceInfo';
|
||||
import invariant from 'invariant';
|
||||
|
||||
type DimensionsValue = {
|
||||
window?: DisplayMetrics,
|
||||
screen?: DisplayMetrics,
|
||||
...
|
||||
};
|
||||
|
||||
const eventEmitter = new EventEmitter();
|
||||
let dimensionsInitialized = false;
|
||||
let dimensions: DimensionsValue;
|
||||
|
||||
class Dimensions {
|
||||
/**
|
||||
* NOTE: `useWindowDimensions` is the preffered API for React components.
|
||||
*
|
||||
* Initial dimensions are set before `runApplication` is called so they should
|
||||
* be available before any other require's are run, but may be updated later.
|
||||
*
|
||||
* Note: Although dimensions are available immediately, they may change (e.g
|
||||
* due to device rotation) so any rendering logic or styles that depend on
|
||||
* these constants should try to call this function on every render, rather
|
||||
* than caching the value (for example, using inline styles rather than
|
||||
* setting a value in a `StyleSheet`).
|
||||
*
|
||||
* Example: `const {height, width} = Dimensions.get('window');`
|
||||
*
|
||||
* @param {string} dim Name of dimension as defined when calling `set`.
|
||||
* @returns {Object?} Value for the dimension.
|
||||
*/
|
||||
static get(dim: string): Object {
|
||||
invariant(dimensions[dim], 'No dimension set for key ' + dim);
|
||||
return dimensions[dim];
|
||||
}
|
||||
|
||||
/**
|
||||
* This should only be called from native code by sending the
|
||||
* didUpdateDimensions event.
|
||||
*
|
||||
* @param {object} dims Simple string-keyed object of dimensions to set
|
||||
*/
|
||||
static set(dims: $ReadOnly<{[key: string]: any, ...}>): void {
|
||||
// We calculate the window dimensions in JS so that we don't encounter loss of
|
||||
// precision in transferring the dimensions (which could be non-integers) over
|
||||
// the bridge.
|
||||
let {screen, window} = dims;
|
||||
const {windowPhysicalPixels} = dims;
|
||||
if (windowPhysicalPixels) {
|
||||
window = {
|
||||
width: windowPhysicalPixels.width / windowPhysicalPixels.scale,
|
||||
height: windowPhysicalPixels.height / windowPhysicalPixels.scale,
|
||||
scale: windowPhysicalPixels.scale,
|
||||
fontScale: windowPhysicalPixels.fontScale,
|
||||
};
|
||||
}
|
||||
const {screenPhysicalPixels} = dims;
|
||||
if (screenPhysicalPixels) {
|
||||
screen = {
|
||||
width: screenPhysicalPixels.width / screenPhysicalPixels.scale,
|
||||
height: screenPhysicalPixels.height / screenPhysicalPixels.scale,
|
||||
scale: screenPhysicalPixels.scale,
|
||||
fontScale: screenPhysicalPixels.fontScale,
|
||||
};
|
||||
} else if (screen == null) {
|
||||
screen = window;
|
||||
}
|
||||
|
||||
dimensions = {window, screen};
|
||||
if (dimensionsInitialized) {
|
||||
// Don't fire 'change' the first time the dimensions are set.
|
||||
eventEmitter.emit('change', dimensions);
|
||||
} else {
|
||||
dimensionsInitialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an event handler. Supported events:
|
||||
*
|
||||
* - `change`: Fires when a property within the `Dimensions` object changes. The argument
|
||||
* to the event handler is an object with `window` and `screen` properties whose values
|
||||
* are the same as the return values of `Dimensions.get('window')` and
|
||||
* `Dimensions.get('screen')`, respectively.
|
||||
*/
|
||||
static addEventListener(type: 'change', handler: Function) {
|
||||
invariant(
|
||||
type === 'change',
|
||||
'Trying to subscribe to unknown event: "%s"',
|
||||
type,
|
||||
);
|
||||
eventEmitter.addListener(type, handler);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove an event handler.
|
||||
*/
|
||||
static removeEventListener(type: 'change', handler: Function) {
|
||||
invariant(
|
||||
type === 'change',
|
||||
'Trying to remove listener for unknown event: "%s"',
|
||||
type,
|
||||
);
|
||||
eventEmitter.removeListener(type, handler);
|
||||
}
|
||||
}
|
||||
|
||||
let initialDims: ?$ReadOnly<{[key: string]: any, ...}> =
|
||||
global.nativeExtensions &&
|
||||
global.nativeExtensions.DeviceInfo &&
|
||||
global.nativeExtensions.DeviceInfo.Dimensions;
|
||||
if (!initialDims) {
|
||||
// Subscribe before calling getConstants to make sure we don't miss any updates in between.
|
||||
RCTDeviceEventEmitter.addListener(
|
||||
'didUpdateDimensions',
|
||||
(update: DimensionsPayload) => {
|
||||
Dimensions.set(update);
|
||||
},
|
||||
);
|
||||
initialDims = NativeDeviceInfo.getConstants().Dimensions;
|
||||
}
|
||||
|
||||
Dimensions.set(initialDims);
|
||||
|
||||
module.exports = Dimensions;
|
25
node_modules/react-native/Libraries/Utilities/GlobalPerformanceLogger.js
generated
vendored
Normal file
25
node_modules/react-native/Libraries/Utilities/GlobalPerformanceLogger.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
const createPerformanceLogger = require('./createPerformanceLogger');
|
||||
|
||||
import type {IPerformanceLogger} from './createPerformanceLogger';
|
||||
|
||||
/**
|
||||
* This is a global shared instance of IPerformanceLogger that is created with
|
||||
* createPerformanceLogger().
|
||||
* This logger should be used only for global performance metrics like the ones
|
||||
* that are logged during loading bundle. If you want to log something from your
|
||||
* React component you should use PerformanceLoggerContext instead.
|
||||
*/
|
||||
const GlobalPerformanceLogger: IPerformanceLogger = createPerformanceLogger();
|
||||
|
||||
module.exports = GlobalPerformanceLogger;
|
327
node_modules/react-native/Libraries/Utilities/HMRClient.js
generated
vendored
Normal file
327
node_modules/react-native/Libraries/Utilities/HMRClient.js
generated
vendored
Normal file
@ -0,0 +1,327 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const DevSettings = require('./DevSettings');
|
||||
const invariant = require('invariant');
|
||||
const MetroHMRClient = require('metro/src/lib/bundle-modules/HMRClient');
|
||||
const Platform = require('./Platform');
|
||||
const prettyFormat = require('pretty-format');
|
||||
|
||||
import NativeRedBox from '../NativeModules/specs/NativeRedBox';
|
||||
import * as LogBoxData from '../LogBox/Data/LogBoxData';
|
||||
import type {ExtendedError} from '../Core/Devtools/parseErrorStack';
|
||||
|
||||
const pendingEntryPoints = [];
|
||||
let hmrClient = null;
|
||||
let hmrUnavailableReason: string | null = null;
|
||||
let currentCompileErrorMessage: string | null = null;
|
||||
let didConnect: boolean = false;
|
||||
let pendingLogs: Array<[LogLevel, Array<mixed>]> = [];
|
||||
|
||||
type LogLevel =
|
||||
| 'trace'
|
||||
| 'info'
|
||||
| 'warn'
|
||||
| 'error'
|
||||
| 'log'
|
||||
| 'group'
|
||||
| 'groupCollapsed'
|
||||
| 'groupEnd'
|
||||
| 'debug';
|
||||
|
||||
export type HMRClientNativeInterface = {|
|
||||
enable(): void,
|
||||
disable(): void,
|
||||
registerBundle(requestUrl: string): void,
|
||||
log(level: LogLevel, data: Array<mixed>): void,
|
||||
setup(
|
||||
platform: string,
|
||||
bundleEntry: string,
|
||||
host: string,
|
||||
port: number | string,
|
||||
isEnabled: boolean,
|
||||
): void,
|
||||
|};
|
||||
|
||||
/**
|
||||
* HMR Client that receives from the server HMR updates and propagates them
|
||||
* runtime to reflects those changes.
|
||||
*/
|
||||
const HMRClient: HMRClientNativeInterface = {
|
||||
enable() {
|
||||
if (hmrUnavailableReason !== null) {
|
||||
// If HMR became unavailable while you weren't using it,
|
||||
// explain why when you try to turn it on.
|
||||
// This is an error (and not a warning) because it is shown
|
||||
// in response to a direct user action.
|
||||
throw new Error(hmrUnavailableReason);
|
||||
}
|
||||
|
||||
invariant(hmrClient, 'Expected HMRClient.setup() call at startup.');
|
||||
const LoadingView = require('./LoadingView');
|
||||
|
||||
// We use this for internal logging only.
|
||||
// It doesn't affect the logic.
|
||||
hmrClient.send(JSON.stringify({type: 'log-opt-in'}));
|
||||
|
||||
// When toggling Fast Refresh on, we might already have some stashed updates.
|
||||
// Since they'll get applied now, we'll show a banner.
|
||||
const hasUpdates = hmrClient.hasPendingUpdates();
|
||||
|
||||
if (hasUpdates) {
|
||||
LoadingView.showMessage('Refreshing...', 'refresh');
|
||||
}
|
||||
try {
|
||||
hmrClient.enable();
|
||||
} finally {
|
||||
if (hasUpdates) {
|
||||
LoadingView.hide();
|
||||
}
|
||||
}
|
||||
|
||||
// There could be a compile error while Fast Refresh was off,
|
||||
// but we ignored it at the time. Show it now.
|
||||
showCompileError();
|
||||
},
|
||||
|
||||
disable() {
|
||||
invariant(hmrClient, 'Expected HMRClient.setup() call at startup.');
|
||||
hmrClient.disable();
|
||||
},
|
||||
|
||||
registerBundle(requestUrl: string) {
|
||||
invariant(hmrClient, 'Expected HMRClient.setup() call at startup.');
|
||||
pendingEntryPoints.push(requestUrl);
|
||||
registerBundleEntryPoints(hmrClient);
|
||||
},
|
||||
|
||||
log(level: LogLevel, data: Array<mixed>) {
|
||||
if (!hmrClient) {
|
||||
// Catch a reasonable number of early logs
|
||||
// in case hmrClient gets initialized later.
|
||||
pendingLogs.push([level, data]);
|
||||
if (pendingLogs.length > 100) {
|
||||
pendingLogs.shift();
|
||||
}
|
||||
return;
|
||||
}
|
||||
try {
|
||||
hmrClient.send(
|
||||
JSON.stringify({
|
||||
type: 'log',
|
||||
level,
|
||||
data: data.map(item =>
|
||||
typeof item === 'string'
|
||||
? item
|
||||
: prettyFormat(item, {
|
||||
escapeString: true,
|
||||
highlight: true,
|
||||
maxDepth: 3,
|
||||
min: true,
|
||||
plugins: [prettyFormat.plugins.ReactElement],
|
||||
}),
|
||||
),
|
||||
}),
|
||||
);
|
||||
} catch (error) {
|
||||
// If sending logs causes any failures we want to silently ignore them
|
||||
// to ensure we do not cause infinite-logging loops.
|
||||
}
|
||||
},
|
||||
|
||||
// Called once by the bridge on startup, even if Fast Refresh is off.
|
||||
// It creates the HMR client but doesn't actually set up the socket yet.
|
||||
setup(
|
||||
platform: string,
|
||||
bundleEntry: string,
|
||||
host: string,
|
||||
port: number | string,
|
||||
isEnabled: boolean,
|
||||
) {
|
||||
invariant(platform, 'Missing required parameter `platform`');
|
||||
invariant(bundleEntry, 'Missing required parameter `bundleEntry`');
|
||||
invariant(host, 'Missing required parameter `host`');
|
||||
invariant(!hmrClient, 'Cannot initialize hmrClient twice');
|
||||
|
||||
// Moving to top gives errors due to NativeModules not being initialized
|
||||
const LoadingView = require('./LoadingView');
|
||||
|
||||
const wsHost = port !== null && port !== '' ? `${host}:${port}` : host;
|
||||
const client = new MetroHMRClient(`ws://${wsHost}/hot`);
|
||||
hmrClient = client;
|
||||
|
||||
pendingEntryPoints.push(
|
||||
`ws://${wsHost}/hot?bundleEntry=${bundleEntry}&platform=${platform}`,
|
||||
);
|
||||
|
||||
client.on('connection-error', e => {
|
||||
let error = `Cannot connect to the Metro server.
|
||||
|
||||
Try the following to fix the issue:
|
||||
- Ensure that the Metro server is running and available on the same network`;
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
error += `
|
||||
- Ensure that the Metro server URL is correctly set in AppDelegate`;
|
||||
} else {
|
||||
error += `
|
||||
- Ensure that your device/emulator is connected to your machine and has USB debugging enabled - run 'adb devices' to see a list of connected devices
|
||||
- If you're on a physical device connected to the same machine, run 'adb reverse tcp:8081 tcp:8081' to forward requests from your device
|
||||
- If your device is on the same Wi-Fi network, set 'Debug server host & port for device' in 'Dev settings' to your machine's IP address and the port of the local dev server - e.g. 10.0.1.1:8081`;
|
||||
}
|
||||
|
||||
error += `
|
||||
|
||||
URL: ${host}:${port}
|
||||
|
||||
Error: ${e.message}`;
|
||||
|
||||
setHMRUnavailableReason(error);
|
||||
});
|
||||
|
||||
client.on('update-start', ({isInitialUpdate}) => {
|
||||
currentCompileErrorMessage = null;
|
||||
didConnect = true;
|
||||
|
||||
if (client.isEnabled() && !isInitialUpdate) {
|
||||
LoadingView.showMessage('Refreshing...', 'refresh');
|
||||
}
|
||||
});
|
||||
|
||||
client.on('update', ({isInitialUpdate}) => {
|
||||
if (client.isEnabled() && !isInitialUpdate) {
|
||||
dismissRedbox();
|
||||
LogBoxData.clear();
|
||||
}
|
||||
});
|
||||
|
||||
client.on('update-done', () => {
|
||||
LoadingView.hide();
|
||||
});
|
||||
|
||||
client.on('error', data => {
|
||||
LoadingView.hide();
|
||||
|
||||
if (data.type === 'GraphNotFoundError') {
|
||||
client.close();
|
||||
setHMRUnavailableReason(
|
||||
'The Metro server has restarted since the last edit. Reload to reconnect.',
|
||||
);
|
||||
} else if (data.type === 'RevisionNotFoundError') {
|
||||
client.close();
|
||||
setHMRUnavailableReason(
|
||||
'The Metro server and the client are out of sync. Reload to reconnect.',
|
||||
);
|
||||
} else {
|
||||
currentCompileErrorMessage = `${data.type} ${data.message}`;
|
||||
if (client.isEnabled()) {
|
||||
showCompileError();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
client.on('close', data => {
|
||||
LoadingView.hide();
|
||||
setHMRUnavailableReason('Disconnected from the Metro server.');
|
||||
});
|
||||
|
||||
if (isEnabled) {
|
||||
HMRClient.enable();
|
||||
} else {
|
||||
HMRClient.disable();
|
||||
}
|
||||
|
||||
registerBundleEntryPoints(hmrClient);
|
||||
flushEarlyLogs(hmrClient);
|
||||
},
|
||||
};
|
||||
|
||||
function setHMRUnavailableReason(reason) {
|
||||
invariant(hmrClient, 'Expected HMRClient.setup() call at startup.');
|
||||
if (hmrUnavailableReason !== null) {
|
||||
// Don't show more than one warning.
|
||||
return;
|
||||
}
|
||||
hmrUnavailableReason = reason;
|
||||
|
||||
// We only want to show a warning if Fast Refresh is on *and* if we ever
|
||||
// previously managed to connect successfully. We don't want to show
|
||||
// the warning to native engineers who use cached bundles without Metro.
|
||||
if (hmrClient.isEnabled() && didConnect) {
|
||||
console.warn(reason);
|
||||
// (Not using the `warning` module to prevent a Buck cycle.)
|
||||
}
|
||||
}
|
||||
|
||||
function registerBundleEntryPoints(client) {
|
||||
if (hmrUnavailableReason) {
|
||||
DevSettings.reload('Bundle Splitting – Metro disconnected');
|
||||
return;
|
||||
}
|
||||
|
||||
if (pendingEntryPoints.length > 0) {
|
||||
client.send(
|
||||
JSON.stringify({
|
||||
type: 'register-entrypoints',
|
||||
entryPoints: pendingEntryPoints,
|
||||
}),
|
||||
);
|
||||
pendingEntryPoints.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function flushEarlyLogs(client) {
|
||||
try {
|
||||
pendingLogs.forEach(([level: LogLevel, data: Array<mixed>]) => {
|
||||
HMRClient.log(level, data);
|
||||
});
|
||||
} finally {
|
||||
pendingLogs.length = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function dismissRedbox() {
|
||||
if (
|
||||
Platform.OS === 'ios' &&
|
||||
NativeRedBox != null &&
|
||||
NativeRedBox.dismiss != null
|
||||
) {
|
||||
NativeRedBox.dismiss();
|
||||
} else {
|
||||
const NativeExceptionsManager = require('../Core/NativeExceptionsManager')
|
||||
.default;
|
||||
NativeExceptionsManager &&
|
||||
NativeExceptionsManager.dismissRedbox &&
|
||||
NativeExceptionsManager.dismissRedbox();
|
||||
}
|
||||
}
|
||||
|
||||
function showCompileError() {
|
||||
if (currentCompileErrorMessage === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Even if there is already a redbox, syntax errors are more important.
|
||||
// Otherwise you risk seeing a stale runtime error while a syntax error is more recent.
|
||||
dismissRedbox();
|
||||
|
||||
const message = currentCompileErrorMessage;
|
||||
currentCompileErrorMessage = null;
|
||||
|
||||
const error: ExtendedError = new Error(message);
|
||||
// Symbolicating compile errors is wasted effort
|
||||
// because the stack trace is meaningless:
|
||||
error.preventSymbolication = true;
|
||||
throw error;
|
||||
}
|
||||
|
||||
module.exports = HMRClient;
|
30
node_modules/react-native/Libraries/Utilities/HMRClientProdShim.js
generated
vendored
Normal file
30
node_modules/react-native/Libraries/Utilities/HMRClientProdShim.js
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {HMRClientNativeInterface} from './HMRClient';
|
||||
|
||||
// This shim ensures DEV binary builds don't crash in JS
|
||||
// when they're combined with a PROD JavaScript build.
|
||||
const HMRClientProdShim: HMRClientNativeInterface = {
|
||||
setup() {},
|
||||
enable() {
|
||||
console.error(
|
||||
'Fast Refresh is disabled in JavaScript bundles built in production mode. ' +
|
||||
'Did you forget to run Metro?',
|
||||
);
|
||||
},
|
||||
disable() {},
|
||||
registerBundle() {},
|
||||
log() {},
|
||||
};
|
||||
|
||||
module.exports = HMRClientProdShim;
|
40
node_modules/react-native/Libraries/Utilities/JSDevSupportModule.js
generated
vendored
Normal file
40
node_modules/react-native/Libraries/Utilities/JSDevSupportModule.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import NativeJSDevSupport from './NativeJSDevSupport';
|
||||
const ReactNative = require('../Renderer/shims/ReactNative');
|
||||
|
||||
const JSDevSupportModule = {
|
||||
getJSHierarchy: function(tag: number) {
|
||||
if (NativeJSDevSupport) {
|
||||
const constants = NativeJSDevSupport.getConstants();
|
||||
try {
|
||||
const {
|
||||
computeComponentStackForErrorReporting,
|
||||
} = ReactNative.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
|
||||
const componentStack = computeComponentStackForErrorReporting(tag);
|
||||
if (!componentStack) {
|
||||
NativeJSDevSupport.onFailure(
|
||||
constants.ERROR_CODE_VIEW_NOT_FOUND,
|
||||
"Component stack doesn't exist for tag " + tag,
|
||||
);
|
||||
} else {
|
||||
NativeJSDevSupport.onSuccess(componentStack);
|
||||
}
|
||||
} catch (e) {
|
||||
NativeJSDevSupport.onFailure(constants.ERROR_CODE_EXCEPTION, e.message);
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = JSDevSupportModule;
|
29
node_modules/react-native/Libraries/Utilities/LoadingView.android.js
generated
vendored
Normal file
29
node_modules/react-native/Libraries/Utilities/LoadingView.android.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import ToastAndroid from '../Components/ToastAndroid/ToastAndroid';
|
||||
|
||||
const TOAST_SHORT_DELAY = 2000;
|
||||
let isVisible = false;
|
||||
|
||||
module.exports = {
|
||||
showMessage(message: string, type: 'load' | 'refresh') {
|
||||
if (!isVisible) {
|
||||
ToastAndroid.show(message, ToastAndroid.SHORT);
|
||||
isVisible = true;
|
||||
setTimeout(() => {
|
||||
isVisible = false;
|
||||
}, TOAST_SHORT_DELAY);
|
||||
}
|
||||
},
|
||||
hide() {},
|
||||
};
|
40
node_modules/react-native/Libraries/Utilities/LoadingView.ios.js
generated
vendored
Normal file
40
node_modules/react-native/Libraries/Utilities/LoadingView.ios.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import processColor from '../StyleSheet/processColor';
|
||||
import NativeDevLoadingView from './NativeDevLoadingView';
|
||||
|
||||
module.exports = {
|
||||
showMessage(message: string, type: 'load' | 'refresh') {
|
||||
if (NativeDevLoadingView) {
|
||||
const green = processColor('#005a00');
|
||||
const blue = processColor('#2584e8');
|
||||
const white = processColor('#ffffff');
|
||||
|
||||
NativeDevLoadingView.showMessage(
|
||||
message,
|
||||
// Use same colors as iOS "Personal Hotspot" bar.
|
||||
typeof white === 'number' ? white : null,
|
||||
type && type === 'load'
|
||||
? typeof green === 'number'
|
||||
? green
|
||||
: null
|
||||
: typeof blue === 'number'
|
||||
? blue
|
||||
: null,
|
||||
);
|
||||
}
|
||||
},
|
||||
hide() {
|
||||
NativeDevLoadingView && NativeDevLoadingView.hide();
|
||||
},
|
||||
};
|
16
node_modules/react-native/Libraries/Utilities/LoadingView.js
generated
vendored
Normal file
16
node_modules/react-native/Libraries/Utilities/LoadingView.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
showMessage(message: string, type: 'load' | 'refresh') {},
|
||||
hide() {},
|
||||
};
|
748
node_modules/react-native/Libraries/Utilities/MatrixMath.js
generated
vendored
Executable file
748
node_modules/react-native/Libraries/Utilities/MatrixMath.js
generated
vendored
Executable file
@ -0,0 +1,748 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @noflow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
/**
|
||||
* Memory conservative (mutative) matrix math utilities. Uses "command"
|
||||
* matrices, which are reusable.
|
||||
*/
|
||||
const MatrixMath = {
|
||||
createIdentityMatrix: function() {
|
||||
return [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
|
||||
},
|
||||
|
||||
createCopy: function(m) {
|
||||
return [
|
||||
m[0],
|
||||
m[1],
|
||||
m[2],
|
||||
m[3],
|
||||
m[4],
|
||||
m[5],
|
||||
m[6],
|
||||
m[7],
|
||||
m[8],
|
||||
m[9],
|
||||
m[10],
|
||||
m[11],
|
||||
m[12],
|
||||
m[13],
|
||||
m[14],
|
||||
m[15],
|
||||
];
|
||||
},
|
||||
|
||||
createOrthographic: function(left, right, bottom, top, near, far) {
|
||||
const a = 2 / (right - left);
|
||||
const b = 2 / (top - bottom);
|
||||
const c = -2 / (far - near);
|
||||
|
||||
const tx = -(right + left) / (right - left);
|
||||
const ty = -(top + bottom) / (top - bottom);
|
||||
const tz = -(far + near) / (far - near);
|
||||
|
||||
return [a, 0, 0, 0, 0, b, 0, 0, 0, 0, c, 0, tx, ty, tz, 1];
|
||||
},
|
||||
|
||||
createFrustum: function(left, right, bottom, top, near, far) {
|
||||
const r_width = 1 / (right - left);
|
||||
const r_height = 1 / (top - bottom);
|
||||
const r_depth = 1 / (near - far);
|
||||
const x = 2 * (near * r_width);
|
||||
const y = 2 * (near * r_height);
|
||||
const A = (right + left) * r_width;
|
||||
const B = (top + bottom) * r_height;
|
||||
const C = (far + near) * r_depth;
|
||||
const D = 2 * (far * near * r_depth);
|
||||
return [x, 0, 0, 0, 0, y, 0, 0, A, B, C, -1, 0, 0, D, 0];
|
||||
},
|
||||
|
||||
/**
|
||||
* This create a perspective projection towards negative z
|
||||
* Clipping the z range of [-near, -far]
|
||||
*
|
||||
* @param fovInRadians - field of view in randians
|
||||
*/
|
||||
createPerspective: function(fovInRadians, aspect, near, far) {
|
||||
const h = 1 / Math.tan(fovInRadians / 2);
|
||||
const r_depth = 1 / (near - far);
|
||||
const C = (far + near) * r_depth;
|
||||
const D = 2 * (far * near * r_depth);
|
||||
return [h / aspect, 0, 0, 0, 0, h, 0, 0, 0, 0, C, -1, 0, 0, D, 0];
|
||||
},
|
||||
|
||||
createTranslate2d: function(x, y) {
|
||||
const mat = MatrixMath.createIdentityMatrix();
|
||||
MatrixMath.reuseTranslate2dCommand(mat, x, y);
|
||||
return mat;
|
||||
},
|
||||
|
||||
reuseTranslate2dCommand: function(matrixCommand, x, y) {
|
||||
matrixCommand[12] = x;
|
||||
matrixCommand[13] = y;
|
||||
},
|
||||
|
||||
reuseTranslate3dCommand: function(matrixCommand, x, y, z) {
|
||||
matrixCommand[12] = x;
|
||||
matrixCommand[13] = y;
|
||||
matrixCommand[14] = z;
|
||||
},
|
||||
|
||||
createScale: function(factor) {
|
||||
const mat = MatrixMath.createIdentityMatrix();
|
||||
MatrixMath.reuseScaleCommand(mat, factor);
|
||||
return mat;
|
||||
},
|
||||
|
||||
reuseScaleCommand: function(matrixCommand, factor) {
|
||||
matrixCommand[0] = factor;
|
||||
matrixCommand[5] = factor;
|
||||
},
|
||||
|
||||
reuseScale3dCommand: function(matrixCommand, x, y, z) {
|
||||
matrixCommand[0] = x;
|
||||
matrixCommand[5] = y;
|
||||
matrixCommand[10] = z;
|
||||
},
|
||||
|
||||
reusePerspectiveCommand: function(matrixCommand, p) {
|
||||
matrixCommand[11] = -1 / p;
|
||||
},
|
||||
|
||||
reuseScaleXCommand(matrixCommand, factor) {
|
||||
matrixCommand[0] = factor;
|
||||
},
|
||||
|
||||
reuseScaleYCommand(matrixCommand, factor) {
|
||||
matrixCommand[5] = factor;
|
||||
},
|
||||
|
||||
reuseScaleZCommand(matrixCommand, factor) {
|
||||
matrixCommand[10] = factor;
|
||||
},
|
||||
|
||||
reuseRotateXCommand: function(matrixCommand, radians) {
|
||||
matrixCommand[5] = Math.cos(radians);
|
||||
matrixCommand[6] = Math.sin(radians);
|
||||
matrixCommand[9] = -Math.sin(radians);
|
||||
matrixCommand[10] = Math.cos(radians);
|
||||
},
|
||||
|
||||
reuseRotateYCommand: function(matrixCommand, amount) {
|
||||
matrixCommand[0] = Math.cos(amount);
|
||||
matrixCommand[2] = -Math.sin(amount);
|
||||
matrixCommand[8] = Math.sin(amount);
|
||||
matrixCommand[10] = Math.cos(amount);
|
||||
},
|
||||
|
||||
// http://www.w3.org/TR/css3-transforms/#recomposing-to-a-2d-matrix
|
||||
reuseRotateZCommand: function(matrixCommand, radians) {
|
||||
matrixCommand[0] = Math.cos(radians);
|
||||
matrixCommand[1] = Math.sin(radians);
|
||||
matrixCommand[4] = -Math.sin(radians);
|
||||
matrixCommand[5] = Math.cos(radians);
|
||||
},
|
||||
|
||||
createRotateZ: function(radians) {
|
||||
const mat = MatrixMath.createIdentityMatrix();
|
||||
MatrixMath.reuseRotateZCommand(mat, radians);
|
||||
return mat;
|
||||
},
|
||||
|
||||
reuseSkewXCommand: function(matrixCommand, radians) {
|
||||
matrixCommand[4] = Math.tan(radians);
|
||||
},
|
||||
|
||||
reuseSkewYCommand: function(matrixCommand, radians) {
|
||||
matrixCommand[1] = Math.tan(radians);
|
||||
},
|
||||
|
||||
multiplyInto: function(out, a, b) {
|
||||
const a00 = a[0],
|
||||
a01 = a[1],
|
||||
a02 = a[2],
|
||||
a03 = a[3],
|
||||
a10 = a[4],
|
||||
a11 = a[5],
|
||||
a12 = a[6],
|
||||
a13 = a[7],
|
||||
a20 = a[8],
|
||||
a21 = a[9],
|
||||
a22 = a[10],
|
||||
a23 = a[11],
|
||||
a30 = a[12],
|
||||
a31 = a[13],
|
||||
a32 = a[14],
|
||||
a33 = a[15];
|
||||
|
||||
let b0 = b[0],
|
||||
b1 = b[1],
|
||||
b2 = b[2],
|
||||
b3 = b[3];
|
||||
out[0] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
||||
out[1] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
||||
out[2] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
||||
out[3] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
||||
|
||||
b0 = b[4];
|
||||
b1 = b[5];
|
||||
b2 = b[6];
|
||||
b3 = b[7];
|
||||
out[4] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
||||
out[5] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
||||
out[6] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
||||
out[7] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
||||
|
||||
b0 = b[8];
|
||||
b1 = b[9];
|
||||
b2 = b[10];
|
||||
b3 = b[11];
|
||||
out[8] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
||||
out[9] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
||||
out[10] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
||||
out[11] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
||||
|
||||
b0 = b[12];
|
||||
b1 = b[13];
|
||||
b2 = b[14];
|
||||
b3 = b[15];
|
||||
out[12] = b0 * a00 + b1 * a10 + b2 * a20 + b3 * a30;
|
||||
out[13] = b0 * a01 + b1 * a11 + b2 * a21 + b3 * a31;
|
||||
out[14] = b0 * a02 + b1 * a12 + b2 * a22 + b3 * a32;
|
||||
out[15] = b0 * a03 + b1 * a13 + b2 * a23 + b3 * a33;
|
||||
},
|
||||
|
||||
determinant(matrix: Array<number>): number {
|
||||
const [
|
||||
m00,
|
||||
m01,
|
||||
m02,
|
||||
m03,
|
||||
m10,
|
||||
m11,
|
||||
m12,
|
||||
m13,
|
||||
m20,
|
||||
m21,
|
||||
m22,
|
||||
m23,
|
||||
m30,
|
||||
m31,
|
||||
m32,
|
||||
m33,
|
||||
] = matrix;
|
||||
return (
|
||||
m03 * m12 * m21 * m30 -
|
||||
m02 * m13 * m21 * m30 -
|
||||
m03 * m11 * m22 * m30 +
|
||||
m01 * m13 * m22 * m30 +
|
||||
m02 * m11 * m23 * m30 -
|
||||
m01 * m12 * m23 * m30 -
|
||||
m03 * m12 * m20 * m31 +
|
||||
m02 * m13 * m20 * m31 +
|
||||
m03 * m10 * m22 * m31 -
|
||||
m00 * m13 * m22 * m31 -
|
||||
m02 * m10 * m23 * m31 +
|
||||
m00 * m12 * m23 * m31 +
|
||||
m03 * m11 * m20 * m32 -
|
||||
m01 * m13 * m20 * m32 -
|
||||
m03 * m10 * m21 * m32 +
|
||||
m00 * m13 * m21 * m32 +
|
||||
m01 * m10 * m23 * m32 -
|
||||
m00 * m11 * m23 * m32 -
|
||||
m02 * m11 * m20 * m33 +
|
||||
m01 * m12 * m20 * m33 +
|
||||
m02 * m10 * m21 * m33 -
|
||||
m00 * m12 * m21 * m33 -
|
||||
m01 * m10 * m22 * m33 +
|
||||
m00 * m11 * m22 * m33
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Inverse of a matrix. Multiplying by the inverse is used in matrix math
|
||||
* instead of division.
|
||||
*
|
||||
* Formula from:
|
||||
* http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.htm
|
||||
*/
|
||||
inverse(matrix: Array<number>): Array<number> {
|
||||
const det = MatrixMath.determinant(matrix);
|
||||
if (!det) {
|
||||
return matrix;
|
||||
}
|
||||
const [
|
||||
m00,
|
||||
m01,
|
||||
m02,
|
||||
m03,
|
||||
m10,
|
||||
m11,
|
||||
m12,
|
||||
m13,
|
||||
m20,
|
||||
m21,
|
||||
m22,
|
||||
m23,
|
||||
m30,
|
||||
m31,
|
||||
m32,
|
||||
m33,
|
||||
] = matrix;
|
||||
return [
|
||||
(m12 * m23 * m31 -
|
||||
m13 * m22 * m31 +
|
||||
m13 * m21 * m32 -
|
||||
m11 * m23 * m32 -
|
||||
m12 * m21 * m33 +
|
||||
m11 * m22 * m33) /
|
||||
det,
|
||||
(m03 * m22 * m31 -
|
||||
m02 * m23 * m31 -
|
||||
m03 * m21 * m32 +
|
||||
m01 * m23 * m32 +
|
||||
m02 * m21 * m33 -
|
||||
m01 * m22 * m33) /
|
||||
det,
|
||||
(m02 * m13 * m31 -
|
||||
m03 * m12 * m31 +
|
||||
m03 * m11 * m32 -
|
||||
m01 * m13 * m32 -
|
||||
m02 * m11 * m33 +
|
||||
m01 * m12 * m33) /
|
||||
det,
|
||||
(m03 * m12 * m21 -
|
||||
m02 * m13 * m21 -
|
||||
m03 * m11 * m22 +
|
||||
m01 * m13 * m22 +
|
||||
m02 * m11 * m23 -
|
||||
m01 * m12 * m23) /
|
||||
det,
|
||||
(m13 * m22 * m30 -
|
||||
m12 * m23 * m30 -
|
||||
m13 * m20 * m32 +
|
||||
m10 * m23 * m32 +
|
||||
m12 * m20 * m33 -
|
||||
m10 * m22 * m33) /
|
||||
det,
|
||||
(m02 * m23 * m30 -
|
||||
m03 * m22 * m30 +
|
||||
m03 * m20 * m32 -
|
||||
m00 * m23 * m32 -
|
||||
m02 * m20 * m33 +
|
||||
m00 * m22 * m33) /
|
||||
det,
|
||||
(m03 * m12 * m30 -
|
||||
m02 * m13 * m30 -
|
||||
m03 * m10 * m32 +
|
||||
m00 * m13 * m32 +
|
||||
m02 * m10 * m33 -
|
||||
m00 * m12 * m33) /
|
||||
det,
|
||||
(m02 * m13 * m20 -
|
||||
m03 * m12 * m20 +
|
||||
m03 * m10 * m22 -
|
||||
m00 * m13 * m22 -
|
||||
m02 * m10 * m23 +
|
||||
m00 * m12 * m23) /
|
||||
det,
|
||||
(m11 * m23 * m30 -
|
||||
m13 * m21 * m30 +
|
||||
m13 * m20 * m31 -
|
||||
m10 * m23 * m31 -
|
||||
m11 * m20 * m33 +
|
||||
m10 * m21 * m33) /
|
||||
det,
|
||||
(m03 * m21 * m30 -
|
||||
m01 * m23 * m30 -
|
||||
m03 * m20 * m31 +
|
||||
m00 * m23 * m31 +
|
||||
m01 * m20 * m33 -
|
||||
m00 * m21 * m33) /
|
||||
det,
|
||||
(m01 * m13 * m30 -
|
||||
m03 * m11 * m30 +
|
||||
m03 * m10 * m31 -
|
||||
m00 * m13 * m31 -
|
||||
m01 * m10 * m33 +
|
||||
m00 * m11 * m33) /
|
||||
det,
|
||||
(m03 * m11 * m20 -
|
||||
m01 * m13 * m20 -
|
||||
m03 * m10 * m21 +
|
||||
m00 * m13 * m21 +
|
||||
m01 * m10 * m23 -
|
||||
m00 * m11 * m23) /
|
||||
det,
|
||||
(m12 * m21 * m30 -
|
||||
m11 * m22 * m30 -
|
||||
m12 * m20 * m31 +
|
||||
m10 * m22 * m31 +
|
||||
m11 * m20 * m32 -
|
||||
m10 * m21 * m32) /
|
||||
det,
|
||||
(m01 * m22 * m30 -
|
||||
m02 * m21 * m30 +
|
||||
m02 * m20 * m31 -
|
||||
m00 * m22 * m31 -
|
||||
m01 * m20 * m32 +
|
||||
m00 * m21 * m32) /
|
||||
det,
|
||||
(m02 * m11 * m30 -
|
||||
m01 * m12 * m30 -
|
||||
m02 * m10 * m31 +
|
||||
m00 * m12 * m31 +
|
||||
m01 * m10 * m32 -
|
||||
m00 * m11 * m32) /
|
||||
det,
|
||||
(m01 * m12 * m20 -
|
||||
m02 * m11 * m20 +
|
||||
m02 * m10 * m21 -
|
||||
m00 * m12 * m21 -
|
||||
m01 * m10 * m22 +
|
||||
m00 * m11 * m22) /
|
||||
det,
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* Turns columns into rows and rows into columns.
|
||||
*/
|
||||
transpose(m: Array<number>): Array<number> {
|
||||
return [
|
||||
m[0],
|
||||
m[4],
|
||||
m[8],
|
||||
m[12],
|
||||
m[1],
|
||||
m[5],
|
||||
m[9],
|
||||
m[13],
|
||||
m[2],
|
||||
m[6],
|
||||
m[10],
|
||||
m[14],
|
||||
m[3],
|
||||
m[7],
|
||||
m[11],
|
||||
m[15],
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* Based on: http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
|
||||
*/
|
||||
multiplyVectorByMatrix(v: Array<number>, m: Array<number>): Array<number> {
|
||||
const [vx, vy, vz, vw] = v;
|
||||
return [
|
||||
vx * m[0] + vy * m[4] + vz * m[8] + vw * m[12],
|
||||
vx * m[1] + vy * m[5] + vz * m[9] + vw * m[13],
|
||||
vx * m[2] + vy * m[6] + vz * m[10] + vw * m[14],
|
||||
vx * m[3] + vy * m[7] + vz * m[11] + vw * m[15],
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* From: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
|
||||
*/
|
||||
v3Length(a: Array<number>): number {
|
||||
return Math.sqrt(a[0] * a[0] + a[1] * a[1] + a[2] * a[2]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Based on: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
|
||||
*/
|
||||
v3Normalize(vector: Array<number>, v3Length: number): Array<number> {
|
||||
const im = 1 / (v3Length || MatrixMath.v3Length(vector));
|
||||
return [vector[0] * im, vector[1] * im, vector[2] * im];
|
||||
},
|
||||
|
||||
/**
|
||||
* The dot product of a and b, two 3-element vectors.
|
||||
* From: https://code.google.com/p/webgl-mjs/source/browse/mjs.js
|
||||
*/
|
||||
v3Dot(a, b) {
|
||||
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
||||
},
|
||||
|
||||
/**
|
||||
* From:
|
||||
* http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
|
||||
*/
|
||||
v3Combine(
|
||||
a: Array<number>,
|
||||
b: Array<number>,
|
||||
aScale: number,
|
||||
bScale: number,
|
||||
): Array<number> {
|
||||
return [
|
||||
aScale * a[0] + bScale * b[0],
|
||||
aScale * a[1] + bScale * b[1],
|
||||
aScale * a[2] + bScale * b[2],
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* From:
|
||||
* http://www.opensource.apple.com/source/WebCore/WebCore-514/platform/graphics/transforms/TransformationMatrix.cpp
|
||||
*/
|
||||
v3Cross(a: Array<number>, b: Array<number>): Array<number> {
|
||||
return [
|
||||
a[1] * b[2] - a[2] * b[1],
|
||||
a[2] * b[0] - a[0] * b[2],
|
||||
a[0] * b[1] - a[1] * b[0],
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* Based on:
|
||||
* http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
|
||||
* and:
|
||||
* http://quat.zachbennett.com/
|
||||
*
|
||||
* Note that this rounds degrees to the thousandth of a degree, due to
|
||||
* floating point errors in the creation of the quaternion.
|
||||
*
|
||||
* Also note that this expects the qw value to be last, not first.
|
||||
*
|
||||
* Also, when researching this, remember that:
|
||||
* yaw === heading === z-axis
|
||||
* pitch === elevation/attitude === y-axis
|
||||
* roll === bank === x-axis
|
||||
*/
|
||||
quaternionToDegreesXYZ(q: Array<number>, matrix, row): Array<number> {
|
||||
const [qx, qy, qz, qw] = q;
|
||||
const qw2 = qw * qw;
|
||||
const qx2 = qx * qx;
|
||||
const qy2 = qy * qy;
|
||||
const qz2 = qz * qz;
|
||||
const test = qx * qy + qz * qw;
|
||||
const unit = qw2 + qx2 + qy2 + qz2;
|
||||
const conv = 180 / Math.PI;
|
||||
|
||||
if (test > 0.49999 * unit) {
|
||||
return [0, 2 * Math.atan2(qx, qw) * conv, 90];
|
||||
}
|
||||
if (test < -0.49999 * unit) {
|
||||
return [0, -2 * Math.atan2(qx, qw) * conv, -90];
|
||||
}
|
||||
|
||||
return [
|
||||
MatrixMath.roundTo3Places(
|
||||
Math.atan2(2 * qx * qw - 2 * qy * qz, 1 - 2 * qx2 - 2 * qz2) * conv,
|
||||
),
|
||||
MatrixMath.roundTo3Places(
|
||||
Math.atan2(2 * qy * qw - 2 * qx * qz, 1 - 2 * qy2 - 2 * qz2) * conv,
|
||||
),
|
||||
MatrixMath.roundTo3Places(Math.asin(2 * qx * qy + 2 * qz * qw) * conv),
|
||||
];
|
||||
},
|
||||
|
||||
/**
|
||||
* Based on:
|
||||
* https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
|
||||
*/
|
||||
roundTo3Places(n: number): number {
|
||||
const arr = n.toString().split('e');
|
||||
return Math.round(arr[0] + 'e' + (arr[1] ? +arr[1] - 3 : 3)) * 0.001;
|
||||
},
|
||||
|
||||
/**
|
||||
* Decompose a matrix into separate transform values, for use on platforms
|
||||
* where applying a precomposed matrix is not possible, and transforms are
|
||||
* applied in an inflexible ordering (e.g. Android).
|
||||
*
|
||||
* Implementation based on
|
||||
* http://www.w3.org/TR/css3-transforms/#decomposing-a-2d-matrix
|
||||
* http://www.w3.org/TR/css3-transforms/#decomposing-a-3d-matrix
|
||||
* which was based on
|
||||
* http://tog.acm.org/resources/GraphicsGems/gemsii/unmatrix.c
|
||||
*/
|
||||
decomposeMatrix(transformMatrix: Array<number>): ?Object {
|
||||
invariant(
|
||||
transformMatrix.length === 16,
|
||||
'Matrix decomposition needs a list of 3d matrix values, received %s',
|
||||
transformMatrix,
|
||||
);
|
||||
|
||||
// output values
|
||||
let perspective = [];
|
||||
const quaternion = [];
|
||||
const scale = [];
|
||||
const skew = [];
|
||||
const translation = [];
|
||||
|
||||
// create normalized, 2d array matrix
|
||||
// and normalized 1d array perspectiveMatrix with redefined 4th column
|
||||
if (!transformMatrix[15]) {
|
||||
return;
|
||||
}
|
||||
const matrix = [];
|
||||
const perspectiveMatrix = [];
|
||||
for (let i = 0; i < 4; i++) {
|
||||
matrix.push([]);
|
||||
for (let j = 0; j < 4; j++) {
|
||||
const value = transformMatrix[i * 4 + j] / transformMatrix[15];
|
||||
matrix[i].push(value);
|
||||
perspectiveMatrix.push(j === 3 ? 0 : value);
|
||||
}
|
||||
}
|
||||
perspectiveMatrix[15] = 1;
|
||||
|
||||
// test for singularity of upper 3x3 part of the perspective matrix
|
||||
if (!MatrixMath.determinant(perspectiveMatrix)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// isolate perspective
|
||||
if (matrix[0][3] !== 0 || matrix[1][3] !== 0 || matrix[2][3] !== 0) {
|
||||
// rightHandSide is the right hand side of the equation.
|
||||
// rightHandSide is a vector, or point in 3d space relative to the origin.
|
||||
const rightHandSide = [
|
||||
matrix[0][3],
|
||||
matrix[1][3],
|
||||
matrix[2][3],
|
||||
matrix[3][3],
|
||||
];
|
||||
|
||||
// Solve the equation by inverting perspectiveMatrix and multiplying
|
||||
// rightHandSide by the inverse.
|
||||
const inversePerspectiveMatrix = MatrixMath.inverse(perspectiveMatrix);
|
||||
const transposedInversePerspectiveMatrix = MatrixMath.transpose(
|
||||
inversePerspectiveMatrix,
|
||||
);
|
||||
perspective = MatrixMath.multiplyVectorByMatrix(
|
||||
rightHandSide,
|
||||
transposedInversePerspectiveMatrix,
|
||||
);
|
||||
} else {
|
||||
// no perspective
|
||||
perspective[0] = perspective[1] = perspective[2] = 0;
|
||||
perspective[3] = 1;
|
||||
}
|
||||
|
||||
// translation is simple
|
||||
for (let i = 0; i < 3; i++) {
|
||||
translation[i] = matrix[3][i];
|
||||
}
|
||||
|
||||
// Now get scale and shear.
|
||||
// 'row' is a 3 element array of 3 component vectors
|
||||
const row = [];
|
||||
for (let i = 0; i < 3; i++) {
|
||||
row[i] = [matrix[i][0], matrix[i][1], matrix[i][2]];
|
||||
}
|
||||
|
||||
// Compute X scale factor and normalize first row.
|
||||
scale[0] = MatrixMath.v3Length(row[0]);
|
||||
row[0] = MatrixMath.v3Normalize(row[0], scale[0]);
|
||||
|
||||
// Compute XY shear factor and make 2nd row orthogonal to 1st.
|
||||
skew[0] = MatrixMath.v3Dot(row[0], row[1]);
|
||||
row[1] = MatrixMath.v3Combine(row[1], row[0], 1.0, -skew[0]);
|
||||
|
||||
// Now, compute Y scale and normalize 2nd row.
|
||||
scale[1] = MatrixMath.v3Length(row[1]);
|
||||
row[1] = MatrixMath.v3Normalize(row[1], scale[1]);
|
||||
skew[0] /= scale[1];
|
||||
|
||||
// Compute XZ and YZ shears, orthogonalize 3rd row
|
||||
skew[1] = MatrixMath.v3Dot(row[0], row[2]);
|
||||
row[2] = MatrixMath.v3Combine(row[2], row[0], 1.0, -skew[1]);
|
||||
skew[2] = MatrixMath.v3Dot(row[1], row[2]);
|
||||
row[2] = MatrixMath.v3Combine(row[2], row[1], 1.0, -skew[2]);
|
||||
|
||||
// Next, get Z scale and normalize 3rd row.
|
||||
scale[2] = MatrixMath.v3Length(row[2]);
|
||||
row[2] = MatrixMath.v3Normalize(row[2], scale[2]);
|
||||
skew[1] /= scale[2];
|
||||
skew[2] /= scale[2];
|
||||
|
||||
// At this point, the matrix (in rows) is orthonormal.
|
||||
// Check for a coordinate system flip. If the determinant
|
||||
// is -1, then negate the matrix and the scaling factors.
|
||||
const pdum3 = MatrixMath.v3Cross(row[1], row[2]);
|
||||
if (MatrixMath.v3Dot(row[0], pdum3) < 0) {
|
||||
for (let i = 0; i < 3; i++) {
|
||||
scale[i] *= -1;
|
||||
row[i][0] *= -1;
|
||||
row[i][1] *= -1;
|
||||
row[i][2] *= -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Now, get the rotations out
|
||||
quaternion[0] =
|
||||
0.5 * Math.sqrt(Math.max(1 + row[0][0] - row[1][1] - row[2][2], 0));
|
||||
quaternion[1] =
|
||||
0.5 * Math.sqrt(Math.max(1 - row[0][0] + row[1][1] - row[2][2], 0));
|
||||
quaternion[2] =
|
||||
0.5 * Math.sqrt(Math.max(1 - row[0][0] - row[1][1] + row[2][2], 0));
|
||||
quaternion[3] =
|
||||
0.5 * Math.sqrt(Math.max(1 + row[0][0] + row[1][1] + row[2][2], 0));
|
||||
|
||||
if (row[2][1] > row[1][2]) {
|
||||
quaternion[0] = -quaternion[0];
|
||||
}
|
||||
if (row[0][2] > row[2][0]) {
|
||||
quaternion[1] = -quaternion[1];
|
||||
}
|
||||
if (row[1][0] > row[0][1]) {
|
||||
quaternion[2] = -quaternion[2];
|
||||
}
|
||||
|
||||
// correct for occasional, weird Euler synonyms for 2d rotation
|
||||
let rotationDegrees;
|
||||
if (
|
||||
quaternion[0] < 0.001 &&
|
||||
quaternion[0] >= 0 &&
|
||||
quaternion[1] < 0.001 &&
|
||||
quaternion[1] >= 0
|
||||
) {
|
||||
// this is a 2d rotation on the z-axis
|
||||
rotationDegrees = [
|
||||
0,
|
||||
0,
|
||||
MatrixMath.roundTo3Places(
|
||||
(Math.atan2(row[0][1], row[0][0]) * 180) / Math.PI,
|
||||
),
|
||||
];
|
||||
} else {
|
||||
rotationDegrees = MatrixMath.quaternionToDegreesXYZ(
|
||||
quaternion,
|
||||
matrix,
|
||||
row,
|
||||
);
|
||||
}
|
||||
|
||||
// expose both base data and convenience names
|
||||
return {
|
||||
rotationDegrees,
|
||||
perspective,
|
||||
quaternion,
|
||||
scale,
|
||||
skew,
|
||||
translation,
|
||||
|
||||
rotate: rotationDegrees[2],
|
||||
rotateX: rotationDegrees[0],
|
||||
rotateY: rotationDegrees[1],
|
||||
scaleX: scale[0],
|
||||
scaleY: scale[1],
|
||||
translateX: translation[0],
|
||||
translateY: translation[1],
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = MatrixMath;
|
36
node_modules/react-native/Libraries/Utilities/NativeAppearance.js
generated
vendored
Normal file
36
node_modules/react-native/Libraries/Utilities/NativeAppearance.js
generated
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export type ColorSchemeName = 'light' | 'dark';
|
||||
|
||||
export type AppearancePreferences = {|
|
||||
// TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
|
||||
// types.
|
||||
/* 'light' | 'dark' */
|
||||
colorScheme?: ?string,
|
||||
|};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
// TODO: (hramos) T52919652 Use ?ColorSchemeName once codegen supports union
|
||||
// types.
|
||||
/* 'light' | 'dark' */
|
||||
+getColorScheme: () => ?string;
|
||||
|
||||
// RCTEventEmitter
|
||||
+addListener: (eventName: string) => void;
|
||||
+removeListeners: (count: number) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('Appearance'): ?Spec);
|
25
node_modules/react-native/Libraries/Utilities/NativeDevLoadingView.js
generated
vendored
Normal file
25
node_modules/react-native/Libraries/Utilities/NativeDevLoadingView.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+showMessage: (
|
||||
message: string,
|
||||
withColor: ?number,
|
||||
withBackgroundColor: ?number,
|
||||
) => void;
|
||||
+hide: () => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('DevLoadingView'): ?Spec);
|
49
node_modules/react-native/Libraries/Utilities/NativeDeviceInfo.js
generated
vendored
Normal file
49
node_modules/react-native/Libraries/Utilities/NativeDeviceInfo.js
generated
vendored
Normal file
@ -0,0 +1,49 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
type DisplayMetricsAndroid = {|
|
||||
width: number,
|
||||
height: number,
|
||||
scale: number,
|
||||
fontScale: number,
|
||||
densityDpi: number,
|
||||
|};
|
||||
|
||||
export type DisplayMetrics = {|
|
||||
width: number,
|
||||
height: number,
|
||||
scale: number,
|
||||
fontScale: number,
|
||||
|};
|
||||
|
||||
export type DimensionsPayload = {|
|
||||
window?: DisplayMetrics,
|
||||
screen?: DisplayMetrics,
|
||||
windowPhysicalPixels?: DisplayMetricsAndroid,
|
||||
screenPhysicalPixels?: DisplayMetricsAndroid,
|
||||
|};
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getConstants: () => {|
|
||||
+Dimensions: DimensionsPayload,
|
||||
+isIPhoneX_deprecated?: boolean,
|
||||
|};
|
||||
}
|
||||
|
||||
const NativeModule: Spec = TurboModuleRegistry.getEnforcing<Spec>('DeviceInfo');
|
||||
|
||||
const NativeDeviceInfo = NativeModule;
|
||||
|
||||
export default NativeDeviceInfo;
|
25
node_modules/react-native/Libraries/Utilities/NativeJSDevSupport.js
generated
vendored
Normal file
25
node_modules/react-native/Libraries/Utilities/NativeJSDevSupport.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getConstants: () => {|
|
||||
ERROR_CODE_EXCEPTION: number,
|
||||
ERROR_CODE_VIEW_NOT_FOUND: number,
|
||||
|};
|
||||
+onSuccess: (data: string) => void;
|
||||
+onFailure: (errorCode: number, error: string) => void;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.get<Spec>('JSDevSupport'): ?Spec);
|
38
node_modules/react-native/Libraries/Utilities/NativePlatformConstantsAndroid.js
generated
vendored
Normal file
38
node_modules/react-native/Libraries/Utilities/NativePlatformConstantsAndroid.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getConstants: () => {|
|
||||
isTesting: boolean,
|
||||
reactNativeVersion: {|
|
||||
major: number,
|
||||
minor: number,
|
||||
patch: number,
|
||||
prerelease: ?number,
|
||||
|},
|
||||
Version: number,
|
||||
Release: string,
|
||||
Serial: string,
|
||||
Fingerprint: string,
|
||||
Model: string,
|
||||
ServerHost?: string,
|
||||
uiMode: string,
|
||||
|};
|
||||
+getAndroidID: () => string;
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.getEnforcing<Spec>(
|
||||
'PlatformConstants',
|
||||
): Spec);
|
34
node_modules/react-native/Libraries/Utilities/NativePlatformConstantsIOS.js
generated
vendored
Normal file
34
node_modules/react-native/Libraries/Utilities/NativePlatformConstantsIOS.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {TurboModule} from '../TurboModule/RCTExport';
|
||||
import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry';
|
||||
|
||||
export interface Spec extends TurboModule {
|
||||
+getConstants: () => {|
|
||||
isTesting: boolean,
|
||||
reactNativeVersion: {|
|
||||
major: number,
|
||||
minor: number,
|
||||
patch: number,
|
||||
prerelease: ?number,
|
||||
|},
|
||||
forceTouchAvailable: boolean,
|
||||
osVersion: string,
|
||||
systemName: string,
|
||||
interfaceIdiom: string,
|
||||
|};
|
||||
}
|
||||
|
||||
export default (TurboModuleRegistry.getEnforcing<Spec>(
|
||||
'PlatformConstants',
|
||||
): Spec);
|
26
node_modules/react-native/Libraries/Utilities/PerformanceLoggerContext.js
generated
vendored
Normal file
26
node_modules/react-native/Libraries/Utilities/PerformanceLoggerContext.js
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import * as React from 'react';
|
||||
import GlobalPerformanceLogger from './GlobalPerformanceLogger';
|
||||
import type {IPerformanceLogger} from './createPerformanceLogger';
|
||||
|
||||
/**
|
||||
* This is a React Context that provides a scoped instance of IPerformanceLogger.
|
||||
* We wrap every <AppContainer /> with a Provider for this context so the logger
|
||||
* should be available in every component.
|
||||
* See React docs about using Context: https://reactjs.org/docs/context.html
|
||||
*/
|
||||
const PerformanceLoggerContext: React.Context<IPerformanceLogger> = React.createContext(
|
||||
GlobalPerformanceLogger,
|
||||
);
|
||||
module.exports = PerformanceLoggerContext;
|
127
node_modules/react-native/Libraries/Utilities/PixelRatio.js
generated
vendored
Normal file
127
node_modules/react-native/Libraries/Utilities/PixelRatio.js
generated
vendored
Normal file
@ -0,0 +1,127 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const Dimensions = require('./Dimensions');
|
||||
|
||||
/**
|
||||
* PixelRatio class gives access to the device pixel density.
|
||||
*
|
||||
* ## Fetching a correctly sized image
|
||||
*
|
||||
* You should get a higher resolution image if you are on a high pixel density
|
||||
* device. A good rule of thumb is to multiply the size of the image you display
|
||||
* by the pixel ratio.
|
||||
*
|
||||
* ```
|
||||
* var image = getImage({
|
||||
* width: PixelRatio.getPixelSizeForLayoutSize(200),
|
||||
* height: PixelRatio.getPixelSizeForLayoutSize(100),
|
||||
* });
|
||||
* <Image source={image} style={{width: 200, height: 100}} />
|
||||
* ```
|
||||
*
|
||||
* ## Pixel grid snapping
|
||||
*
|
||||
* In iOS, you can specify positions and dimensions for elements with arbitrary
|
||||
* precision, for example 29.674825. But, ultimately the physical display only
|
||||
* have a fixed number of pixels, for example 640×960 for iPhone 4 or 750×1334
|
||||
* for iPhone 6. iOS tries to be as faithful as possible to the user value by
|
||||
* spreading one original pixel into multiple ones to trick the eye. The
|
||||
* downside of this technique is that it makes the resulting element look
|
||||
* blurry.
|
||||
*
|
||||
* In practice, we found out that developers do not want this feature and they
|
||||
* have to work around it by doing manual rounding in order to avoid having
|
||||
* blurry elements. In React Native, we are rounding all the pixels
|
||||
* automatically.
|
||||
*
|
||||
* We have to be careful when to do this rounding. You never want to work with
|
||||
* rounded and unrounded values at the same time as you're going to accumulate
|
||||
* rounding errors. Having even one rounding error is deadly because a one
|
||||
* pixel border may vanish or be twice as big.
|
||||
*
|
||||
* In React Native, everything in JavaScript and within the layout engine works
|
||||
* with arbitrary precision numbers. It's only when we set the position and
|
||||
* dimensions of the native element on the main thread that we round. Also,
|
||||
* rounding is done relative to the root rather than the parent, again to avoid
|
||||
* accumulating rounding errors.
|
||||
*
|
||||
*/
|
||||
class PixelRatio {
|
||||
/**
|
||||
* Returns the device pixel density. Some examples:
|
||||
*
|
||||
* - PixelRatio.get() === 1
|
||||
* - mdpi Android devices (160 dpi)
|
||||
* - PixelRatio.get() === 1.5
|
||||
* - hdpi Android devices (240 dpi)
|
||||
* - PixelRatio.get() === 2
|
||||
* - iPhone 4, 4S
|
||||
* - iPhone 5, 5c, 5s
|
||||
* - iPhone 6
|
||||
* - iPhone 7
|
||||
* - iPhone 8
|
||||
* - iPhone SE
|
||||
* - xhdpi Android devices (320 dpi)
|
||||
* - PixelRatio.get() === 3
|
||||
* - iPhone 6 Plus
|
||||
* - iPhone 7 Plus
|
||||
* - iPhone 8 Plus
|
||||
* - iPhone X
|
||||
* - xxhdpi Android devices (480 dpi)
|
||||
* - PixelRatio.get() === 3.5
|
||||
* - Nexus 6
|
||||
*/
|
||||
static get(): number {
|
||||
return Dimensions.get('window').scale;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scaling factor for font sizes. This is the ratio that is used to calculate the
|
||||
* absolute font size, so any elements that heavily depend on that should use this to do
|
||||
* calculations.
|
||||
*
|
||||
* If a font scale is not set, this returns the device pixel ratio.
|
||||
*
|
||||
* This reflects the user preference set in:
|
||||
* - Settings > Display > Font size on Android,
|
||||
* - Settings > Display & Brightness > Text Size on iOS.
|
||||
*/
|
||||
static getFontScale(): number {
|
||||
return Dimensions.get('window').fontScale || PixelRatio.get();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a layout size (dp) to pixel size (px).
|
||||
*
|
||||
* Guaranteed to return an integer number.
|
||||
*/
|
||||
static getPixelSizeForLayoutSize(layoutSize: number): number {
|
||||
return Math.round(layoutSize * PixelRatio.get());
|
||||
}
|
||||
|
||||
/**
|
||||
* Rounds a layout size (dp) to the nearest layout size that corresponds to
|
||||
* an integer number of pixels. For example, on a device with a PixelRatio
|
||||
* of 3, `PixelRatio.roundToNearestPixel(8.4) = 8.33`, which corresponds to
|
||||
* exactly (8.33 * 3) = 25 pixels.
|
||||
*/
|
||||
static roundToNearestPixel(layoutSize: number): number {
|
||||
const ratio = PixelRatio.get();
|
||||
return Math.round(layoutSize * ratio) / ratio;
|
||||
}
|
||||
|
||||
// No-op for iOS, but used on the web. Should not be documented.
|
||||
static startDetecting() {}
|
||||
}
|
||||
|
||||
module.exports = PixelRatio;
|
66
node_modules/react-native/Libraries/Utilities/Platform.android.js
generated
vendored
Normal file
66
node_modules/react-native/Libraries/Utilities/Platform.android.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import NativePlatformConstantsAndroid from './NativePlatformConstantsAndroid';
|
||||
|
||||
export type PlatformSelectSpec<A, N, D> = {
|
||||
android?: A,
|
||||
native?: N,
|
||||
default?: D,
|
||||
...
|
||||
};
|
||||
|
||||
const Platform = {
|
||||
__constants: null,
|
||||
OS: 'android',
|
||||
get Version(): number {
|
||||
return this.constants.Version;
|
||||
},
|
||||
get constants(): {|
|
||||
isTesting: boolean,
|
||||
reactNativeVersion: {|
|
||||
major: number,
|
||||
minor: number,
|
||||
patch: number,
|
||||
prerelease: ?number,
|
||||
|},
|
||||
Version: number,
|
||||
Release: string,
|
||||
Serial: string,
|
||||
Fingerprint: string,
|
||||
Model: string,
|
||||
ServerHost?: string,
|
||||
uiMode: string,
|
||||
|} {
|
||||
if (this.__constants == null) {
|
||||
this.__constants = NativePlatformConstantsAndroid.getConstants();
|
||||
}
|
||||
return this.__constants;
|
||||
},
|
||||
get isTesting(): boolean {
|
||||
if (__DEV__) {
|
||||
return this.constants.isTesting;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
get isTV(): boolean {
|
||||
return this.constants.uiMode === 'tv';
|
||||
},
|
||||
select: <A, N, D>(spec: PlatformSelectSpec<A, N, D>): A | N | D =>
|
||||
'android' in spec
|
||||
? spec.android
|
||||
: 'native' in spec
|
||||
? spec.native
|
||||
: spec.default,
|
||||
};
|
||||
|
||||
module.exports = Platform;
|
68
node_modules/react-native/Libraries/Utilities/Platform.ios.js
generated
vendored
Normal file
68
node_modules/react-native/Libraries/Utilities/Platform.ios.js
generated
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import NativePlatformConstantsIOS from './NativePlatformConstantsIOS';
|
||||
|
||||
export type PlatformSelectSpec<D, N, I> = {
|
||||
default?: D,
|
||||
native?: N,
|
||||
ios?: I,
|
||||
...
|
||||
};
|
||||
|
||||
const Platform = {
|
||||
__constants: null,
|
||||
OS: 'ios',
|
||||
get Version(): string {
|
||||
return this.constants.osVersion;
|
||||
},
|
||||
get constants(): {|
|
||||
forceTouchAvailable: boolean,
|
||||
interfaceIdiom: string,
|
||||
isTesting: boolean,
|
||||
osVersion: string,
|
||||
reactNativeVersion: {|
|
||||
major: number,
|
||||
minor: number,
|
||||
patch: number,
|
||||
prerelease: ?number,
|
||||
|},
|
||||
systemName: string,
|
||||
|} {
|
||||
if (this.__constants == null) {
|
||||
this.__constants = NativePlatformConstantsIOS.getConstants();
|
||||
}
|
||||
return this.__constants;
|
||||
},
|
||||
get isPad(): boolean {
|
||||
return this.constants.interfaceIdiom === 'pad';
|
||||
},
|
||||
/**
|
||||
* Deprecated, use `isTV` instead.
|
||||
*/
|
||||
get isTVOS(): boolean {
|
||||
return Platform.isTV;
|
||||
},
|
||||
get isTV(): boolean {
|
||||
return this.constants.interfaceIdiom === 'tv';
|
||||
},
|
||||
get isTesting(): boolean {
|
||||
if (__DEV__) {
|
||||
return this.constants.isTesting;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
select: <D, N, I>(spec: PlatformSelectSpec<D, N, I>): D | N | I =>
|
||||
'ios' in spec ? spec.ios : 'native' in spec ? spec.native : spec.default,
|
||||
};
|
||||
|
||||
module.exports = Platform;
|
56
node_modules/react-native/Libraries/Utilities/PolyfillFunctions.js
generated
vendored
Normal file
56
node_modules/react-native/Libraries/Utilities/PolyfillFunctions.js
generated
vendored
Normal file
@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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 defineLazyObjectProperty = require('./defineLazyObjectProperty');
|
||||
|
||||
/**
|
||||
* Sets an object's property. If a property with the same name exists, this will
|
||||
* replace it but maintain its descriptor configuration. The property will be
|
||||
* replaced with a lazy getter.
|
||||
*
|
||||
* In DEV mode the original property value will be preserved as `original[PropertyName]`
|
||||
* so that, if necessary, it can be restored. For example, if you want to route
|
||||
* network requests through DevTools (to trace them):
|
||||
*
|
||||
* global.XMLHttpRequest = global.originalXMLHttpRequest;
|
||||
*
|
||||
* @see https://github.com/facebook/react-native/issues/934
|
||||
*/
|
||||
function polyfillObjectProperty<T>(
|
||||
object: Object,
|
||||
name: string,
|
||||
getValue: () => T,
|
||||
): void {
|
||||
const descriptor = Object.getOwnPropertyDescriptor(object, name);
|
||||
if (__DEV__ && descriptor) {
|
||||
const backupName = `original${name[0].toUpperCase()}${name.substr(1)}`;
|
||||
Object.defineProperty(object, backupName, descriptor);
|
||||
}
|
||||
|
||||
const {enumerable, writable, configurable} = descriptor || {};
|
||||
if (descriptor && !configurable) {
|
||||
console.error('Failed to set polyfill. ' + name + ' is not configurable.');
|
||||
return;
|
||||
}
|
||||
|
||||
defineLazyObjectProperty(object, name, {
|
||||
get: getValue,
|
||||
enumerable: enumerable !== false,
|
||||
writable: writable !== false,
|
||||
});
|
||||
}
|
||||
|
||||
function polyfillGlobal<T>(name: string, getValue: () => T): void {
|
||||
polyfillObjectProperty(global, name, getValue);
|
||||
}
|
||||
|
||||
module.exports = {polyfillObjectProperty, polyfillGlobal};
|
55
node_modules/react-native/Libraries/Utilities/RCTLog.js
generated
vendored
Normal file
55
node_modules/react-native/Libraries/Utilities/RCTLog.js
generated
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const invariant = require('invariant');
|
||||
|
||||
const levelsMap = {
|
||||
log: 'log',
|
||||
info: 'info',
|
||||
warn: 'warn',
|
||||
error: 'error',
|
||||
fatal: 'error',
|
||||
};
|
||||
|
||||
let warningHandler: ?(Array<any>) => void = null;
|
||||
|
||||
const RCTLog = {
|
||||
// level one of log, info, warn, error, mustfix
|
||||
logIfNoNativeHook(level: string, ...args: Array<any>): void {
|
||||
// We already printed in the native console, so only log here if using a js debugger
|
||||
if (typeof global.nativeLoggingHook === 'undefined') {
|
||||
RCTLog.logToConsole(level, ...args);
|
||||
} else {
|
||||
// Report native warnings to LogBox
|
||||
if (warningHandler && level === 'warn') {
|
||||
warningHandler(...args);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// Log to console regardless of nativeLoggingHook
|
||||
logToConsole(level: string, ...args: Array<any>): void {
|
||||
const logFn = levelsMap[level];
|
||||
invariant(
|
||||
logFn,
|
||||
'Level "' + level + '" not one of ' + Object.keys(levelsMap).toString(),
|
||||
);
|
||||
|
||||
console[logFn](...args);
|
||||
},
|
||||
|
||||
setWarningHandler(handler: typeof warningHandler): void {
|
||||
warningHandler = handler;
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = RCTLog;
|
249
node_modules/react-native/Libraries/Utilities/ReactNativeTestTools.js
generated
vendored
Normal file
249
node_modules/react-native/Libraries/Utilities/ReactNativeTestTools.js
generated
vendored
Normal file
@ -0,0 +1,249 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
/* eslint-env jest */
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
|
||||
const ReactTestRenderer = require('react-test-renderer');
|
||||
const ShallowRenderer = require('react-test-renderer/shallow');
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an error
|
||||
* found when Flow v0.122.0 was deployed. To see the error, delete this comment
|
||||
* and run Flow. */
|
||||
const shallowRenderer = new ShallowRenderer();
|
||||
|
||||
import type {ReactTestRenderer as ReactTestRendererType} from 'react-test-renderer';
|
||||
|
||||
export type ReactTestInstance = $PropertyType<ReactTestRendererType, 'root'>;
|
||||
|
||||
export type Predicate = (node: ReactTestInstance) => boolean;
|
||||
|
||||
type $ReturnType<Fn> = $Call<<Ret, A>((...A) => Ret) => Ret, Fn>;
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an error
|
||||
* found when Flow v0.122.0 was deployed. To see the error, delete this comment
|
||||
* and run Flow. */
|
||||
export type ReactTestRendererJSON = $ReturnType<ReactTestRenderer.create.toJSON>;
|
||||
|
||||
const {
|
||||
Switch,
|
||||
Text,
|
||||
TextInput,
|
||||
View,
|
||||
VirtualizedList,
|
||||
} = require('react-native');
|
||||
|
||||
function byClickable(): Predicate {
|
||||
return withMessage(
|
||||
node =>
|
||||
// note: <Text /> lazy-mounts press handlers after the first press,
|
||||
// so this is a workaround for targeting text nodes.
|
||||
(node.type === Text &&
|
||||
node.props &&
|
||||
typeof node.props.onPress === 'function') ||
|
||||
// note: Special casing <Switch /> since it doesn't use touchable
|
||||
(node.type === Switch && node.props && node.props.disabled !== true) ||
|
||||
(node.type === View &&
|
||||
node?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig) ||
|
||||
// HACK: Find components that use `Pressability`.
|
||||
node.instance?.state?.pressability != null ||
|
||||
// TODO: Remove this after deleting `Touchable`.
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.122.0 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
(node.instance &&
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses
|
||||
* an error found when Flow v0.122.0 was deployed. To see the error,
|
||||
* delete this comment and run Flow. */
|
||||
typeof node.instance.touchableHandlePress === 'function'),
|
||||
'is clickable',
|
||||
);
|
||||
}
|
||||
|
||||
function byTestID(testID: string): Predicate {
|
||||
return withMessage(
|
||||
node => node.props && node.props.testID === testID,
|
||||
`testID prop equals ${testID}`,
|
||||
);
|
||||
}
|
||||
|
||||
function byTextMatching(regex: RegExp): Predicate {
|
||||
return withMessage(
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.122.0 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
node => node.props && regex.exec(node.props.children),
|
||||
`text content matches ${regex.toString()}`,
|
||||
);
|
||||
}
|
||||
|
||||
function enter(instance: ReactTestInstance, text: string) {
|
||||
const input = instance.findByType(TextInput);
|
||||
input.props.onChange && input.props.onChange({nativeEvent: {text}});
|
||||
input.props.onChangeText && input.props.onChangeText(text);
|
||||
}
|
||||
|
||||
// Returns null if there is no error, otherwise returns an error message string.
|
||||
function maximumDepthError(
|
||||
tree: ReactTestRendererType,
|
||||
maxDepthLimit: number,
|
||||
): ?string {
|
||||
const maxDepth = maximumDepthOfJSON(tree.toJSON());
|
||||
if (maxDepth > maxDepthLimit) {
|
||||
return (
|
||||
`maximumDepth of ${maxDepth} exceeded limit of ${maxDepthLimit} - this is a proxy ` +
|
||||
'metric to protect against stack overflow errors:\n\n' +
|
||||
'https://fburl.com/rn-view-stack-overflow.\n\n' +
|
||||
'To fix, you need to remove native layers from your hierarchy, such as unnecessary View ' +
|
||||
'wrappers.'
|
||||
);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function expectNoConsoleWarn() {
|
||||
(jest: $FlowFixMe).spyOn(console, 'warn').mockImplementation((...args) => {
|
||||
expect(args).toBeFalsy();
|
||||
});
|
||||
}
|
||||
|
||||
function expectNoConsoleError() {
|
||||
let hasNotFailed = true;
|
||||
(jest: $FlowFixMe).spyOn(console, 'error').mockImplementation((...args) => {
|
||||
if (hasNotFailed) {
|
||||
hasNotFailed = false; // set false to prevent infinite recursion
|
||||
expect(args).toBeFalsy();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function expectRendersMatchingSnapshot(
|
||||
name: string,
|
||||
ComponentProvider: () => React.Element<any>,
|
||||
unmockComponent: () => mixed,
|
||||
) {
|
||||
let instance;
|
||||
|
||||
jest.resetAllMocks();
|
||||
|
||||
instance = ReactTestRenderer.create(<ComponentProvider />);
|
||||
expect(instance).toMatchSnapshot(
|
||||
'should deep render when mocked (please verify output manually)',
|
||||
);
|
||||
|
||||
jest.resetAllMocks();
|
||||
unmockComponent();
|
||||
|
||||
instance = shallowRenderer.render(<ComponentProvider />);
|
||||
expect(instance).toMatchSnapshot(
|
||||
`should shallow render as <${name} /> when not mocked`,
|
||||
);
|
||||
|
||||
jest.resetAllMocks();
|
||||
|
||||
instance = shallowRenderer.render(<ComponentProvider />);
|
||||
expect(instance).toMatchSnapshot(
|
||||
`should shallow render as <${name} /> when mocked`,
|
||||
);
|
||||
|
||||
jest.resetAllMocks();
|
||||
unmockComponent();
|
||||
|
||||
instance = ReactTestRenderer.create(<ComponentProvider />);
|
||||
expect(instance).toMatchSnapshot(
|
||||
'should deep render when not mocked (please verify output manually)',
|
||||
);
|
||||
}
|
||||
|
||||
// Takes a node from toJSON()
|
||||
function maximumDepthOfJSON(node: ?ReactTestRendererJSON): number {
|
||||
if (node == null) {
|
||||
return 0;
|
||||
} else if (typeof node === 'string' || node.children == null) {
|
||||
return 1;
|
||||
} else {
|
||||
let maxDepth = 0;
|
||||
node.children.forEach(child => {
|
||||
maxDepth = Math.max(maximumDepthOfJSON(child) + 1, maxDepth);
|
||||
});
|
||||
return maxDepth;
|
||||
}
|
||||
}
|
||||
|
||||
function renderAndEnforceStrictMode(element: React.Node): any {
|
||||
expectNoConsoleError();
|
||||
return renderWithStrictMode(element);
|
||||
}
|
||||
|
||||
function renderWithStrictMode(element: React.Node): ReactTestRendererType {
|
||||
const WorkAroundBugWithStrictModeInTestRenderer = prps => prps.children;
|
||||
const StrictMode = (React: $FlowFixMe).StrictMode;
|
||||
return ReactTestRenderer.create(
|
||||
<WorkAroundBugWithStrictModeInTestRenderer>
|
||||
<StrictMode>{element}</StrictMode>
|
||||
</WorkAroundBugWithStrictModeInTestRenderer>,
|
||||
);
|
||||
}
|
||||
|
||||
function tap(instance: ReactTestInstance) {
|
||||
const touchable = instance.find(byClickable());
|
||||
if (touchable.type === Text && touchable.props && touchable.props.onPress) {
|
||||
touchable.props.onPress();
|
||||
} else if (touchable.type === Switch && touchable.props) {
|
||||
const value = !touchable.props.value;
|
||||
const {onChange, onValueChange} = touchable.props;
|
||||
onChange && onChange({nativeEvent: {value}});
|
||||
onValueChange && onValueChange(value);
|
||||
} else if (
|
||||
touchable?.props?.onStartShouldSetResponder?.testOnly_pressabilityConfig
|
||||
) {
|
||||
const {
|
||||
onPress,
|
||||
disabled,
|
||||
} = touchable.props.onStartShouldSetResponder.testOnly_pressabilityConfig();
|
||||
if (!disabled) {
|
||||
onPress({nativeEvent: {}});
|
||||
}
|
||||
} else {
|
||||
// Only tap when props.disabled isn't set (or there aren't any props)
|
||||
if (!touchable.props || !touchable.props.disabled) {
|
||||
touchable.props.onPress({nativeEvent: {}});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function scrollToBottom(instance: ReactTestInstance) {
|
||||
const list = instance.findByType(VirtualizedList);
|
||||
list.props && list.props.onEndReached();
|
||||
}
|
||||
|
||||
// To make error messages a little bit better, we attach a custom toString
|
||||
// implementation to a predicate
|
||||
function withMessage(fn: Predicate, message: string): Predicate {
|
||||
(fn: any).toString = () => message;
|
||||
return fn;
|
||||
}
|
||||
|
||||
export {byClickable};
|
||||
export {byTestID};
|
||||
export {byTextMatching};
|
||||
export {enter};
|
||||
export {expectNoConsoleWarn};
|
||||
export {expectNoConsoleError};
|
||||
export {expectRendersMatchingSnapshot};
|
||||
export {maximumDepthError};
|
||||
export {maximumDepthOfJSON};
|
||||
export {renderAndEnforceStrictMode};
|
||||
export {renderWithStrictMode};
|
||||
export {scrollToBottom};
|
||||
export {tap};
|
||||
export {withMessage};
|
41
node_modules/react-native/Libraries/Utilities/SceneTracker.js
generated
vendored
Normal file
41
node_modules/react-native/Libraries/Utilities/SceneTracker.js
generated
vendored
Normal file
@ -0,0 +1,41 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
export type Scene = {name: string, ...};
|
||||
|
||||
let _listeners: Array<(scene: Scene) => void> = [];
|
||||
|
||||
let _activeScene = {name: 'default'};
|
||||
|
||||
const SceneTracker = {
|
||||
setActiveScene(scene: Scene) {
|
||||
_activeScene = scene;
|
||||
_listeners.forEach(listener => listener(_activeScene));
|
||||
},
|
||||
|
||||
getActiveScene(): Scene {
|
||||
return _activeScene;
|
||||
},
|
||||
|
||||
addActiveSceneChangedListener(
|
||||
callback: (scene: Scene) => void,
|
||||
): {remove: () => void, ...} {
|
||||
_listeners.push(callback);
|
||||
return {
|
||||
remove: () => {
|
||||
_listeners = _listeners.filter(listener => callback !== listener);
|
||||
},
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = SceneTracker;
|
50
node_modules/react-native/Libraries/Utilities/__mocks__/BackHandler.js
generated
vendored
Normal file
50
node_modules/react-native/Libraries/Utilities/__mocks__/BackHandler.js
generated
vendored
Normal file
@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const _backPressSubscriptions = new Set();
|
||||
|
||||
const BackHandler = {
|
||||
exitApp: jest.fn(),
|
||||
|
||||
addEventListener: function(
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
): {remove: () => void} {
|
||||
_backPressSubscriptions.add(handler);
|
||||
return {
|
||||
remove: () => BackHandler.removeEventListener(eventName, handler),
|
||||
};
|
||||
},
|
||||
|
||||
removeEventListener: function(
|
||||
eventName: BackPressEventName,
|
||||
handler: Function,
|
||||
): void {
|
||||
_backPressSubscriptions.delete(handler);
|
||||
},
|
||||
|
||||
mockPressBack: function() {
|
||||
let invokeDefault = true;
|
||||
const subscriptions = [..._backPressSubscriptions].reverse();
|
||||
for (let i = 0; i < subscriptions.length; ++i) {
|
||||
if (subscriptions[i]()) {
|
||||
invokeDefault = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (invokeDefault) {
|
||||
BackHandler.exitApp();
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = BackHandler;
|
16
node_modules/react-native/Libraries/Utilities/__mocks__/GlobalPerformanceLogger.js
generated
vendored
Normal file
16
node_modules/react-native/Libraries/Utilities/__mocks__/GlobalPerformanceLogger.js
generated
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const GlobalPerformanceLogger = jest
|
||||
.unmock('../createPerformanceLogger')
|
||||
.genMockFromModule('../GlobalPerformanceLogger');
|
||||
|
||||
module.exports = GlobalPerformanceLogger;
|
25
node_modules/react-native/Libraries/Utilities/__mocks__/PixelRatio.js
generated
vendored
Normal file
25
node_modules/react-native/Libraries/Utilities/__mocks__/PixelRatio.js
generated
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const PixelRatio = {
|
||||
get: jest.fn().mockReturnValue(2),
|
||||
getFontScale: jest.fn(() => PixelRatio.get()),
|
||||
getPixelSizeForLayoutSize: jest.fn(layoutSize =>
|
||||
Math.round(layoutSize * PixelRatio.get()),
|
||||
),
|
||||
roundToNearestPixel: jest.fn(layoutSize => {
|
||||
const ratio = PixelRatio.get();
|
||||
return Math.round(layoutSize * ratio) / ratio;
|
||||
}),
|
||||
startDetecting: jest.fn(),
|
||||
};
|
||||
|
||||
module.exports = PixelRatio;
|
29
node_modules/react-native/Libraries/Utilities/binaryToBase64.js
generated
vendored
Normal file
29
node_modules/react-native/Libraries/Utilities/binaryToBase64.js
generated
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const base64 = require('base64-js');
|
||||
|
||||
function binaryToBase64(data: ArrayBuffer | $ArrayBufferView): any {
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
if (data instanceof Uint8Array) {
|
||||
return base64.fromByteArray(data);
|
||||
}
|
||||
if (!ArrayBuffer.isView(data)) {
|
||||
throw new Error('data must be ArrayBuffer or typed array');
|
||||
}
|
||||
const {buffer, byteOffset, byteLength} = data;
|
||||
return base64.fromByteArray(new Uint8Array(buffer, byteOffset, byteLength));
|
||||
}
|
||||
|
||||
module.exports = binaryToBase64;
|
211
node_modules/react-native/Libraries/Utilities/buildStyleInterpolator.js
generated
vendored
Normal file
211
node_modules/react-native/Libraries/Utilities/buildStyleInterpolator.js
generated
vendored
Normal file
@ -0,0 +1,211 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const keyOf = require('fbjs/lib/keyOf');
|
||||
|
||||
const X_DIM = keyOf({x: null});
|
||||
const Y_DIM = keyOf({y: null});
|
||||
const Z_DIM = keyOf({z: null});
|
||||
|
||||
const InitialOperationField = {
|
||||
transformTranslate: [0, 0, 0],
|
||||
transformScale: [1, 1, 1],
|
||||
};
|
||||
|
||||
const InterpolateMatrix = {
|
||||
transformScale: function(mat, x, y, z) {
|
||||
mat[0] = mat[0] * x;
|
||||
mat[1] = mat[1] * x;
|
||||
mat[2] = mat[2] * x;
|
||||
mat[3] = mat[3] * x;
|
||||
mat[4] = mat[4] * y;
|
||||
mat[5] = mat[5] * y;
|
||||
mat[6] = mat[6] * y;
|
||||
mat[7] = mat[7] * y;
|
||||
mat[8] = mat[8] * z;
|
||||
mat[9] = mat[9] * z;
|
||||
mat[10] = mat[10] * z;
|
||||
mat[11] = mat[11] * z;
|
||||
},
|
||||
transformTranslate: function(mat, x, y, z) {
|
||||
mat[12] = mat[0] * x + mat[4] * y + mat[8] * z + mat[12];
|
||||
mat[13] = mat[1] * x + mat[5] * y + mat[9] * z + mat[13];
|
||||
mat[14] = mat[2] * x + mat[6] * y + mat[10] * z + mat[14];
|
||||
mat[15] = mat[3] * x + mat[7] * y + mat[11] * z + mat[15];
|
||||
},
|
||||
};
|
||||
|
||||
const computeNextValLinear = function(anim, from, to, value) {
|
||||
const hasRoundRatio = 'round' in anim;
|
||||
const roundRatio = anim.round;
|
||||
let ratio = (value - anim.min) / (anim.max - anim.min);
|
||||
if (!anim.extrapolate) {
|
||||
ratio = ratio > 1 ? 1 : ratio < 0 ? 0 : ratio;
|
||||
}
|
||||
let nextVal = from * (1 - ratio) + to * ratio;
|
||||
if (hasRoundRatio) {
|
||||
nextVal = Math.round(roundRatio * nextVal) / roundRatio;
|
||||
}
|
||||
if (!isFinite(nextVal)) {
|
||||
nextVal = null;
|
||||
}
|
||||
return nextVal;
|
||||
};
|
||||
|
||||
const computeNextValLinearScalar = function(anim, value) {
|
||||
return computeNextValLinear(anim, anim.from, anim.to, value);
|
||||
};
|
||||
|
||||
const setNextValAndDetectChange = function(result, name, nextVal, didChange) {
|
||||
if (!didChange) {
|
||||
const prevVal = result[name];
|
||||
result[name] = nextVal;
|
||||
didChange = didChange || nextVal !== prevVal;
|
||||
} else {
|
||||
result[name] = nextVal;
|
||||
}
|
||||
return didChange;
|
||||
};
|
||||
|
||||
const initIdentity = function(mat) {
|
||||
mat[0] = 1;
|
||||
mat[1] = 0;
|
||||
mat[2] = 0;
|
||||
mat[3] = 0;
|
||||
mat[4] = 0;
|
||||
mat[5] = 1;
|
||||
mat[6] = 0;
|
||||
mat[7] = 0;
|
||||
mat[8] = 0;
|
||||
mat[9] = 0;
|
||||
mat[10] = 1;
|
||||
mat[11] = 0;
|
||||
mat[12] = 0;
|
||||
mat[13] = 0;
|
||||
mat[14] = 0;
|
||||
mat[15] = 1;
|
||||
};
|
||||
|
||||
const computeNextMatrixOperationField = function(
|
||||
anim,
|
||||
name,
|
||||
dim,
|
||||
index,
|
||||
value,
|
||||
) {
|
||||
if (anim.from[dim] !== undefined && anim.to[dim] !== undefined) {
|
||||
return computeNextValLinear(anim, anim.from[dim], anim.to[dim], value);
|
||||
} else {
|
||||
return InitialOperationField[name][index];
|
||||
}
|
||||
};
|
||||
|
||||
const computeTransform = function(
|
||||
anim,
|
||||
name,
|
||||
value,
|
||||
result,
|
||||
didChange,
|
||||
didMatrix,
|
||||
) {
|
||||
const transform =
|
||||
result.transform !== undefined
|
||||
? result.transform
|
||||
: (result.transform = [{matrix: []}]);
|
||||
const mat = transform[0].matrix;
|
||||
const m0 = mat[0];
|
||||
const m1 = mat[1];
|
||||
const m2 = mat[2];
|
||||
const m3 = mat[3];
|
||||
const m4 = mat[4];
|
||||
const m5 = mat[5];
|
||||
const m6 = mat[6];
|
||||
const m7 = mat[7];
|
||||
const m8 = mat[8];
|
||||
const m9 = mat[9];
|
||||
const m10 = mat[10];
|
||||
const m11 = mat[11];
|
||||
const m12 = mat[12];
|
||||
const m13 = mat[13];
|
||||
const m14 = mat[14];
|
||||
const m15 = mat[15];
|
||||
if (!didMatrix) {
|
||||
initIdentity(mat); // This will be the first transform.
|
||||
}
|
||||
const x = computeNextMatrixOperationField(anim, name, X_DIM, 0, value);
|
||||
const y = computeNextMatrixOperationField(anim, name, Y_DIM, 1, value);
|
||||
const z = computeNextMatrixOperationField(anim, name, Z_DIM, 2, value);
|
||||
InterpolateMatrix[name](mat, x, y, z);
|
||||
if (!didChange) {
|
||||
didChange =
|
||||
m0 !== mat[0] ||
|
||||
m1 !== mat[1] ||
|
||||
m2 !== mat[2] ||
|
||||
m3 !== mat[3] ||
|
||||
m4 !== mat[4] ||
|
||||
m5 !== mat[5] ||
|
||||
m6 !== mat[6] ||
|
||||
m7 !== mat[7] ||
|
||||
m8 !== mat[8] ||
|
||||
m9 !== mat[9] ||
|
||||
m10 !== mat[10] ||
|
||||
m11 !== mat[11] ||
|
||||
m12 !== mat[12] ||
|
||||
m13 !== mat[13] ||
|
||||
m14 !== mat[14] ||
|
||||
m15 !== mat[15];
|
||||
}
|
||||
return didChange;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {object} anims Animation configuration by style property name.
|
||||
* @return {function} Function accepting style object, that mutates that style
|
||||
* object and returns a boolean describing if any update was actually applied.
|
||||
*/
|
||||
const buildStyleInterpolator = function(anims) {
|
||||
function styleInterpolator(result, value) {
|
||||
let didChange = false;
|
||||
let didMatrix = false;
|
||||
for (const name in anims) {
|
||||
const anim = anims[name];
|
||||
if (anim.type === 'linear') {
|
||||
if (name in InterpolateMatrix) {
|
||||
didChange = computeTransform(
|
||||
anim,
|
||||
name,
|
||||
value,
|
||||
result,
|
||||
didChange,
|
||||
didMatrix,
|
||||
);
|
||||
didMatrix = true;
|
||||
} else {
|
||||
const next = computeNextValLinearScalar(anim, value);
|
||||
didChange = setNextValAndDetectChange(result, name, next, didChange);
|
||||
}
|
||||
} else if (anim.type === 'constant') {
|
||||
const next = anim.value;
|
||||
didChange = setNextValAndDetectChange(result, name, next, didChange);
|
||||
} else if (anim.type === 'step') {
|
||||
const next = value >= anim.threshold ? anim.to : anim.from;
|
||||
didChange = setNextValAndDetectChange(result, name, next, didChange);
|
||||
} else if (anim.type === 'identity') {
|
||||
const next = value;
|
||||
didChange = setNextValAndDetectChange(result, name, next, didChange);
|
||||
}
|
||||
}
|
||||
return didChange;
|
||||
}
|
||||
return styleInterpolator;
|
||||
};
|
||||
|
||||
module.exports = buildStyleInterpolator;
|
23
node_modules/react-native/Libraries/Utilities/clamp.js
generated
vendored
Normal file
23
node_modules/react-native/Libraries/Utilities/clamp.js
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function clamp(min: number, value: number, max: number): number {
|
||||
if (value < min) {
|
||||
return min;
|
||||
}
|
||||
if (value > max) {
|
||||
return max;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
module.exports = clamp;
|
31
node_modules/react-native/Libraries/Utilities/codegenNativeCommands.js
generated
vendored
Normal file
31
node_modules/react-native/Libraries/Utilities/codegenNativeCommands.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import {dispatchCommand} from '../../Libraries/Renderer/shims/ReactNative';
|
||||
|
||||
type Options<T = string> = $ReadOnly<{|
|
||||
supportedCommands: $ReadOnlyArray<T>,
|
||||
|}>;
|
||||
|
||||
function codegenNativeCommands<T: {...}>(options: Options<$Keys<T>>): T {
|
||||
const commandObj = {};
|
||||
|
||||
options.supportedCommands.forEach(command => {
|
||||
commandObj[command] = (ref, ...args) => {
|
||||
dispatchCommand(ref, command, args);
|
||||
};
|
||||
});
|
||||
|
||||
return ((commandObj: any): T);
|
||||
}
|
||||
|
||||
export default codegenNativeCommands;
|
63
node_modules/react-native/Libraries/Utilities/codegenNativeComponent.js
generated
vendored
Normal file
63
node_modules/react-native/Libraries/Utilities/codegenNativeComponent.js
generated
vendored
Normal file
@ -0,0 +1,63 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
// TODO: move this file to shims/ReactNative (requires React update and sync)
|
||||
|
||||
'use strict';
|
||||
|
||||
import requireNativeComponent from '../../Libraries/ReactNative/requireNativeComponent';
|
||||
import type {HostComponent} from '../../Libraries/Renderer/shims/ReactNativeTypes';
|
||||
import UIManager from '../ReactNative/UIManager';
|
||||
|
||||
// TODO: import from CodegenSchema once workspaces are enabled
|
||||
type Options = $ReadOnly<{|
|
||||
interfaceOnly?: boolean,
|
||||
paperComponentName?: string,
|
||||
paperComponentNameDeprecated?: string,
|
||||
excludedPlatform?: 'iOS' | 'android',
|
||||
|}>;
|
||||
|
||||
export type NativeComponentType<T> = HostComponent<T>;
|
||||
|
||||
function codegenNativeComponent<Props>(
|
||||
componentName: string,
|
||||
options?: Options,
|
||||
): NativeComponentType<Props> {
|
||||
let componentNameInUse =
|
||||
options && options.paperComponentName
|
||||
? options.paperComponentName
|
||||
: componentName;
|
||||
|
||||
if (options != null && options.paperComponentNameDeprecated != null) {
|
||||
if (UIManager.getViewManagerConfig(componentName)) {
|
||||
componentNameInUse = componentName;
|
||||
} else if (
|
||||
options.paperComponentNameDeprecated != null &&
|
||||
UIManager.getViewManagerConfig(options.paperComponentNameDeprecated)
|
||||
) {
|
||||
componentNameInUse = options.paperComponentNameDeprecated;
|
||||
} else {
|
||||
throw new Error(
|
||||
`Failed to find native component for either ${componentName} or ${options.paperComponentNameDeprecated ||
|
||||
'(unknown)'}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// If this function is run at runtime then that means the view configs were not
|
||||
// generated with the view config babel plugin, so we need to require the native component.
|
||||
//
|
||||
// This will be useful during migration, but eventually this will error.
|
||||
return (requireNativeComponent<Props>(
|
||||
componentNameInUse,
|
||||
): HostComponent<Props>);
|
||||
}
|
||||
|
||||
export default codegenNativeComponent;
|
275
node_modules/react-native/Libraries/Utilities/createPerformanceLogger.js
generated
vendored
Normal file
275
node_modules/react-native/Libraries/Utilities/createPerformanceLogger.js
generated
vendored
Normal file
@ -0,0 +1,275 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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 Systrace = require('../Performance/Systrace');
|
||||
|
||||
const infoLog = require('./infoLog');
|
||||
const performanceNow =
|
||||
global.nativeQPLTimestamp ||
|
||||
global.nativePerformanceNow ||
|
||||
require('fbjs/lib/performanceNow');
|
||||
|
||||
type Timespan = {
|
||||
description?: string,
|
||||
totalTime?: number,
|
||||
startTime?: number,
|
||||
endTime?: number,
|
||||
...
|
||||
};
|
||||
|
||||
export type IPerformanceLogger = {
|
||||
addTimespan(string, number, string | void): void,
|
||||
startTimespan(string, string | void): void,
|
||||
stopTimespan(string, options?: {update?: boolean}): void,
|
||||
clear(): void,
|
||||
clearCompleted(): void,
|
||||
clearExceptTimespans(Array<string>): void,
|
||||
currentTimestamp(): number,
|
||||
getTimespans(): {[key: string]: Timespan, ...},
|
||||
hasTimespan(string): boolean,
|
||||
logTimespans(): void,
|
||||
addTimespans(Array<number>, Array<string>): void,
|
||||
setExtra(string, any): void,
|
||||
getExtras(): {[key: string]: any, ...},
|
||||
removeExtra(string): ?any,
|
||||
logExtras(): void,
|
||||
markPoint(string, number | void): void,
|
||||
getPoints(): {[key: string]: number, ...},
|
||||
logPoints(): void,
|
||||
logEverything(): void,
|
||||
...
|
||||
};
|
||||
|
||||
const _cookies: {[key: string]: number, ...} = {};
|
||||
|
||||
const PRINT_TO_CONSOLE: false = false; // Type as false to prevent accidentally committing `true`;
|
||||
|
||||
/**
|
||||
* This function creates performance loggers that can be used to collect and log
|
||||
* various performance data such as timespans, points and extras.
|
||||
* The loggers need to have minimal overhead since they're used in production.
|
||||
*/
|
||||
function createPerformanceLogger(): IPerformanceLogger {
|
||||
const result: IPerformanceLogger & {
|
||||
_timespans: {[key: string]: Timespan, ...},
|
||||
_extras: {[key: string]: any, ...},
|
||||
_points: {[key: string]: number, ...},
|
||||
...
|
||||
} = {
|
||||
_timespans: {},
|
||||
_extras: {},
|
||||
_points: {},
|
||||
|
||||
addTimespan(key: string, lengthInMs: number, description?: string) {
|
||||
if (this._timespans[key]) {
|
||||
if (PRINT_TO_CONSOLE && __DEV__) {
|
||||
infoLog(
|
||||
'PerformanceLogger: Attempting to add a timespan that already exists ',
|
||||
key,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._timespans[key] = {
|
||||
description: description,
|
||||
totalTime: lengthInMs,
|
||||
};
|
||||
},
|
||||
|
||||
startTimespan(key: string, description?: string) {
|
||||
if (this._timespans[key]) {
|
||||
if (PRINT_TO_CONSOLE && __DEV__) {
|
||||
infoLog(
|
||||
'PerformanceLogger: Attempting to start a timespan that already exists ',
|
||||
key,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
this._timespans[key] = {
|
||||
description: description,
|
||||
startTime: performanceNow(),
|
||||
};
|
||||
_cookies[key] = Systrace.beginAsyncEvent(key);
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
infoLog('PerformanceLogger.js', 'start: ' + key);
|
||||
}
|
||||
},
|
||||
|
||||
stopTimespan(key: string, options?: {update?: boolean}) {
|
||||
const timespan = this._timespans[key];
|
||||
if (!timespan || !timespan.startTime) {
|
||||
if (PRINT_TO_CONSOLE && __DEV__) {
|
||||
infoLog(
|
||||
'PerformanceLogger: Attempting to end a timespan that has not started ',
|
||||
key,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (timespan.endTime && !options?.update) {
|
||||
if (PRINT_TO_CONSOLE && __DEV__) {
|
||||
infoLog(
|
||||
'PerformanceLogger: Attempting to end a timespan that has already ended ',
|
||||
key,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
timespan.endTime = performanceNow();
|
||||
timespan.totalTime = timespan.endTime - (timespan.startTime || 0);
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
infoLog('PerformanceLogger.js', 'end: ' + key);
|
||||
}
|
||||
|
||||
if (_cookies[key] != null) {
|
||||
Systrace.endAsyncEvent(key, _cookies[key]);
|
||||
delete _cookies[key];
|
||||
}
|
||||
},
|
||||
|
||||
clear() {
|
||||
this._timespans = {};
|
||||
this._extras = {};
|
||||
this._points = {};
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
infoLog('PerformanceLogger.js', 'clear');
|
||||
}
|
||||
},
|
||||
|
||||
clearCompleted() {
|
||||
for (const key in this._timespans) {
|
||||
if (this._timespans[key].totalTime) {
|
||||
delete this._timespans[key];
|
||||
}
|
||||
}
|
||||
this._extras = {};
|
||||
this._points = {};
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
infoLog('PerformanceLogger.js', 'clearCompleted');
|
||||
}
|
||||
},
|
||||
|
||||
clearExceptTimespans(keys: Array<string>) {
|
||||
this._timespans = Object.keys(this._timespans).reduce(function(
|
||||
previous,
|
||||
key,
|
||||
) {
|
||||
if (keys.indexOf(key) !== -1) {
|
||||
previous[key] = this._timespans[key];
|
||||
}
|
||||
return previous;
|
||||
},
|
||||
{});
|
||||
this._extras = {};
|
||||
this._points = {};
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
infoLog('PerformanceLogger.js', 'clearExceptTimespans', keys);
|
||||
}
|
||||
},
|
||||
|
||||
currentTimestamp() {
|
||||
return performanceNow();
|
||||
},
|
||||
|
||||
getTimespans() {
|
||||
return this._timespans;
|
||||
},
|
||||
|
||||
hasTimespan(key: string) {
|
||||
return !!this._timespans[key];
|
||||
},
|
||||
|
||||
logTimespans() {
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
for (const key in this._timespans) {
|
||||
if (this._timespans[key].totalTime) {
|
||||
infoLog(key + ': ' + this._timespans[key].totalTime + 'ms');
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
addTimespans(newTimespans: Array<number>, labels: Array<string>) {
|
||||
for (let ii = 0, l = newTimespans.length; ii < l; ii += 2) {
|
||||
const label = labels[ii / 2];
|
||||
this.addTimespan(label, newTimespans[ii + 1] - newTimespans[ii], label);
|
||||
}
|
||||
},
|
||||
|
||||
setExtra(key: string, value: any) {
|
||||
if (this._extras[key]) {
|
||||
if (PRINT_TO_CONSOLE && __DEV__) {
|
||||
infoLog(
|
||||
'PerformanceLogger: Attempting to set an extra that already exists ',
|
||||
{key, currentValue: this._extras[key], attemptedValue: value},
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this._extras[key] = value;
|
||||
},
|
||||
|
||||
getExtras() {
|
||||
return this._extras;
|
||||
},
|
||||
|
||||
removeExtra(key: string): ?any {
|
||||
const value = this._extras[key];
|
||||
delete this._extras[key];
|
||||
return value;
|
||||
},
|
||||
|
||||
logExtras() {
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
infoLog(this._extras);
|
||||
}
|
||||
},
|
||||
|
||||
markPoint(key: string, timestamp?: number) {
|
||||
if (this._points[key]) {
|
||||
if (PRINT_TO_CONSOLE && __DEV__) {
|
||||
infoLog(
|
||||
'PerformanceLogger: Attempting to mark a point that has been already logged ',
|
||||
key,
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this._points[key] = timestamp ?? performanceNow();
|
||||
},
|
||||
|
||||
getPoints() {
|
||||
return this._points;
|
||||
},
|
||||
|
||||
logPoints() {
|
||||
if (PRINT_TO_CONSOLE) {
|
||||
for (const key in this._points) {
|
||||
infoLog(key + ': ' + this._points[key] + 'ms');
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
logEverything() {
|
||||
this.logTimespans();
|
||||
this.logExtras();
|
||||
this.logPoints();
|
||||
},
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = createPerformanceLogger;
|
84
node_modules/react-native/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js
generated
vendored
Normal file
84
node_modules/react-native/Libraries/Utilities/deepFreezeAndThrowOnMutationInDev.js
generated
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* If your application is accepting different values for the same field over
|
||||
* time and is doing a diff on them, you can either (1) create a copy or
|
||||
* (2) ensure that those values are not mutated behind two passes.
|
||||
* This function helps you with (2) by freezing the object and throwing if
|
||||
* the user subsequently modifies the value.
|
||||
*
|
||||
* There are two caveats with this function:
|
||||
* - If the call site is not in strict mode, it will only throw when
|
||||
* mutating existing fields, adding a new one
|
||||
* will unfortunately fail silently :(
|
||||
* - If the object is already frozen or sealed, it will not continue the
|
||||
* deep traversal and will leave leaf nodes unfrozen.
|
||||
*
|
||||
* Freezing the object and adding the throw mechanism is expensive and will
|
||||
* only be used in DEV.
|
||||
*/
|
||||
function deepFreezeAndThrowOnMutationInDev<T: Object>(object: T): T {
|
||||
if (__DEV__) {
|
||||
if (
|
||||
typeof object !== 'object' ||
|
||||
object === null ||
|
||||
Object.isFrozen(object) ||
|
||||
Object.isSealed(object)
|
||||
) {
|
||||
return object;
|
||||
}
|
||||
|
||||
const keys = Object.keys(object);
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (hasOwnProperty.call(object, key)) {
|
||||
Object.defineProperty(object, key, {
|
||||
get: identity.bind(null, object[key]),
|
||||
});
|
||||
Object.defineProperty(object, key, {
|
||||
set: throwOnImmutableMutation.bind(null, key),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Object.freeze(object);
|
||||
Object.seal(object);
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
const key = keys[i];
|
||||
if (hasOwnProperty.call(object, key)) {
|
||||
deepFreezeAndThrowOnMutationInDev(object[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return object;
|
||||
}
|
||||
|
||||
function throwOnImmutableMutation(key, value) {
|
||||
throw Error(
|
||||
'You attempted to set the key `' +
|
||||
key +
|
||||
'` with the value `' +
|
||||
JSON.stringify(value) +
|
||||
'` on an object that is meant to be immutable ' +
|
||||
'and has been frozen.',
|
||||
);
|
||||
}
|
||||
|
||||
function identity(value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
module.exports = deepFreezeAndThrowOnMutationInDev;
|
66
node_modules/react-native/Libraries/Utilities/defineLazyObjectProperty.js
generated
vendored
Normal file
66
node_modules/react-native/Libraries/Utilities/defineLazyObjectProperty.js
generated
vendored
Normal file
@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Defines a lazily evaluated property on the supplied `object`.
|
||||
*/
|
||||
function defineLazyObjectProperty<T>(
|
||||
object: Object,
|
||||
name: string,
|
||||
descriptor: {
|
||||
get: () => T,
|
||||
enumerable?: boolean,
|
||||
writable?: boolean,
|
||||
...
|
||||
},
|
||||
): void {
|
||||
const {get} = descriptor;
|
||||
const enumerable = descriptor.enumerable !== false;
|
||||
const writable = descriptor.writable !== false;
|
||||
|
||||
let value;
|
||||
let valueSet = false;
|
||||
function getValue(): T {
|
||||
// WORKAROUND: A weird infinite loop occurs where calling `getValue` calls
|
||||
// `setValue` which calls `Object.defineProperty` which somehow triggers
|
||||
// `getValue` again. Adding `valueSet` breaks this loop.
|
||||
if (!valueSet) {
|
||||
// Calling `get()` here can trigger an infinite loop if it fails to
|
||||
// remove the getter on the property, which can happen when executing
|
||||
// JS in a V8 context. `valueSet = true` will break this loop, and
|
||||
// sets the value of the property to undefined, until the code in `get()`
|
||||
// finishes, at which point the property is set to the correct value.
|
||||
valueSet = true;
|
||||
setValue(get());
|
||||
}
|
||||
return value;
|
||||
}
|
||||
function setValue(newValue: T): void {
|
||||
value = newValue;
|
||||
valueSet = true;
|
||||
Object.defineProperty(object, name, {
|
||||
value: newValue,
|
||||
configurable: true,
|
||||
enumerable,
|
||||
writable,
|
||||
});
|
||||
}
|
||||
|
||||
Object.defineProperty(object, name, {
|
||||
get: getValue,
|
||||
set: setValue,
|
||||
configurable: true,
|
||||
enumerable,
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = defineLazyObjectProperty;
|
38
node_modules/react-native/Libraries/Utilities/deprecatedPropType.js
generated
vendored
Normal file
38
node_modules/react-native/Libraries/Utilities/deprecatedPropType.js
generated
vendored
Normal file
@ -0,0 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const UIManager = require('../ReactNative/UIManager');
|
||||
|
||||
/**
|
||||
* Adds a deprecation warning when the prop is used.
|
||||
*/
|
||||
function deprecatedPropType(
|
||||
propType: ReactPropsCheckType,
|
||||
explanation: string,
|
||||
): ReactPropsCheckType {
|
||||
return function validate(props, propName, componentName, ...rest) {
|
||||
// Don't warn for native components.
|
||||
if (
|
||||
!global.RN$Bridgeless &&
|
||||
!UIManager.getViewManagerConfig(componentName) &&
|
||||
props[propName] !== undefined
|
||||
) {
|
||||
console.warn(
|
||||
`\`${propName}\` supplied to \`${componentName}\` has been deprecated. ${explanation}`,
|
||||
);
|
||||
}
|
||||
|
||||
return propType(props, propName, componentName, ...rest);
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = deprecatedPropType;
|
101
node_modules/react-native/Libraries/Utilities/differ/deepDiffer.js
generated
vendored
Normal file
101
node_modules/react-native/Libraries/Utilities/differ/deepDiffer.js
generated
vendored
Normal file
@ -0,0 +1,101 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
let logListeners;
|
||||
|
||||
type LogListeners = {|
|
||||
+onDifferentFunctionsIgnored: (nameOne: ?string, nameTwo: ?string) => void,
|
||||
|};
|
||||
|
||||
type Options = {|+unsafelyIgnoreFunctions?: boolean|};
|
||||
|
||||
function unstable_setLogListeners(listeners: ?LogListeners) {
|
||||
logListeners = listeners;
|
||||
}
|
||||
|
||||
/*
|
||||
* @returns {bool} true if different, false if equal
|
||||
*/
|
||||
const deepDiffer = function(
|
||||
one: any,
|
||||
two: any,
|
||||
maxDepthOrOptions: Options | number = -1,
|
||||
maybeOptions?: Options,
|
||||
): boolean {
|
||||
const options =
|
||||
typeof maxDepthOrOptions === 'number' ? maybeOptions : maxDepthOrOptions;
|
||||
const maxDepth =
|
||||
typeof maxDepthOrOptions === 'number' ? maxDepthOrOptions : -1;
|
||||
if (maxDepth === 0) {
|
||||
return true;
|
||||
}
|
||||
if (one === two) {
|
||||
// Short circuit on identical object references instead of traversing them.
|
||||
return false;
|
||||
}
|
||||
if (typeof one === 'function' && typeof two === 'function') {
|
||||
// We consider all functions equal unless explicitly configured otherwise
|
||||
let unsafelyIgnoreFunctions = options?.unsafelyIgnoreFunctions;
|
||||
if (unsafelyIgnoreFunctions == null) {
|
||||
if (
|
||||
logListeners &&
|
||||
logListeners.onDifferentFunctionsIgnored &&
|
||||
(!options || !('unsafelyIgnoreFunctions' in options))
|
||||
) {
|
||||
logListeners.onDifferentFunctionsIgnored(one.name, two.name);
|
||||
}
|
||||
unsafelyIgnoreFunctions = true;
|
||||
}
|
||||
return !unsafelyIgnoreFunctions;
|
||||
}
|
||||
if (typeof one !== 'object' || one === null) {
|
||||
// Primitives can be directly compared
|
||||
return one !== two;
|
||||
}
|
||||
if (typeof two !== 'object' || two === null) {
|
||||
// We know they are different because the previous case would have triggered
|
||||
// otherwise.
|
||||
return true;
|
||||
}
|
||||
if (one.constructor !== two.constructor) {
|
||||
return true;
|
||||
}
|
||||
if (Array.isArray(one)) {
|
||||
// We know two is also an array because the constructors are equal
|
||||
const len = one.length;
|
||||
if (two.length !== len) {
|
||||
return true;
|
||||
}
|
||||
for (let ii = 0; ii < len; ii++) {
|
||||
if (deepDiffer(one[ii], two[ii], maxDepth - 1, options)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (const key in one) {
|
||||
if (deepDiffer(one[key], two[key], maxDepth - 1, options)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
for (const twoKey in two) {
|
||||
// The only case we haven't checked yet is keys that are in two but aren't
|
||||
// in one, which means they are different.
|
||||
if (one[twoKey] === undefined && two[twoKey] !== undefined) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
module.exports = deepDiffer;
|
||||
module.exports.unstable_setLogListeners = unstable_setLogListeners;
|
40
node_modules/react-native/Libraries/Utilities/differ/insetsDiffer.js
generated
vendored
Normal file
40
node_modules/react-native/Libraries/Utilities/differ/insetsDiffer.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
type Inset = {
|
||||
top: ?number,
|
||||
left: ?number,
|
||||
right: ?number,
|
||||
bottom: ?number,
|
||||
...
|
||||
};
|
||||
|
||||
const dummyInsets = {
|
||||
top: undefined,
|
||||
left: undefined,
|
||||
right: undefined,
|
||||
bottom: undefined,
|
||||
};
|
||||
|
||||
const insetsDiffer = function(one: Inset, two: Inset): boolean {
|
||||
one = one || dummyInsets;
|
||||
two = two || dummyInsets;
|
||||
return (
|
||||
one !== two &&
|
||||
(one.top !== two.top ||
|
||||
one.left !== two.left ||
|
||||
one.right !== two.right ||
|
||||
one.bottom !== two.bottom)
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = insetsDiffer;
|
47
node_modules/react-native/Libraries/Utilities/differ/matricesDiffer.js
generated
vendored
Normal file
47
node_modules/react-native/Libraries/Utilities/differ/matricesDiffer.js
generated
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Unrolls an array comparison specially for matrices. Prioritizes
|
||||
* checking of indices that are most likely to change so that the comparison
|
||||
* bails as early as possible.
|
||||
*
|
||||
* @param {MatrixMath.Matrix} one First matrix.
|
||||
* @param {MatrixMath.Matrix} two Second matrix.
|
||||
* @return {boolean} Whether or not the two matrices differ.
|
||||
*/
|
||||
const matricesDiffer = function(one, two) {
|
||||
if (one === two) {
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
!one ||
|
||||
!two ||
|
||||
one[12] !== two[12] ||
|
||||
one[13] !== two[13] ||
|
||||
one[14] !== two[14] ||
|
||||
one[5] !== two[5] ||
|
||||
one[10] !== two[10] ||
|
||||
one[0] !== two[0] ||
|
||||
one[1] !== two[1] ||
|
||||
one[2] !== two[2] ||
|
||||
one[3] !== two[3] ||
|
||||
one[4] !== two[4] ||
|
||||
one[6] !== two[6] ||
|
||||
one[7] !== two[7] ||
|
||||
one[8] !== two[8] ||
|
||||
one[9] !== two[9] ||
|
||||
one[11] !== two[11] ||
|
||||
one[15] !== two[15]
|
||||
);
|
||||
};
|
||||
|
||||
module.exports = matricesDiffer;
|
27
node_modules/react-native/Libraries/Utilities/differ/pointsDiffer.js
generated
vendored
Normal file
27
node_modules/react-native/Libraries/Utilities/differ/pointsDiffer.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
type Point = {
|
||||
x: ?number,
|
||||
y: ?number,
|
||||
...
|
||||
};
|
||||
|
||||
const dummyPoint = {x: undefined, y: undefined};
|
||||
|
||||
const pointsDiffer = function(one: ?Point, two: ?Point): boolean {
|
||||
one = one || dummyPoint;
|
||||
two = two || dummyPoint;
|
||||
return one !== two && (one.x !== two.x || one.y !== two.y);
|
||||
};
|
||||
|
||||
module.exports = pointsDiffer;
|
20
node_modules/react-native/Libraries/Utilities/differ/sizesDiffer.js
generated
vendored
Normal file
20
node_modules/react-native/Libraries/Utilities/differ/sizesDiffer.js
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const dummySize = {width: undefined, height: undefined};
|
||||
|
||||
const sizesDiffer = function(one, two) {
|
||||
one = one || dummySize;
|
||||
two = two || dummySize;
|
||||
return one !== two && (one.width !== two.width || one.height !== two.height);
|
||||
};
|
||||
|
||||
module.exports = sizesDiffer;
|
21
node_modules/react-native/Libraries/Utilities/dismissKeyboard.js
generated
vendored
Normal file
21
node_modules/react-native/Libraries/Utilities/dismissKeyboard.js
generated
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
// This function dismisses the currently-open keyboard, if any.
|
||||
|
||||
'use strict';
|
||||
|
||||
const TextInputState = require('../Components/TextInput/TextInputState');
|
||||
|
||||
function dismissKeyboard() {
|
||||
TextInputState.blurTextInput(TextInputState.currentlyFocusedInput());
|
||||
}
|
||||
|
||||
module.exports = dismissKeyboard;
|
51
node_modules/react-native/Libraries/Utilities/groupByEveryN.js
generated
vendored
Normal file
51
node_modules/react-native/Libraries/Utilities/groupByEveryN.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
/**
|
||||
* Useful method to split an array into groups of the same number of elements.
|
||||
* You can use it to generate grids, rows, pages...
|
||||
*
|
||||
* If the input length is not a multiple of the count, it'll fill the last
|
||||
* array with null so you can display a placeholder.
|
||||
*
|
||||
* Example:
|
||||
* groupByEveryN([1, 2, 3, 4, 5], 3)
|
||||
* => [[1, 2, 3], [4, 5, null]]
|
||||
*
|
||||
* groupByEveryN([1, 2, 3], 2).map(elems => {
|
||||
* return <Row>{elems.map(elem => <Elem>{elem}</Elem>)}</Row>;
|
||||
* })
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function groupByEveryN<T>(array: Array<T>, n: number): Array<Array<?T>> {
|
||||
const result = [];
|
||||
let temp = [];
|
||||
|
||||
for (let i = 0; i < array.length; ++i) {
|
||||
if (i > 0 && i % n === 0) {
|
||||
result.push(temp);
|
||||
temp = [];
|
||||
}
|
||||
temp.push(array[i]);
|
||||
}
|
||||
|
||||
if (temp.length > 0) {
|
||||
while (temp.length !== n) {
|
||||
temp.push(null);
|
||||
}
|
||||
result.push(temp);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
module.exports = groupByEveryN;
|
20
node_modules/react-native/Libraries/Utilities/infoLog.js
generated
vendored
Normal file
20
node_modules/react-native/Libraries/Utilities/infoLog.js
generated
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Intentional info-level logging for clear separation from ad-hoc console debug logging.
|
||||
*/
|
||||
function infoLog(...args: Array<mixed>): void {
|
||||
return console.log(...args);
|
||||
}
|
||||
|
||||
module.exports = infoLog;
|
27
node_modules/react-native/Libraries/Utilities/logError.js
generated
vendored
Normal file
27
node_modules/react-native/Libraries/Utilities/logError.js
generated
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Small utility that can be used as an error handler. You cannot just pass
|
||||
* `console.error` as a failure callback - it's not properly bound. If passes an
|
||||
* `Error` object, it will print the message and stack.
|
||||
*/
|
||||
const logError = function(...args: $ReadOnlyArray<mixed>) {
|
||||
if (args.length === 1 && args[0] instanceof Error) {
|
||||
const err = args[0];
|
||||
console.error('Error: "' + err.message + '". Stack:\n' + err.stack);
|
||||
} else {
|
||||
console.error.apply(console, args);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = logError;
|
28
node_modules/react-native/Libraries/Utilities/mapWithSeparator.js
generated
vendored
Normal file
28
node_modules/react-native/Libraries/Utilities/mapWithSeparator.js
generated
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function mapWithSeparator<TFrom, TTo>(
|
||||
items: Array<TFrom>,
|
||||
itemRenderer: (item: TFrom, index: number, items: Array<TFrom>) => TTo,
|
||||
spacerRenderer: (index: number) => TTo,
|
||||
): Array<TTo> {
|
||||
const mapped = [];
|
||||
if (items.length > 0) {
|
||||
mapped.push(itemRenderer(items[0], 0, items));
|
||||
for (let ii = 1; ii < items.length; ii++) {
|
||||
mapped.push(spacerRenderer(ii - 1), itemRenderer(items[ii], ii, items));
|
||||
}
|
||||
}
|
||||
return mapped;
|
||||
}
|
||||
|
||||
module.exports = mapWithSeparator;
|
26
node_modules/react-native/Libraries/Utilities/mergeIntoFast.js
generated
vendored
Normal file
26
node_modules/react-native/Libraries/Utilities/mergeIntoFast.js
generated
vendored
Normal file
@ -0,0 +1,26 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Faster version of `mergeInto` that doesn't check its arguments and
|
||||
* also copies over prototype inherited properties.
|
||||
*
|
||||
* @param {object} one Object to assign to.
|
||||
* @param {object} two Object to assign from.
|
||||
*/
|
||||
const mergeIntoFast = function(one: Object, two: Object): void {
|
||||
for (const keyTwo in two) {
|
||||
one[keyTwo] = two[keyTwo];
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = mergeIntoFast;
|
83
node_modules/react-native/Libraries/Utilities/registerGeneratedViewConfig.js
generated
vendored
Normal file
83
node_modules/react-native/Libraries/Utilities/registerGeneratedViewConfig.js
generated
vendored
Normal file
@ -0,0 +1,83 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* 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 ReactNativeViewConfigRegistry = require('../Renderer/shims/ReactNativeViewConfigRegistry');
|
||||
const ReactNativeViewViewConfig = require('../Components/View/ReactNativeViewViewConfig');
|
||||
import verifyComponentAttributeEquivalence from './verifyComponentAttributeEquivalence';
|
||||
|
||||
export type GeneratedViewConfig = {
|
||||
uiViewClassName: string,
|
||||
bubblingEventTypes?: $ReadOnly<{
|
||||
[eventName: string]: $ReadOnly<{|
|
||||
phasedRegistrationNames: $ReadOnly<{|
|
||||
captured: string,
|
||||
bubbled: string,
|
||||
|}>,
|
||||
|}>,
|
||||
...,
|
||||
}>,
|
||||
directEventTypes?: $ReadOnly<{
|
||||
[eventName: string]: $ReadOnly<{|
|
||||
registrationName: string,
|
||||
|}>,
|
||||
...,
|
||||
}>,
|
||||
validAttributes?: {
|
||||
[propName: string]:
|
||||
| true
|
||||
| $ReadOnly<{|
|
||||
diff?: <T>(arg1: any, arg2: any) => boolean,
|
||||
process?: (arg1: any) => any,
|
||||
|}>,
|
||||
...,
|
||||
},
|
||||
...
|
||||
};
|
||||
|
||||
function registerGeneratedViewConfig(
|
||||
componentName: string,
|
||||
viewConfig: GeneratedViewConfig,
|
||||
) {
|
||||
const mergedViewConfig = {
|
||||
uiViewClassName: componentName,
|
||||
Commands: {},
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.122.0 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
bubblingEventTypes: {
|
||||
...ReactNativeViewViewConfig.bubblingEventTypes,
|
||||
...(viewConfig.bubblingEventTypes || {}),
|
||||
},
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.122.0 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
directEventTypes: {
|
||||
...ReactNativeViewViewConfig.directEventTypes,
|
||||
...(viewConfig.directEventTypes || {}),
|
||||
},
|
||||
/* $FlowFixMe(>=0.122.0 site=react_native_fb) This comment suppresses an
|
||||
* error found when Flow v0.122.0 was deployed. To see the error, delete
|
||||
* this comment and run Flow. */
|
||||
validAttributes: {
|
||||
...ReactNativeViewViewConfig.validAttributes,
|
||||
...(viewConfig.validAttributes || {}),
|
||||
},
|
||||
};
|
||||
|
||||
ReactNativeViewConfigRegistry.register(componentName, () => {
|
||||
verifyComponentAttributeEquivalence(componentName, mergedViewConfig);
|
||||
|
||||
return mergedViewConfig;
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = registerGeneratedViewConfig;
|
71
node_modules/react-native/Libraries/Utilities/setAndForwardRef.js
generated
vendored
Normal file
71
node_modules/react-native/Libraries/Utilities/setAndForwardRef.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ElementRef, Ref} from 'react';
|
||||
|
||||
type Args = $ReadOnly<{|
|
||||
getForwardedRef: () => ?Ref<any>,
|
||||
setLocalRef: (ref: ElementRef<any>) => mixed,
|
||||
|}>;
|
||||
|
||||
/**
|
||||
* This is a helper function for when a component needs to be able to forward a ref
|
||||
* to a child component, but still needs to have access to that component as part of
|
||||
* its implementation.
|
||||
*
|
||||
* Its main use case is in wrappers for native components.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* class MyView extends React.Component {
|
||||
* _nativeRef = null;
|
||||
*
|
||||
* _setNativeRef = setAndForwardRef({
|
||||
* getForwardedRef: () => this.props.forwardedRef,
|
||||
* setLocalRef: ref => {
|
||||
* this._nativeRef = ref;
|
||||
* },
|
||||
* });
|
||||
*
|
||||
* render() {
|
||||
* return <View ref={this._setNativeRef} />;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* const MyViewWithRef = React.forwardRef((props, ref) => (
|
||||
* <MyView {...props} forwardedRef={ref} />
|
||||
* ));
|
||||
*
|
||||
* module.exports = MyViewWithRef;
|
||||
*/
|
||||
|
||||
function setAndForwardRef({
|
||||
getForwardedRef,
|
||||
setLocalRef,
|
||||
}: Args): (ref: ElementRef<any>) => void {
|
||||
return function forwardRef(ref: ElementRef<any>) {
|
||||
const forwardedRef = getForwardedRef();
|
||||
|
||||
setLocalRef(ref);
|
||||
|
||||
// Forward to user ref prop (if one has been specified)
|
||||
if (typeof forwardedRef === 'function') {
|
||||
// Handle function-based refs. String-based refs are handled as functions.
|
||||
forwardedRef(ref);
|
||||
} else if (typeof forwardedRef === 'object' && forwardedRef != null) {
|
||||
// Handle createRef-based refs
|
||||
forwardedRef.current = ref;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = setAndForwardRef;
|
121
node_modules/react-native/Libraries/Utilities/stringifySafe.js
generated
vendored
Normal file
121
node_modules/react-native/Libraries/Utilities/stringifySafe.js
generated
vendored
Normal file
@ -0,0 +1,121 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import invariant from 'invariant';
|
||||
|
||||
/**
|
||||
* Tries to stringify with JSON.stringify and toString, but catches exceptions
|
||||
* (e.g. from circular objects) and always returns a string and never throws.
|
||||
*/
|
||||
export function createStringifySafeWithLimits(limits: {|
|
||||
maxDepth?: number,
|
||||
maxStringLimit?: number,
|
||||
maxArrayLimit?: number,
|
||||
maxObjectKeysLimit?: number,
|
||||
|}): mixed => string {
|
||||
const {
|
||||
maxDepth = Number.POSITIVE_INFINITY,
|
||||
maxStringLimit = Number.POSITIVE_INFINITY,
|
||||
maxArrayLimit = Number.POSITIVE_INFINITY,
|
||||
maxObjectKeysLimit = Number.POSITIVE_INFINITY,
|
||||
} = limits;
|
||||
const stack = [];
|
||||
function replacer(key: string, value: mixed): mixed {
|
||||
while (stack.length && this !== stack[0]) {
|
||||
stack.shift();
|
||||
}
|
||||
|
||||
if (typeof value === 'string') {
|
||||
const truncatedString = '...(truncated)...';
|
||||
if (value.length > maxStringLimit + truncatedString.length) {
|
||||
return value.substring(0, maxStringLimit) + truncatedString;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
if (typeof value !== 'object' || value === null) {
|
||||
return value;
|
||||
}
|
||||
|
||||
let retval = value;
|
||||
if (Array.isArray(value)) {
|
||||
if (stack.length >= maxDepth) {
|
||||
retval = `[ ... array with ${value.length} values ... ]`;
|
||||
} else if (value.length > maxArrayLimit) {
|
||||
retval = value
|
||||
.slice(0, maxArrayLimit)
|
||||
.concat([
|
||||
`... extra ${value.length - maxArrayLimit} values truncated ...`,
|
||||
]);
|
||||
}
|
||||
} else {
|
||||
// Add refinement after Array.isArray call.
|
||||
invariant(typeof value === 'object', 'This was already found earlier');
|
||||
let keys = Object.keys(value);
|
||||
if (stack.length >= maxDepth) {
|
||||
retval = `{ ... object with ${keys.length} keys ... }`;
|
||||
} else if (keys.length > maxObjectKeysLimit) {
|
||||
// Return a sample of the keys.
|
||||
retval = {};
|
||||
for (let k of keys.slice(0, maxObjectKeysLimit)) {
|
||||
retval[k] = value[k];
|
||||
}
|
||||
const truncatedKey = '...(truncated keys)...';
|
||||
retval[truncatedKey] = keys.length - maxObjectKeysLimit;
|
||||
}
|
||||
}
|
||||
stack.unshift(retval);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return function stringifySafe(arg: mixed): string {
|
||||
if (arg === undefined) {
|
||||
return 'undefined';
|
||||
} else if (arg === null) {
|
||||
return 'null';
|
||||
} else if (typeof arg === 'function') {
|
||||
try {
|
||||
return arg.toString();
|
||||
} catch (e) {
|
||||
return '[function unknown]';
|
||||
}
|
||||
} else if (arg instanceof Error) {
|
||||
return arg.name + ': ' + arg.message;
|
||||
} else {
|
||||
// Perform a try catch, just in case the object has a circular
|
||||
// reference or stringify throws for some other reason.
|
||||
try {
|
||||
const ret = JSON.stringify(arg, replacer);
|
||||
if (ret === undefined) {
|
||||
return '["' + typeof arg + '" failed to stringify]';
|
||||
}
|
||||
return ret;
|
||||
} catch (e) {
|
||||
if (typeof arg.toString === 'function') {
|
||||
try {
|
||||
// $FlowFixMe: toString shouldn't take any arguments in general.
|
||||
return arg.toString();
|
||||
} catch (E) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
return '["' + typeof arg + '" failed to stringify]';
|
||||
};
|
||||
}
|
||||
|
||||
const stringifySafe: mixed => string = createStringifySafeWithLimits({
|
||||
maxDepth: 10,
|
||||
maxStringLimit: 100,
|
||||
maxArrayLimit: 50,
|
||||
maxObjectKeysLimit: 50,
|
||||
});
|
||||
|
||||
export default stringifySafe;
|
51
node_modules/react-native/Libraries/Utilities/truncate.js
generated
vendored
Normal file
51
node_modules/react-native/Libraries/Utilities/truncate.js
generated
vendored
Normal file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
type truncateOptions = {
|
||||
breakOnWords: boolean,
|
||||
minDelta: number,
|
||||
elipsis: string,
|
||||
...
|
||||
};
|
||||
|
||||
const defaultOptions = {
|
||||
breakOnWords: true,
|
||||
minDelta: 10, // Prevents truncating a tiny bit off the end
|
||||
elipsis: '...',
|
||||
};
|
||||
|
||||
// maxChars (including ellipsis)
|
||||
const truncate = function(
|
||||
str: ?string,
|
||||
maxChars: number,
|
||||
options?: truncateOptions,
|
||||
): ?string {
|
||||
options = Object.assign({}, defaultOptions, options);
|
||||
if (
|
||||
str &&
|
||||
str.length &&
|
||||
str.length - options.minDelta + options.elipsis.length >= maxChars
|
||||
) {
|
||||
// If the slice is happening in the middle of a wide char, add one more char
|
||||
const extraChar =
|
||||
str.charCodeAt(maxChars - options.elipsis.length) > 255 ? 1 : 0;
|
||||
str = str.slice(0, maxChars - options.elipsis.length + 1 + extraChar);
|
||||
if (options.breakOnWords) {
|
||||
const ii = Math.max(str.lastIndexOf(' '), str.lastIndexOf('\n'));
|
||||
str = str.slice(0, ii);
|
||||
}
|
||||
str = str.trim() + options.elipsis;
|
||||
}
|
||||
return str;
|
||||
};
|
||||
|
||||
module.exports = truncate;
|
31
node_modules/react-native/Libraries/Utilities/useColorScheme.js
generated
vendored
Normal file
31
node_modules/react-native/Libraries/Utilities/useColorScheme.js
generated
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import {useMemo} from 'react';
|
||||
import {useSubscription} from 'use-subscription';
|
||||
import Appearance from './Appearance';
|
||||
import type {ColorSchemeName} from './NativeAppearance';
|
||||
|
||||
export default function useColorScheme(): ?ColorSchemeName {
|
||||
const subscription = useMemo(
|
||||
() => ({
|
||||
getCurrentValue: () => Appearance.getColorScheme(),
|
||||
subscribe: callback => {
|
||||
Appearance.addChangeListener(callback);
|
||||
return () => Appearance.removeChangeListener(callback);
|
||||
},
|
||||
}),
|
||||
[],
|
||||
);
|
||||
|
||||
return useSubscription(subscription);
|
||||
}
|
40
node_modules/react-native/Libraries/Utilities/useWindowDimensions.js
generated
vendored
Normal file
40
node_modules/react-native/Libraries/Utilities/useWindowDimensions.js
generated
vendored
Normal file
@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import Dimensions from './Dimensions';
|
||||
import {type DisplayMetrics} from './NativeDeviceInfo';
|
||||
import {useEffect, useState} from 'react';
|
||||
|
||||
export default function useWindowDimensions(): DisplayMetrics {
|
||||
const [dimensions, setDimensions] = useState(() => Dimensions.get('window'));
|
||||
useEffect(() => {
|
||||
function handleChange({window}) {
|
||||
if (
|
||||
dimensions.width !== window.width ||
|
||||
dimensions.height !== window.height ||
|
||||
dimensions.scale !== window.scale ||
|
||||
dimensions.fontScale !== window.fontScale
|
||||
) {
|
||||
setDimensions(window);
|
||||
}
|
||||
}
|
||||
Dimensions.addEventListener('change', handleChange);
|
||||
// We might have missed an update between calling `get` in render and
|
||||
// `addEventListener` in this handler, so we set it here. If there was
|
||||
// no change, React will filter out this update as a no-op.
|
||||
handleChange({window: Dimensions.get('window')});
|
||||
return () => {
|
||||
Dimensions.removeEventListener('change', handleChange);
|
||||
};
|
||||
}, [dimensions]);
|
||||
return dimensions;
|
||||
}
|
134
node_modules/react-native/Libraries/Utilities/verifyComponentAttributeEquivalence.js
generated
vendored
Normal file
134
node_modules/react-native/Libraries/Utilities/verifyComponentAttributeEquivalence.js
generated
vendored
Normal file
@ -0,0 +1,134 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const getNativeComponentAttributes = require('../ReactNative/getNativeComponentAttributes');
|
||||
|
||||
import ReactNativeViewViewConfig from '../Components/View/ReactNativeViewViewConfig';
|
||||
import type {ReactNativeBaseComponentViewConfig} from '../Renderer/shims/ReactNativeTypes';
|
||||
|
||||
const IGNORED_KEYS = ['transform', 'hitSlop'];
|
||||
/**
|
||||
* The purpose of this function is to validate that the view config that
|
||||
* native exposes for a given view manager is the same as the view config
|
||||
* that is specified for that view manager in JS.
|
||||
*
|
||||
* In order to improve perf, we want to avoid calling into native to get
|
||||
* the view config when each view manager is used. To do this, we are moving
|
||||
* the configs to JS. In the future we will use these JS based view configs
|
||||
* to codegen the view manager on native to ensure they stay in sync without
|
||||
* this runtime check.
|
||||
*
|
||||
* If this function fails, that likely means a change was made to the native
|
||||
* view manager without updating the JS config as well. Ideally you can make
|
||||
* that direct change to the JS config. If you don't know what the differences
|
||||
* are, the best approach I've found is to create a view that prints
|
||||
* the return value of getNativeComponentAttributes, and then copying that
|
||||
* text and pasting it back into JS:
|
||||
* <Text selectable={true}>{JSON.stringify(getNativeComponentAttributes('RCTView'))}</Text>
|
||||
*
|
||||
* This is meant to be a stopgap until the time comes when we only have a
|
||||
* single source of truth. I wonder if this message will still be here two
|
||||
* years from now...
|
||||
*/
|
||||
function verifyComponentAttributeEquivalence(
|
||||
componentName: string,
|
||||
config: ReactNativeBaseComponentViewConfig<>,
|
||||
) {
|
||||
if (!global.RN$Bridgeless) {
|
||||
const nativeAttributes = getNativeComponentAttributes(componentName);
|
||||
|
||||
['validAttributes', 'bubblingEventTypes', 'directEventTypes'].forEach(
|
||||
prop => {
|
||||
const diffKeys = Object.keys(
|
||||
lefthandObjectDiff(nativeAttributes[prop], config[prop]),
|
||||
);
|
||||
|
||||
if (diffKeys.length) {
|
||||
console.error(
|
||||
`${componentName} generated view config for ${prop} does not match native, missing: ${diffKeys.join(
|
||||
' ',
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export function lefthandObjectDiff(leftObj: Object, rightObj: Object): Object {
|
||||
const differentKeys = {};
|
||||
|
||||
function compare(leftItem, rightItem, key) {
|
||||
if (typeof leftItem !== typeof rightItem && leftItem != null) {
|
||||
differentKeys[key] = rightItem;
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeof leftItem === 'object') {
|
||||
const objDiff = lefthandObjectDiff(leftItem, rightItem);
|
||||
if (Object.keys(objDiff).length > 1) {
|
||||
differentKeys[key] = objDiff;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (leftItem !== rightItem) {
|
||||
differentKeys[key] = rightItem;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (const key in leftObj) {
|
||||
if (IGNORED_KEYS.includes(key)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!rightObj) {
|
||||
differentKeys[key] = {};
|
||||
} else if (leftObj.hasOwnProperty(key)) {
|
||||
compare(leftObj[key], rightObj[key], key);
|
||||
}
|
||||
}
|
||||
|
||||
return differentKeys;
|
||||
}
|
||||
|
||||
export function getConfigWithoutViewProps(
|
||||
viewConfig: ReactNativeBaseComponentViewConfig<>,
|
||||
propName: string,
|
||||
): {...} {
|
||||
if (!viewConfig[propName]) {
|
||||
return {};
|
||||
}
|
||||
|
||||
return Object.keys(viewConfig[propName])
|
||||
.filter(prop => !ReactNativeViewViewConfig[propName][prop])
|
||||
.reduce((obj, prop) => {
|
||||
obj[prop] = viewConfig[propName][prop];
|
||||
return obj;
|
||||
}, {});
|
||||
}
|
||||
|
||||
export function stringifyViewConfig(viewConfig: any): string {
|
||||
return JSON.stringify(
|
||||
viewConfig,
|
||||
(key, val) => {
|
||||
if (typeof val === 'function') {
|
||||
return `ƒ ${val.name}`;
|
||||
}
|
||||
return val;
|
||||
},
|
||||
2,
|
||||
);
|
||||
}
|
||||
|
||||
export default verifyComponentAttributeEquivalence;
|
34
node_modules/react-native/Libraries/Utilities/warnOnce.js
generated
vendored
Normal file
34
node_modules/react-native/Libraries/Utilities/warnOnce.js
generated
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const warning = require('fbjs/lib/warning');
|
||||
|
||||
const warnedKeys: {[string]: boolean, ...} = {};
|
||||
|
||||
/**
|
||||
* A simple function that prints a warning message once per session.
|
||||
*
|
||||
* @param {string} key - The key used to ensure the message is printed once.
|
||||
* This should be unique to the callsite.
|
||||
* @param {string} message - The message to print
|
||||
*/
|
||||
function warnOnce(key: string, message: string) {
|
||||
if (warnedKeys[key]) {
|
||||
return;
|
||||
}
|
||||
|
||||
warning(false, message);
|
||||
|
||||
warnedKeys[key] = true;
|
||||
}
|
||||
|
||||
module.exports = warnOnce;
|
Reference in New Issue
Block a user