mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
c05f39ec3e
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/53494 Changelog: [Internal] Reviewed By: lenaic Differential Revision: D81203760 fbshipit-source-id: 185d6b3a6cd06d58c770dd04c68cc707a7621f08
45178 lines
1.6 MiB
Plaintext
45178 lines
1.6 MiB
Plaintext
/*
|
|
* This file is generated, do not edit.
|
|
* @generated
|
|
*
|
|
* @file_count 1208
|
|
* @generate-command: node tools/api/public-api.js
|
|
*/
|
|
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTAppDelegate.h}:
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h}
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h}
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTJSRuntimeConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef UIView *_Nonnull (
|
|
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
|
|
typedef RCTBridge *_Nonnull (
|
|
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
|
|
typedef void (^RCTCustomizeRootViewBlock)(UIView *rootView);
|
|
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
|
|
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
|
|
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
|
|
typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
|
|
RCTBridge *bridge,
|
|
RCTSourceLoadProgressBlock onProgress,
|
|
RCTSourceLoadBlock loadCallback);
|
|
typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
|
|
@interface RCTRootViewFactoryConfiguration : NSObject
|
|
@property (nonatomic, assign, readonly) BOOL fabricEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL bridgelessEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL turboModuleEnabled;
|
|
@property (nonatomic, nonnull) RCTBundleURLBlock bundleURLBlock;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled NS_DESIGNATED_INITIALIZER __deprecated;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled __deprecated;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock newArchEnabled:(BOOL)newArchEnabled;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled;
|
|
@property (nonatomic, nullable) RCTCreateRootViewWithBridgeBlock createRootViewWithBridge;
|
|
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
|
|
@property (nonatomic, nullable) RCTCustomizeRootViewBlock customizeRootView;
|
|
@property (nonatomic, weak, nullable) id<RCTJSRuntimeConfiguratorProtocol> jsRuntimeConfiguratorDelegate;
|
|
@property (nonatomic, nullable) RCTSourceURLForBridgeBlock sourceURLForBridge;
|
|
@property (nonatomic, nullable) RCTExtraModulesForBridgeBlock extraModulesForBridge;
|
|
@property (nonatomic, nullable) RCTExtraLazyModuleClassesForBridge extraLazyModuleClassesForBridge;
|
|
@property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
|
|
@end
|
|
@interface RCTRootViewFactory : NSObject
|
|
@property (nonatomic, strong, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nullable) RCTHost *reactHost;
|
|
@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
|
|
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate> _Nullable)turboModuleManagerDelegate;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (instancetype)initWithTurboModuleDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
hostDelegate:(id<RCTHostDelegate>)hostdelegate
|
|
configuration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties
|
|
launchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName;
|
|
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (RCTHost *)createReactHost:(NSDictionary *__nullable)launchOptions;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable };
|
|
@protocol RCTReactNativeFactoryDelegate <
|
|
RCTBridgeDelegate,
|
|
RCTUIConfiguratorProtocol,
|
|
RCTHostDelegate,
|
|
RCTTurboModuleManagerDelegate,
|
|
RCTComponentViewFactoryComponentProvider,
|
|
RCTJSRuntimeConfiguratorProtocol,
|
|
RCTArchConfiguratorProtocol>
|
|
- (NSURL *__nullable)bundleURL;
|
|
@property (nonatomic, strong) id<RCTDependencyProvider> dependencyProvider;
|
|
@optional
|
|
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions;
|
|
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initProps:(NSDictionary *)initProps;
|
|
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
|
|
@end
|
|
@interface RCTReactNativeFactory : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate;
|
|
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate releaseLevel:(RCTReleaseLevel)releaseLevel;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName inWindow:(UIWindow *_Nullable)window;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName
|
|
inWindow:(UIWindow *_Nullable)window
|
|
launchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName
|
|
inWindow:(UIWindow *_Nullable)window
|
|
initialProperties:(NSDictionary *_Nullable)initialProperties
|
|
launchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
@property (nonatomic, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
|
|
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
@property (nonatomic, weak) id<RCTReactNativeFactoryDelegate> delegate;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTDefaultReactNativeFactoryDelegate : UIResponder <RCTReactNativeFactoryDelegate>
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
__attribute__((deprecated(
|
|
"RCTAppDelegate is deprecated and will be removed in a future version of React Native. Use `RCTReactNativeFactory` instead.")))
|
|
@interface RCTAppDelegate : RCTDefaultReactNativeFactoryDelegate<UIApplicationDelegate>
|
|
@property (nonatomic, strong, nonnull) UIWindow *window;
|
|
@property (nonatomic, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nullable) NSString *moduleName;
|
|
@property (nonatomic, strong, nullable) NSDictionary *initialProps;
|
|
@property (nonatomic, strong) RCTReactNativeFactory *reactNativeFactory;
|
|
@property (nonatomic, assign) BOOL automaticallyLoadReactNativeWindow;
|
|
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
- (RCTRootViewFactory *)rootViewFactory;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTAppSetupUtils.h}:
|
|
|
|
namespace facebook::react {
|
|
}
|
|
RCT_EXTERN NSArray<NSString *> *RCTAppSetupUnstableModulesRequiringMainQueueSetup(
|
|
id<RCTDependencyProvider> dependencyProvider);
|
|
RCT_EXTERN id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(
|
|
Class moduleClass,
|
|
id<RCTDependencyProvider> dependencyProvider);
|
|
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutorFactory(
|
|
RCTBridge *bridge,
|
|
RCTTurboModuleManager *turboModuleManager,
|
|
const std::shared_ptr<facebook::react::RuntimeScheduler> &runtimeScheduler);
|
|
std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupJsExecutorFactoryForOldArch(
|
|
RCTBridge *bridge,
|
|
const std::shared_ptr<facebook::react::RuntimeScheduler> &runtimeScheduler);
|
|
RCT_EXTERN_C_BEGIN
|
|
void RCTAppSetupPrepareApp(UIApplication *application, BOOL turboModuleEnabled);
|
|
UIView *RCTAppSetupDefaultRootView(
|
|
RCTBridge *bridge,
|
|
NSString *moduleName,
|
|
NSDictionary *initialProperties,
|
|
BOOL fabricEnabled);
|
|
RCT_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTArchConfiguratorProtocol
|
|
- (BOOL)turboModuleEnabled __attribute__((deprecated("Use RCTIsNewArchEnabled instead")));
|
|
- (BOOL)fabricEnabled __attribute__((deprecated("Use RCTIsNewArchEnabled instead")));
|
|
- (BOOL)bridgelessEnabled __attribute__((deprecated("Use RCTIsNewArchEnabled instead")));
|
|
- (BOOL)newArchEnabled __attribute__((deprecated("Use RCTIsNewArchEnabled instead")));
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTDefaultReactNativeFactoryDelegate.h}:
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h}
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h}
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTJSRuntimeConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef UIView *_Nonnull (
|
|
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
|
|
typedef RCTBridge *_Nonnull (
|
|
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
|
|
typedef void (^RCTCustomizeRootViewBlock)(UIView *rootView);
|
|
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
|
|
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
|
|
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
|
|
typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
|
|
RCTBridge *bridge,
|
|
RCTSourceLoadProgressBlock onProgress,
|
|
RCTSourceLoadBlock loadCallback);
|
|
typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
|
|
@interface RCTRootViewFactoryConfiguration : NSObject
|
|
@property (nonatomic, assign, readonly) BOOL fabricEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL bridgelessEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL turboModuleEnabled;
|
|
@property (nonatomic, nonnull) RCTBundleURLBlock bundleURLBlock;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled NS_DESIGNATED_INITIALIZER __deprecated;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled __deprecated;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock newArchEnabled:(BOOL)newArchEnabled;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled;
|
|
@property (nonatomic, nullable) RCTCreateRootViewWithBridgeBlock createRootViewWithBridge;
|
|
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
|
|
@property (nonatomic, nullable) RCTCustomizeRootViewBlock customizeRootView;
|
|
@property (nonatomic, weak, nullable) id<RCTJSRuntimeConfiguratorProtocol> jsRuntimeConfiguratorDelegate;
|
|
@property (nonatomic, nullable) RCTSourceURLForBridgeBlock sourceURLForBridge;
|
|
@property (nonatomic, nullable) RCTExtraModulesForBridgeBlock extraModulesForBridge;
|
|
@property (nonatomic, nullable) RCTExtraLazyModuleClassesForBridge extraLazyModuleClassesForBridge;
|
|
@property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
|
|
@end
|
|
@interface RCTRootViewFactory : NSObject
|
|
@property (nonatomic, strong, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nullable) RCTHost *reactHost;
|
|
@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
|
|
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate> _Nullable)turboModuleManagerDelegate;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (instancetype)initWithTurboModuleDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
hostDelegate:(id<RCTHostDelegate>)hostdelegate
|
|
configuration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties
|
|
launchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName;
|
|
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (RCTHost *)createReactHost:(NSDictionary *__nullable)launchOptions;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable };
|
|
@protocol RCTReactNativeFactoryDelegate <
|
|
RCTBridgeDelegate,
|
|
RCTUIConfiguratorProtocol,
|
|
RCTHostDelegate,
|
|
RCTTurboModuleManagerDelegate,
|
|
RCTComponentViewFactoryComponentProvider,
|
|
RCTJSRuntimeConfiguratorProtocol,
|
|
RCTArchConfiguratorProtocol>
|
|
- (NSURL *__nullable)bundleURL;
|
|
@property (nonatomic, strong) id<RCTDependencyProvider> dependencyProvider;
|
|
@optional
|
|
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions;
|
|
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initProps:(NSDictionary *)initProps;
|
|
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
|
|
@end
|
|
@interface RCTReactNativeFactory : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate;
|
|
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate releaseLevel:(RCTReleaseLevel)releaseLevel;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName inWindow:(UIWindow *_Nullable)window;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName
|
|
inWindow:(UIWindow *_Nullable)window
|
|
launchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName
|
|
inWindow:(UIWindow *_Nullable)window
|
|
initialProperties:(NSDictionary *_Nullable)initialProperties
|
|
launchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
@property (nonatomic, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
|
|
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
@property (nonatomic, weak) id<RCTReactNativeFactoryDelegate> delegate;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTDefaultReactNativeFactoryDelegate : UIResponder <RCTReactNativeFactoryDelegate>
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTDependencyProvider <NSObject>
|
|
- (NSArray<NSString *> *)imageURLLoaderClassNames;
|
|
- (NSArray<NSString *> *)imageDataDecoderClassNames;
|
|
- (NSArray<NSString *> *)URLRequestHandlerClassNames;
|
|
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
|
|
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
|
|
- (nonnull NSDictionary<NSString *, id<RCTModuleProvider>> *)moduleProviders;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTJSRuntimeConfiguratorProtocol.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef void *JSRuntimeFactoryRef;
|
|
@protocol RCTJSRuntimeConfiguratorProtocol
|
|
- (JSRuntimeFactoryRef)createJSRuntimeFactory;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTReactNativeFactory.h}:
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTArchConfiguratorProtocol.h}
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTDependencyProvider.h}
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTJSRuntimeConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef UIView *_Nonnull (
|
|
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
|
|
typedef RCTBridge *_Nonnull (
|
|
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
|
|
typedef void (^RCTCustomizeRootViewBlock)(UIView *rootView);
|
|
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
|
|
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
|
|
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
|
|
typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
|
|
RCTBridge *bridge,
|
|
RCTSourceLoadProgressBlock onProgress,
|
|
RCTSourceLoadBlock loadCallback);
|
|
typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
|
|
@interface RCTRootViewFactoryConfiguration : NSObject
|
|
@property (nonatomic, assign, readonly) BOOL fabricEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL bridgelessEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL turboModuleEnabled;
|
|
@property (nonatomic, nonnull) RCTBundleURLBlock bundleURLBlock;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled NS_DESIGNATED_INITIALIZER __deprecated;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled __deprecated;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock newArchEnabled:(BOOL)newArchEnabled;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled;
|
|
@property (nonatomic, nullable) RCTCreateRootViewWithBridgeBlock createRootViewWithBridge;
|
|
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
|
|
@property (nonatomic, nullable) RCTCustomizeRootViewBlock customizeRootView;
|
|
@property (nonatomic, weak, nullable) id<RCTJSRuntimeConfiguratorProtocol> jsRuntimeConfiguratorDelegate;
|
|
@property (nonatomic, nullable) RCTSourceURLForBridgeBlock sourceURLForBridge;
|
|
@property (nonatomic, nullable) RCTExtraModulesForBridgeBlock extraModulesForBridge;
|
|
@property (nonatomic, nullable) RCTExtraLazyModuleClassesForBridge extraLazyModuleClassesForBridge;
|
|
@property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
|
|
@end
|
|
@interface RCTRootViewFactory : NSObject
|
|
@property (nonatomic, strong, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nullable) RCTHost *reactHost;
|
|
@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
|
|
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate> _Nullable)turboModuleManagerDelegate;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (instancetype)initWithTurboModuleDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
hostDelegate:(id<RCTHostDelegate>)hostdelegate
|
|
configuration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties
|
|
launchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName;
|
|
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (RCTHost *)createReactHost:(NSDictionary *__nullable)launchOptions;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_ENUM(NSInteger, RCTReleaseLevel) { Canary, Experimental, Stable };
|
|
@protocol RCTReactNativeFactoryDelegate <
|
|
RCTBridgeDelegate,
|
|
RCTUIConfiguratorProtocol,
|
|
RCTHostDelegate,
|
|
RCTTurboModuleManagerDelegate,
|
|
RCTComponentViewFactoryComponentProvider,
|
|
RCTJSRuntimeConfiguratorProtocol,
|
|
RCTArchConfiguratorProtocol>
|
|
- (NSURL *__nullable)bundleURL;
|
|
@property (nonatomic, strong) id<RCTDependencyProvider> dependencyProvider;
|
|
@optional
|
|
- (RCTBridge *)createBridgeWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions;
|
|
- (UIView *)createRootViewWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initProps:(NSDictionary *)initProps;
|
|
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
|
|
@end
|
|
@interface RCTReactNativeFactory : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate;
|
|
- (instancetype)initWithDelegate:(id<RCTReactNativeFactoryDelegate>)delegate releaseLevel:(RCTReleaseLevel)releaseLevel;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName inWindow:(UIWindow *_Nullable)window;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName
|
|
inWindow:(UIWindow *_Nullable)window
|
|
launchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
- (void)startReactNativeWithModuleName:(NSString *)moduleName
|
|
inWindow:(UIWindow *_Nullable)window
|
|
initialProperties:(NSDictionary *_Nullable)initialProperties
|
|
launchOptions:(NSDictionary *_Nullable)launchOptions;
|
|
@property (nonatomic, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nonnull) RCTRootViewFactory *rootViewFactory;
|
|
@property (nonatomic, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
@property (nonatomic, weak) id<RCTReactNativeFactoryDelegate> delegate;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTRootViewFactory.h}:
|
|
/// @dep {packages/react-native/Libraries/AppDelegate/RCTJSRuntimeConfiguratorProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef UIView *_Nonnull (
|
|
^RCTCreateRootViewWithBridgeBlock)(RCTBridge *bridge, NSString *moduleName, NSDictionary *initProps);
|
|
typedef RCTBridge *_Nonnull (
|
|
^RCTCreateBridgeWithDelegateBlock)(id<RCTBridgeDelegate> delegate, NSDictionary *launchOptions);
|
|
typedef void (^RCTCustomizeRootViewBlock)(UIView *rootView);
|
|
typedef NSURL *_Nullable (^RCTSourceURLForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSURL *_Nullable (^RCTBundleURLBlock)(void);
|
|
typedef NSArray<id<RCTBridgeModule>> *_Nonnull (^RCTExtraModulesForBridgeBlock)(RCTBridge *bridge);
|
|
typedef NSDictionary<NSString *, Class> *_Nonnull (^RCTExtraLazyModuleClassesForBridge)(RCTBridge *bridge);
|
|
typedef BOOL (^RCTBridgeDidNotFindModuleBlock)(RCTBridge *bridge, NSString *moduleName);
|
|
typedef void (^RCTLoadSourceForBridgeWithProgressBlock)(
|
|
RCTBridge *bridge,
|
|
RCTSourceLoadProgressBlock onProgress,
|
|
RCTSourceLoadBlock loadCallback);
|
|
typedef void (^RCTLoadSourceForBridgeBlock)(RCTBridge *bridge, RCTSourceLoadBlock loadCallback);
|
|
@interface RCTRootViewFactoryConfiguration : NSObject
|
|
@property (nonatomic, assign, readonly) BOOL fabricEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL bridgelessEnabled;
|
|
@property (nonatomic, assign, readonly) BOOL turboModuleEnabled;
|
|
@property (nonatomic, nonnull) RCTBundleURLBlock bundleURLBlock;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled NS_DESIGNATED_INITIALIZER __deprecated;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
newArchEnabled:(BOOL)newArchEnabled
|
|
turboModuleEnabled:(BOOL)turboModuleEnabled
|
|
bridgelessEnabled:(BOOL)bridgelessEnabled __deprecated;
|
|
- (instancetype)initWithBundleURLBlock:(RCTBundleURLBlock)bundleURLBlock newArchEnabled:(BOOL)newArchEnabled;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL newArchEnabled:(BOOL)newArchEnabled;
|
|
@property (nonatomic, nullable) RCTCreateRootViewWithBridgeBlock createRootViewWithBridge;
|
|
@property (nonatomic, nullable) RCTCreateBridgeWithDelegateBlock createBridgeWithDelegate;
|
|
@property (nonatomic, nullable) RCTCustomizeRootViewBlock customizeRootView;
|
|
@property (nonatomic, weak, nullable) id<RCTJSRuntimeConfiguratorProtocol> jsRuntimeConfiguratorDelegate;
|
|
@property (nonatomic, nullable) RCTSourceURLForBridgeBlock sourceURLForBridge;
|
|
@property (nonatomic, nullable) RCTExtraModulesForBridgeBlock extraModulesForBridge;
|
|
@property (nonatomic, nullable) RCTExtraLazyModuleClassesForBridge extraLazyModuleClassesForBridge;
|
|
@property (nonatomic, nullable) RCTBridgeDidNotFindModuleBlock bridgeDidNotFindModule;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeWithProgressBlock loadSourceForBridgeWithProgress;
|
|
@property (nonatomic, nullable) RCTLoadSourceForBridgeBlock loadSourceForBridge;
|
|
@end
|
|
@interface RCTRootViewFactory : NSObject
|
|
@property (nonatomic, strong, nullable) RCTBridge *bridge;
|
|
@property (nonatomic, strong, nullable) RCTHost *reactHost;
|
|
@property (nonatomic, strong, nullable) RCTSurfacePresenterBridgeAdapter *bridgeAdapter;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration
|
|
andTurboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate> _Nullable)turboModuleManagerDelegate;
|
|
- (instancetype)initWithConfiguration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (instancetype)initWithTurboModuleDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
hostDelegate:(id<RCTHostDelegate>)hostdelegate
|
|
configuration:(RCTRootViewFactoryConfiguration *)configuration;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties
|
|
launchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *__nullable)initialProperties;
|
|
- (UIView *_Nonnull)viewWithModuleName:(NSString *)moduleName;
|
|
- (void)initializeReactHostWithLaunchOptions:(NSDictionary *__nullable)launchOptions;
|
|
- (RCTHost *)createReactHost:(NSDictionary *__nullable)launchOptions;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/AppDelegate/RCTUIConfiguratorProtocol.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTUIConfiguratorProtocol
|
|
- (RCTColorSpace)defaultColorSpace;
|
|
- (void)customizeRootView:(RCTRootView *)rootView;
|
|
- (UIViewController *)createRootViewController;
|
|
- (void)setRootView:(UIView *)rootView toRootViewController:(UIViewController *)rootViewController;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Blob/RCTBlobCollector.h}:
|
|
|
|
namespace facebook::react {
|
|
class JSI_EXPORT RCTBlobCollector : public jsi::HostObject {
|
|
public:
|
|
RCTBlobCollector(RCTBlobManager *blobManager, const std::string &blobId);
|
|
~RCTBlobCollector();
|
|
static void install(RCTBlobManager *blobManager);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/Libraries/Blob/RCTBlobManager.h}:
|
|
@interface RCTBlobManager : NSObject <RCTBridgeModule, RCTURLRequestHandler, RCTInitializing>
|
|
- (NSString *)store:(NSData *)data;
|
|
- (void)store:(NSData *)data withId:(NSString *)blobId;
|
|
- (NSUInteger)lengthOfBlobWithId:(NSString *)blobId;
|
|
- (NSData *)resolve:(NSDictionary<NSString *, id> *)blob;
|
|
- (NSData *)resolve:(NSString *)blobId offset:(NSInteger)offset size:(NSInteger)size;
|
|
- (NSData *)resolveURL:(NSURL *)url;
|
|
- (void)remove:(NSString *)blobId;
|
|
- (void)createFromParts:(NSArray<NSDictionary<NSString *, id> *> *)parts withId:(NSString *)blobId;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Blob/RCTBlobPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTBlobClassProvider(const char* name);
|
|
Class RCTBlobManagerCls(void) __attribute__((used));
|
|
Class RCTFileReaderModuleCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/Blob/RCTFileReaderModule.h}:
|
|
@interface RCTFileReaderModule : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/FBLazyVector/FBLazyVector/FBLazyIterator.h}:
|
|
namespace FB {
|
|
template <typename T, typename U>
|
|
class LazyIterator {
|
|
public:
|
|
using value_type = T;
|
|
using pointer = std::unique_ptr<T>;
|
|
using reference = T;
|
|
using iterator_category = std::random_access_iterator_tag;
|
|
using difference_type = std::int32_t;
|
|
using size_type = std::int32_t;
|
|
using convert_type = std::function<T(U)>;
|
|
|
|
public:
|
|
LazyIterator() = default;
|
|
LazyIterator(U vector, convert_type convert, size_type i)
|
|
: _v(vector), _i(i), _convert(std::move(convert)) {}
|
|
bool operator==(const LazyIterator& other) const {
|
|
return _i == other._i && _v == other._v;
|
|
}
|
|
bool operator<(const LazyIterator& b) const {
|
|
return _i < b._i;
|
|
}
|
|
value_type operator*() const {
|
|
return _convert(_v[_i]);
|
|
}
|
|
std::unique_ptr<value_type> operator->() const {
|
|
return std::make_unique<value_type>(*this);
|
|
}
|
|
LazyIterator operator+(difference_type n) const {
|
|
return LazyIterator(_v, _convert, _i + n);
|
|
}
|
|
LazyIterator& operator+=(difference_type n) {
|
|
_i += n;
|
|
return *this;
|
|
}
|
|
LazyIterator& operator-=(difference_type n) {
|
|
_i -= n;
|
|
return *this;
|
|
}
|
|
LazyIterator operator-(difference_type n) const {
|
|
return LazyIterator(_v, _i - n);
|
|
}
|
|
difference_type operator-(const LazyIterator& a) const {
|
|
return _i - a._i;
|
|
}
|
|
LazyIterator& operator++() {
|
|
return *this += 1;
|
|
}
|
|
LazyIterator operator++(int) {
|
|
auto tmp = *this;
|
|
++*this;
|
|
return tmp;
|
|
}
|
|
LazyIterator& operator--() {
|
|
return *this -= 1;
|
|
}
|
|
LazyIterator operator--(int) {
|
|
auto tmp = *this;
|
|
--*this;
|
|
return tmp;
|
|
}
|
|
value_type operator[](difference_type n) const {
|
|
return _convert(_v[_i + n]);
|
|
}
|
|
};
|
|
template <typename T, typename U>
|
|
LazyIterator<T, U> operator+(
|
|
typename LazyIterator<T, U>::difference_type n,
|
|
const LazyIterator<T, U>& i) {
|
|
return i + n;
|
|
}
|
|
template <typename T, typename U>
|
|
bool operator!=(const LazyIterator<T, U>& a, const LazyIterator<T, U>& b) {
|
|
return !(a == b);
|
|
}
|
|
template <typename T, typename U>
|
|
bool operator<=(const LazyIterator<T, U>& a, const LazyIterator<T, U>& b) {
|
|
return a < b || a == b;
|
|
}
|
|
template <typename T, typename U>
|
|
bool operator>(const LazyIterator<T, U>& a, const LazyIterator<T, U>& b) {
|
|
return b < a;
|
|
}
|
|
template <typename T, typename U>
|
|
bool operator>=(const LazyIterator<T, U>& a, const LazyIterator<T, U>& b) {
|
|
return a > b || a == b;
|
|
}
|
|
} // namespace FB
|
|
|
|
/// @src {packages/react-native/Libraries/FBLazyVector/FBLazyVector/FBLazyVector.h}:
|
|
namespace FB {
|
|
template <typename T, typename U>
|
|
class LazyVector {
|
|
public:
|
|
using value_type = T;
|
|
using reference = T;
|
|
using const_reference = T;
|
|
using const_iterator = LazyIterator<T, U>;
|
|
using iterator = const_iterator;
|
|
using size_type = std::int32_t;
|
|
using convert_type = std::function<T(U)>;
|
|
static LazyVector<T, U>
|
|
fromUnsafeRawValue(U v, size_type size, convert_type convert) {
|
|
return {v, size, convert};
|
|
}
|
|
U unsafeRawValue() const {
|
|
return _v;
|
|
}
|
|
bool empty() const {
|
|
return _size == 0;
|
|
}
|
|
size_type size() const {
|
|
return _size;
|
|
}
|
|
const_reference at(size_type pos) const {
|
|
if (!(pos < _size)) {
|
|
throw std::out_of_range("out of range");
|
|
}
|
|
return _convert(_v[pos]);
|
|
}
|
|
const_reference operator[](size_type pos) const {
|
|
assert(pos < _size);
|
|
return _convert(_v[pos]);
|
|
}
|
|
const_reference front() const {
|
|
assert(_size);
|
|
return (*this)[0];
|
|
}
|
|
const_reference back() const {
|
|
assert(_size);
|
|
return (*this)[_size - 1];
|
|
}
|
|
const_iterator begin() const {
|
|
return const_iterator(_v, _convert, 0);
|
|
}
|
|
const_iterator cbegin() const {
|
|
return begin();
|
|
}
|
|
const_iterator end() const {
|
|
return const_iterator(_v, _convert, _size);
|
|
}
|
|
const_iterator cend() const {
|
|
return end();
|
|
}
|
|
};
|
|
} // namespace FB
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTAnimatedImage.h}:
|
|
@protocol RCTAnimatedImage <NSObject>
|
|
@property (nonatomic, assign, readonly) NSUInteger animatedImageFrameCount;
|
|
@property (nonatomic, assign, readonly) NSUInteger animatedImageLoopCount;
|
|
- (nullable UIImage *)animatedImageFrameAtIndex:(NSUInteger)index;
|
|
- (NSTimeInterval)animatedImageDurationAtIndex:(NSUInteger)index;
|
|
@end
|
|
@interface RCTAnimatedImage : UIImage <RCTAnimatedImage>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTBundleAssetImageLoader.h}:
|
|
@interface RCTBundleAssetImageLoader : NSObject <RCTImageURLLoader>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTDisplayWeakRefreshable.h}:
|
|
@protocol RCTDisplayRefreshable
|
|
- (void)displayDidRefresh:(CADisplayLink *)displayLink;
|
|
@end
|
|
@interface RCTDisplayWeakRefreshable : NSObject
|
|
@property (nonatomic, weak) id<RCTDisplayRefreshable> refreshable;
|
|
+ (CADisplayLink *)displayLinkWithWeakRefreshable:(id<RCTDisplayRefreshable>)refreshable;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTGIFImageDecoder.h}:
|
|
@interface RCTGIFImageDecoder : NSObject <RCTImageDataDecoder>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageBlurUtils.h}:
|
|
RCT_EXTERN UIImage *RCTBlurredImageWithRadius(UIImage *inputImage, CGFloat radius);
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageCache.h}:
|
|
@interface UIImage (React)
|
|
@property (nonatomic, assign) NSInteger reactDecodedImageBytes;
|
|
@end
|
|
@protocol RCTImageCache <NSObject>
|
|
- (UIImage *)imageForUrl:(NSString *)url size:(CGSize)size scale:(CGFloat)scale resizeMode:(RCTResizeMode)resizeMode;
|
|
- (void)addImageToCache:(UIImage *)image
|
|
URL:(NSString *)url
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
response:(NSURLResponse *)response;
|
|
@end
|
|
@interface RCTImageCache : NSObject <RCTImageCache>
|
|
RCT_EXTERN void RCTSetImageCacheLimits(
|
|
NSUInteger maxCacheableDecodedImageSizeInBytes,
|
|
NSUInteger imageCacheTotalCostLimit);
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageDataDecoder.h}:
|
|
@protocol RCTImageDataDecoder <RCTBridgeModule>
|
|
- (BOOL)canDecodeImageData:(NSData *)imageData;
|
|
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler;
|
|
@optional
|
|
- (float)decoderPriority;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageEditingManager.h}:
|
|
@interface RCTImageEditingManager : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageLoader.h}:
|
|
@interface RCTImageLoader : NSObject <RCTBridgeModule, RCTImageLoaderProtocol, RCTImageLoaderLoggableProtocol>
|
|
- (instancetype)init;
|
|
- (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectDelegate NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithRedirectDelegate:(id<RCTImageRedirectProtocol>)redirectDelegate
|
|
loadersProvider:(NSArray<id<RCTImageURLLoader>> * (^)(RCTModuleRegistry *))getLoaders
|
|
decodersProvider:(NSArray<id<RCTImageDataDecoder>> * (^)(RCTModuleRegistry *))getDecoders;
|
|
@end
|
|
@interface RCTBridge (RCTImageLoader)
|
|
@property (nonatomic, readonly) RCTImageLoader *imageLoader;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTImageLoader)
|
|
@property (nonatomic, readonly) RCTImageLoader *imageLoader;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageLoaderLoggable.h}:
|
|
@protocol RCTImageLoaderLoggableProtocol <NSObject>
|
|
- (BOOL)shouldEnablePerfLoggingForRequestUrl:(NSURL *)url;
|
|
@end
|
|
@protocol RCTImageLoaderLoggable
|
|
- (BOOL)shouldEnablePerfLogging;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageLoaderProtocol.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTImageRedirectProtocol
|
|
- (NSURL *)redirectAssetsURL:(NSURL *)URL;
|
|
@end
|
|
typedef NS_ENUM(NSInteger, RCTImageLoaderPriority) { RCTImageLoaderPriorityImmediate, RCTImageLoaderPriorityPrefetch };
|
|
@protocol RCTImageLoaderProtocol <RCTURLRequestHandler>
|
|
@property (nonatomic, assign) NSUInteger maxConcurrentLoadingTasks;
|
|
@property (nonatomic, assign) NSUInteger maxConcurrentDecodingTasks;
|
|
@property (nonatomic, assign) NSUInteger maxConcurrentDecodingBytes;
|
|
- (nullable RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
|
|
callback:(RCTImageLoaderCompletionBlock)callback;
|
|
- (nullable RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
|
|
priority:(RCTImageLoaderPriority)priority
|
|
callback:(RCTImageLoaderCompletionBlock)callback;
|
|
- (nullable RCTImageLoaderCancellationBlock)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
clipped:(BOOL)clipped
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
|
|
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
|
|
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock;
|
|
- (RCTImageLoaderCancellationBlock)decodeImageData:(NSData *)imageData
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
clipped:(BOOL)clipped
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
completionBlock:(RCTImageLoaderCompletionBlock)completionBlock;
|
|
- (RCTImageLoaderCancellationBlock)getImageSizeForURLRequest:(NSURLRequest *)imageURLRequest
|
|
block:(void (^)(NSError *error, CGSize size))completionBlock;
|
|
- (NSDictionary *)getImageCacheStatus:(NSArray *)requests;
|
|
- (void)setImageCache:(id<RCTImageCache>)cache;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageLoaderWithAttributionProtocol.h}:
|
|
@protocol RCTImageLoaderWithAttributionProtocol <RCTImageLoaderProtocol, RCTImageLoaderLoggableProtocol>
|
|
- (RCTImageURLLoaderRequest *)loadImageWithURLRequest:(NSURLRequest *)imageURLRequest
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
clipped:(BOOL)clipped
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
priority:(RCTImageLoaderPriority)priority
|
|
attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution
|
|
progressBlock:(RCTImageLoaderProgressBlock)progressBlock
|
|
partialLoadBlock:(RCTImageLoaderPartialLoadBlock)partialLoadBlock
|
|
completionBlock:(RCTImageLoaderCompletionBlockWithMetadata)completionBlock;
|
|
- (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(UIView *)imageView;
|
|
- (void)trackURLImageRequestDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest;
|
|
- (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImagePlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTImageClassProvider(const char* name);
|
|
Class RCTGIFImageDecoderCls(void) __attribute__((used));
|
|
Class RCTImageEditingManagerCls(void) __attribute__((used));
|
|
Class RCTImageLoaderCls(void) __attribute__((used));
|
|
Class RCTImageStoreManagerCls(void) __attribute__((used));
|
|
Class RCTLocalAssetImageLoaderCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageShadowView.h}:
|
|
@interface RCTImageShadowView : RCTShadowView
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageStoreManager.h}:
|
|
RCT_EXTERN void RCTEnableImageStoreManagerStorageQueue(BOOL enabled);
|
|
@interface RCTImageStoreManager : NSObject <RCTURLRequestHandler>
|
|
- (void)removeImageForTag:(NSString *)imageTag withBlock:(void (^)(void))block;
|
|
- (void)storeImageData:(NSData *)imageData withBlock:(void (^)(NSString *imageTag))block;
|
|
- (void)getImageDataForTag:(NSString *)imageTag withBlock:(void (^)(NSData *imageData))block;
|
|
- (void)storeImage:(UIImage *)image withBlock:(void (^)(NSString *imageTag))block;
|
|
@end
|
|
@interface RCTImageStoreManager (Deprecated)
|
|
- (NSString *)storeImage:(UIImage *)image __deprecated;
|
|
- (UIImage *)imageForTag:(NSString *)imageTag __deprecated;
|
|
- (void)getImageForTag:(NSString *)imageTag withBlock:(void (^)(UIImage *image))block __deprecated;
|
|
@end
|
|
@interface RCTBridge (RCTImageStoreManager)
|
|
@property (nonatomic, readonly) RCTImageStoreManager *imageStoreManager;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTImageStoreManager)
|
|
@property (nonatomic, readonly) RCTImageStoreManager *imageStoreManager;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageURLLoader.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef void (^RCTImageLoaderProgressBlock)(int64_t progress, int64_t total);
|
|
typedef void (^RCTImageLoaderPartialLoadBlock)(UIImage *image);
|
|
typedef void (^RCTImageLoaderCompletionBlock)(NSError *_Nullable error, UIImage *_Nullable image);
|
|
typedef void (^RCTImageLoaderCompletionBlockWithMetadata)(
|
|
NSError *_Nullable error,
|
|
UIImage *_Nullable image,
|
|
id _Nullable metadata);
|
|
typedef dispatch_block_t RCTImageLoaderCancellationBlock;
|
|
@protocol RCTImageURLLoader <RCTBridgeModule>
|
|
- (BOOL)canLoadImageURL:(NSURL *)requestURL;
|
|
- (nullable RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
|
|
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
|
|
completionHandler:(RCTImageLoaderCompletionBlock)completionHandler
|
|
RCT_DEPRECATED;
|
|
@optional
|
|
- (nullable RCTImageLoaderCancellationBlock)loadImageForURL:(NSURL *)imageURL
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
|
|
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
|
|
completionHandlerWithMetadata:
|
|
(RCTImageLoaderCompletionBlockWithMetadata)completionHandlerWithMetadata;
|
|
- (float)loaderPriority;
|
|
- (BOOL)requiresScheduling;
|
|
- (BOOL)shouldCacheLoadedImages;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageURLLoaderWithAttribution.h}:
|
|
namespace facebook::react {
|
|
struct ImageURLLoaderAttribution {
|
|
int32_t nativeViewTag = 0;
|
|
int32_t surfaceId = 0;
|
|
std::string queryRootName;
|
|
NSString *analyticTag;
|
|
};
|
|
} // namespace facebook::react
|
|
@interface RCTImageURLLoaderRequest : NSObject
|
|
@property (nonatomic, strong, readonly) NSString *requestId;
|
|
@property (nonatomic, strong, readonly) NSURL *imageURL;
|
|
@property (nonatomic, copy, readonly) RCTImageLoaderCancellationBlock cancellationBlock;
|
|
- (instancetype)initWithRequestId:(NSString *)requestId
|
|
imageURL:(NSURL *)imageURL
|
|
cancellationBlock:(RCTImageLoaderCancellationBlock)cancellationBlock;
|
|
- (void)cancel;
|
|
@end
|
|
@protocol RCTImageURLLoaderWithAttribution <RCTImageURLLoader, RCTImageLoaderLoggable>
|
|
- (RCTImageURLLoaderRequest *)loadImageForURL:(NSURL *)imageURL
|
|
size:(CGSize)size
|
|
scale:(CGFloat)scale
|
|
resizeMode:(RCTResizeMode)resizeMode
|
|
requestId:(NSString *)requestId
|
|
priority:(RCTImageLoaderPriority)priority
|
|
attribution:(const facebook::react::ImageURLLoaderAttribution &)attribution
|
|
progressHandler:(RCTImageLoaderProgressBlock)progressHandler
|
|
partialLoadHandler:(RCTImageLoaderPartialLoadBlock)partialLoadHandler
|
|
completionHandler:(RCTImageLoaderCompletionBlockWithMetadata)completionHandler;
|
|
- (void)trackURLImageVisibilityForRequest:(RCTImageURLLoaderRequest *)loaderRequest imageView:(UIView *)imageView;
|
|
- (void)trackURLImageRequestDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest;
|
|
- (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN CGRect RCTTargetRect(CGSize sourceSize, CGSize destSize, CGFloat destScale, RCTResizeMode resizeMode);
|
|
RCT_EXTERN CGAffineTransform RCTTransformFromTargetRect(CGSize sourceSize, CGRect targetRect);
|
|
RCT_EXTERN CGSize RCTTargetSize(
|
|
CGSize sourceSize,
|
|
CGFloat sourceScale,
|
|
CGSize destSize,
|
|
CGFloat destScale,
|
|
RCTResizeMode resizeMode,
|
|
BOOL allowUpscaling);
|
|
RCT_EXTERN BOOL RCTUpscalingRequired(
|
|
CGSize sourceSize,
|
|
CGFloat sourceScale,
|
|
CGSize destSize,
|
|
CGFloat destScale,
|
|
RCTResizeMode resizeMode);
|
|
RCT_EXTERN UIImage *__nullable
|
|
RCTDecodeImageWithData(NSData *data, CGSize destSize, CGFloat destScale, RCTResizeMode resizeMode);
|
|
RCT_EXTERN NSDictionary<NSString *, id> *__nullable RCTGetImageMetadata(NSData *data);
|
|
RCT_EXTERN NSData *__nullable RCTGetImageData(UIImage *image, float quality);
|
|
RCT_EXTERN UIImage *__nullable
|
|
RCTTransformImage(UIImage *image, CGSize destSize, CGFloat destScale, CGAffineTransform transform);
|
|
RCT_EXTERN BOOL RCTImageHasAlpha(CGImageRef image);
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageView.h}:
|
|
|
|
@interface RCTImageView : RCTView
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
@property (nonatomic, assign) UIEdgeInsets capInsets;
|
|
@property (nonatomic, strong) UIImage *defaultImage;
|
|
@property (nonatomic, assign) UIImageRenderingMode renderingMode;
|
|
@property (nonatomic, copy) NSArray<RCTImageSource *> *imageSources;
|
|
@property (nonatomic, assign) CGFloat blurRadius;
|
|
@property (nonatomic, assign) RCTResizeMode resizeMode;
|
|
@property (nonatomic, copy) NSString *internal_analyticTag;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTImageViewManager.h}:
|
|
@interface RCTImageViewManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTLocalAssetImageLoader.h}:
|
|
__deprecated_msg("Use RCTBundleAssetImageLoader instead") @interface RCTLocalAssetImageLoader
|
|
: NSObject<RCTImageURLLoader>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTResizeMode.h}:
|
|
typedef NS_ENUM(NSInteger, RCTResizeMode) {
|
|
RCTResizeModeCover = UIViewContentModeScaleAspectFill,
|
|
RCTResizeModeContain = UIViewContentModeScaleAspectFit,
|
|
RCTResizeModeStretch = UIViewContentModeScaleToFill,
|
|
RCTResizeModeCenter = UIViewContentModeCenter,
|
|
RCTResizeModeRepeat = -1,
|
|
RCTResizeModeNone = UIViewContentModeTopLeft,
|
|
};
|
|
static inline RCTResizeMode RCTResizeModeFromUIViewContentMode(UIViewContentMode mode)
|
|
{
|
|
switch (mode) {
|
|
case UIViewContentModeScaleToFill:
|
|
return RCTResizeModeStretch;
|
|
case UIViewContentModeScaleAspectFit:
|
|
return RCTResizeModeContain;
|
|
case UIViewContentModeScaleAspectFill:
|
|
return RCTResizeModeCover;
|
|
case UIViewContentModeTopLeft:
|
|
return RCTResizeModeNone;
|
|
case UIViewContentModeRedraw:
|
|
case UIViewContentModeTop:
|
|
case UIViewContentModeBottom:
|
|
case UIViewContentModeLeft:
|
|
case UIViewContentModeRight:
|
|
case UIViewContentModeTopRight:
|
|
case UIViewContentModeBottomLeft:
|
|
case UIViewContentModeBottomRight:
|
|
return RCTResizeModeRepeat;
|
|
case UIViewContentModeCenter:
|
|
default:
|
|
return RCTResizeModeCenter;
|
|
}
|
|
};
|
|
@interface RCTConvert (RCTResizeMode)
|
|
+ (RCTResizeMode)RCTResizeMode:(id)json;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Image/RCTUIImageViewAnimated.h}:
|
|
@interface RCTUIImageViewAnimated : UIImageView
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/LinkingIOS/RCTLinkingManager.h}:
|
|
@interface RCTLinkingManager : RCTEventEmitter
|
|
+ (BOOL)application:(nonnull UIApplication *)app
|
|
openURL:(nonnull NSURL *)URL
|
|
options:(nonnull NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options;
|
|
+ (BOOL)application:(nonnull UIApplication *)application
|
|
openURL:(nonnull NSURL *)URL
|
|
sourceApplication:(nullable NSString *)sourceApplication
|
|
annotation:(nonnull id)annotation;
|
|
+ (BOOL)application:(nonnull UIApplication *)application
|
|
continueUserActivity:(nonnull NSUserActivity *)userActivity
|
|
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> *_Nullable))restorationHandler;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/LinkingIOS/RCTLinkingPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTLinkingClassProvider(const char* name);
|
|
Class RCTLinkingManagerCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Drivers/RCTAnimationDriver.h}:
|
|
static CGFloat RCTSingleFrameInterval = (CGFloat)(1.0 / 60.0);
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTAnimationDriver <NSObject>
|
|
@property (nonatomic, readonly) NSNumber *animationId;
|
|
@property (nonatomic, readonly) RCTValueAnimatedNode *valueNode;
|
|
@property (nonatomic, readonly) BOOL animationHasBegun;
|
|
@property (nonatomic, readonly) BOOL animationHasFinished;
|
|
- (instancetype)initWithId:(NSNumber *)animationId
|
|
config:(NSDictionary *)config
|
|
forNode:(RCTValueAnimatedNode *)valueNode
|
|
callBack:(nullable RCTResponseSenderBlock)callback;
|
|
- (void)startAnimation;
|
|
- (void)stepAnimationWithTime:(NSTimeInterval)currentTime;
|
|
- (void)stopAnimation;
|
|
- (void)resetAnimationConfig:(NSDictionary *)config;
|
|
NS_ASSUME_NONNULL_END
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Drivers/RCTDecayAnimation.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Drivers/RCTAnimationDriver.h}
|
|
|
|
@interface RCTDecayAnimation : NSObject <RCTAnimationDriver>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Drivers/RCTEventAnimation.h}:
|
|
@interface RCTEventAnimation : NSObject
|
|
@property (nonatomic, readonly, weak) RCTValueAnimatedNode *valueNode;
|
|
- (instancetype)initWithEventPath:(NSArray<NSString *> *)eventPath valueNode:(RCTValueAnimatedNode *)valueNode;
|
|
- (void)updateWithEvent:(id<RCTEvent>)event;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Drivers/RCTFrameAnimation.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Drivers/RCTAnimationDriver.h}
|
|
|
|
@interface RCTFrameAnimation : NSObject <RCTAnimationDriver>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Drivers/RCTSpringAnimation.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Drivers/RCTAnimationDriver.h}
|
|
|
|
@interface RCTSpringAnimation : NSObject <RCTAnimationDriver>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAdditionAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
@interface RCTAdditionAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}:
|
|
|
|
@interface RCTAnimatedNode : NSObject
|
|
- (instancetype)initWithTag:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config NS_DESIGNATED_INITIALIZER;
|
|
@property (nonatomic, readonly) NSNumber *nodeTag;
|
|
@property (nonatomic, weak) RCTNativeAnimatedNodesManager *manager;
|
|
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *config;
|
|
@property (nonatomic, copy, readonly) NSMapTable<NSNumber *, RCTAnimatedNode *> *childNodes;
|
|
@property (nonatomic, copy, readonly) NSMapTable<NSNumber *, RCTAnimatedNode *> *parentNodes;
|
|
@property (nonatomic, readonly) BOOL needsUpdate;
|
|
- (BOOL)isManagedByFabric;
|
|
- (void)setNeedsUpdate NS_REQUIRES_SUPER;
|
|
- (void)updateNodeIfNecessary NS_REQUIRES_SUPER;
|
|
- (void)performUpdate NS_REQUIRES_SUPER;
|
|
- (void)addChild:(RCTAnimatedNode *)child NS_REQUIRES_SUPER;
|
|
- (void)removeChild:(RCTAnimatedNode *)child NS_REQUIRES_SUPER;
|
|
- (void)onAttachedToNode:(RCTAnimatedNode *)parent NS_REQUIRES_SUPER;
|
|
- (void)onDetachedFromNode:(RCTAnimatedNode *)parent NS_REQUIRES_SUPER;
|
|
- (void)detachNode NS_REQUIRES_SUPER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTColorAnimatedNode.h}:
|
|
@interface RCTColorAnimatedNode : RCTAnimatedNode
|
|
@property (nonatomic, assign) int32_t color;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTDiffClampAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
@interface RCTDiffClampAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTDivisionAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
@interface RCTDivisionAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTInterpolationAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInterpolateString(
|
|
NSString *pattern,
|
|
CGFloat inputValue,
|
|
NSArray<NSNumber *> *inputRange,
|
|
NSArray<NSArray<NSNumber *> *> *outputRange,
|
|
NSString *extrapolateLeft,
|
|
NSString *extrapolateRight);
|
|
@interface RCTInterpolationAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTModuloAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
@interface RCTModuloAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTMultiplicationAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
@interface RCTMultiplicationAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTObjectAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
|
|
@interface RCTObjectAnimatedNode : RCTAnimatedNode
|
|
@property (nonatomic, strong, readonly) id value;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTPropsAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@interface RCTPropsAnimatedNode : RCTAnimatedNode
|
|
- (void)connectToView:(NSNumber *)viewTag
|
|
viewName:(NSString *)viewName
|
|
bridge:(RCTBridge *)bridge
|
|
surfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter;
|
|
- (void)disconnectFromView:(NSNumber *)viewTag;
|
|
- (void)restoreDefaultValues;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTStyleAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
|
|
@interface RCTStyleAnimatedNode : RCTAnimatedNode
|
|
- (NSDictionary<NSString *, NSObject *> *)propsDictionary;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTSubtractionAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
@interface RCTSubtractionAnimatedNode : RCTValueAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTTrackingAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
|
|
@interface RCTTrackingAnimatedNode : RCTAnimatedNode
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTTransformAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
|
|
@interface RCTTransformAnimatedNode : RCTAnimatedNode
|
|
- (NSDictionary<NSString *, NSObject *> *)propsDictionary;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/Nodes/RCTValueAnimatedNode.h}:
|
|
/// @dep {packages/react-native/Libraries/NativeAnimation/Nodes/RCTAnimatedNode.h}
|
|
@protocol RCTValueAnimatedNodeObserver <NSObject>
|
|
- (void)animatedNode:(RCTValueAnimatedNode *)node didUpdateValue:(CGFloat)value;
|
|
@end
|
|
@interface RCTValueAnimatedNode : RCTAnimatedNode
|
|
- (void)setOffset:(CGFloat)offset;
|
|
- (void)flattenOffset;
|
|
- (void)extractOffset;
|
|
@property (nonatomic, assign) CGFloat value;
|
|
@property (nonatomic, strong, readonly) id animatedObject;
|
|
@property (nonatomic, weak) id<RCTValueAnimatedNodeObserver> valueObserver;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/RCTAnimationPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTAnimationClassProvider(const char* name);
|
|
Class RCTNativeAnimatedModuleCls(void) __attribute__((used));
|
|
Class RCTNativeAnimatedTurboModuleCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/RCTAnimationUtils.h}:
|
|
RCT_EXTERN NSString *const EXTRAPOLATE_TYPE_IDENTITY;
|
|
RCT_EXTERN NSString *const EXTRAPOLATE_TYPE_CLAMP;
|
|
RCT_EXTERN NSString *const EXTRAPOLATE_TYPE_EXTEND;
|
|
RCT_EXTERN NSUInteger RCTFindIndexOfNearestValue(CGFloat value, NSArray<NSNumber *> *range);
|
|
RCT_EXTERN CGFloat RCTInterpolateValue(
|
|
CGFloat value,
|
|
CGFloat inputMin,
|
|
CGFloat inputMax,
|
|
CGFloat outputMin,
|
|
CGFloat outputMax,
|
|
NSString *extrapolateLeft,
|
|
NSString *extrapolateRight);
|
|
RCT_EXTERN CGFloat RCTInterpolateValueInRange(
|
|
CGFloat value,
|
|
NSArray<NSNumber *> *inputRange,
|
|
NSArray<NSNumber *> *outputRange,
|
|
NSString *extrapolateLeft,
|
|
NSString *extrapolateRight);
|
|
RCT_EXTERN uint32_t
|
|
RCTInterpolateColorInRange(CGFloat value, NSArray<NSNumber *> *inputRange, NSArray<UIColor *> *outputRange);
|
|
RCT_EXTERN uint32_t RCTColorFromComponents(CGFloat red, CGFloat green, CGFloat blue, CGFloat alpha);
|
|
RCT_EXTERN CGFloat RCTAnimationDragCoefficient(void);
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedModule.h}:
|
|
@interface RCTNativeAnimatedModule : RCTEventEmitter <
|
|
RCTBridgeModule,
|
|
RCTValueAnimatedNodeObserver,
|
|
RCTEventDispatcherObserver,
|
|
RCTUIManagerObserver,
|
|
RCTSurfacePresenterObserver>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedNodesManager.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTNativeAnimatedNodesManager : NSObject
|
|
- (nonnull instancetype)initWithBridge:(nullable RCTBridge *)bridge
|
|
surfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter;
|
|
- (void)updateAnimations;
|
|
- (void)stepAnimations:(CADisplayLink *)displaylink;
|
|
- (BOOL)isNodeManagedByFabric:(NSNumber *)tag;
|
|
- (void)getValue:(NSNumber *)nodeTag saveCallback:(RCTResponseSenderBlock)saveCallback;
|
|
- (void)createAnimatedNode:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config;
|
|
- (void)connectAnimatedNodes:(NSNumber *)parentTag childTag:(NSNumber *)childTag;
|
|
- (void)disconnectAnimatedNodes:(NSNumber *)parentTag childTag:(NSNumber *)childTag;
|
|
- (void)connectAnimatedNodeToView:(NSNumber *)nodeTag
|
|
viewTag:(NSNumber *)viewTag
|
|
viewName:(nullable NSString *)viewName;
|
|
- (void)restoreDefaultValues:(NSNumber *)nodeTag;
|
|
- (void)disconnectAnimatedNodeFromView:(NSNumber *)nodeTag viewTag:(NSNumber *)viewTag;
|
|
- (void)dropAnimatedNode:(NSNumber *)tag;
|
|
- (void)setAnimatedNodeValue:(NSNumber *)nodeTag value:(NSNumber *)value;
|
|
- (void)setAnimatedNodeOffset:(NSNumber *)nodeTag offset:(NSNumber *)offset;
|
|
- (void)flattenAnimatedNodeOffset:(NSNumber *)nodeTag;
|
|
- (void)extractAnimatedNodeOffset:(NSNumber *)nodeTag;
|
|
- (void)updateAnimatedNodeConfig:(NSNumber *)tag config:(NSDictionary<NSString *, id> *)config;
|
|
- (void)startAnimatingNode:(NSNumber *)animationId
|
|
nodeTag:(NSNumber *)nodeTag
|
|
config:(NSDictionary<NSString *, id> *)config
|
|
endCallback:(nullable RCTResponseSenderBlock)callBack;
|
|
- (void)stopAnimation:(NSNumber *)animationId;
|
|
- (void)stopAnimationLoop;
|
|
- (void)addAnimatedEventToView:(NSNumber *)viewTag
|
|
eventName:(NSString *)eventName
|
|
eventMapping:(NSDictionary<NSString *, id> *)eventMapping;
|
|
- (void)removeAnimatedEventFromView:(NSNumber *)viewTag
|
|
eventName:(NSString *)eventName
|
|
animatedNodeTag:(NSNumber *)animatedNodeTag;
|
|
- (void)handleAnimatedEvent:(id<RCTEvent>)event;
|
|
- (void)startListeningToAnimatedNodeValue:(NSNumber *)tag valueObserver:(id<RCTValueAnimatedNodeObserver>)valueObserver;
|
|
- (void)stopListeningToAnimatedNodeValue:(NSNumber *)tag;
|
|
- (NSSet<NSNumber *> *)getTagsOfConnectedNodesFrom:(NSNumber *)tag andEvent:(NSString *)eventName;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/NativeAnimation/RCTNativeAnimatedTurboModule.h}:
|
|
@interface RCTNativeAnimatedTurboModule : RCTEventEmitter <
|
|
RCTBridgeModule,
|
|
RCTValueAnimatedNodeObserver,
|
|
RCTEventDispatcherObserver,
|
|
RCTSurfacePresenterObserver>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTDataRequestHandler.h}:
|
|
@interface RCTDataRequestHandler : NSObject <RCTURLRequestHandler, RCTInvalidating>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTFileRequestHandler.h}:
|
|
@interface RCTFileRequestHandler : NSObject <RCTURLRequestHandler, RCTInvalidating>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTHTTPRequestHandler.h}:
|
|
typedef NSURLSessionConfiguration * (^NSURLSessionConfigurationProvider)(void);
|
|
RCT_EXTERN void RCTSetCustomNSURLSessionConfigurationProvider(NSURLSessionConfigurationProvider);
|
|
@interface RCTHTTPRequestHandler : NSObject <RCTURLRequestHandler, RCTInvalidating>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTInspectorNetworkReporter.h}:
|
|
@interface RCTInspectorNetworkReporter : NSObject
|
|
+ (void)reportRequestStart:(NSNumber *)requestId
|
|
request:(NSURLRequest *)request
|
|
encodedDataLength:(int)encodedDataLength;
|
|
+ (void)reportConnectionTiming:(NSNumber *)requestId request:(NSURLRequest *)request;
|
|
+ (void)reportResponseStart:(NSNumber *)requestId
|
|
response:(NSURLResponse *)response
|
|
statusCode:(int)statusCode
|
|
headers:(NSDictionary<NSString *, NSString *> *)headers;
|
|
+ (void)reportDataReceived:(NSNumber *)requestId data:(NSData *)data;
|
|
+ (void)reportResponseEnd:(NSNumber *)requestId encodedDataLength:(int)encodedDataLength;
|
|
+ (void)reportRequestFailed:(NSNumber *)requestId cancelled:(BOOL)cancelled;
|
|
+ (void)maybeStoreResponseBody:(NSNumber *)requestId data:(NSData *)data base64Encoded:(bool)base64Encoded;
|
|
+ (void)maybeStoreResponseBodyIncremental:(NSNumber *)requestId data:(NSString *)data;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTNetworkConversions.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
inline std::string_view RCTStringViewFromNSString(NSString *string)
|
|
{
|
|
return std::string_view{string.UTF8String, string.length};
|
|
}
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTNetworkPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTNetworkClassProvider(const char* name);
|
|
Class RCTDataRequestHandlerCls(void) __attribute__((used));
|
|
Class RCTFileRequestHandlerCls(void) __attribute__((used));
|
|
Class RCTHTTPRequestHandlerCls(void) __attribute__((used));
|
|
Class RCTNetworkingCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTNetworkTask.h}:
|
|
typedef void (^RCTURLRequestCompletionBlock)(NSURLResponse *response, NSData *data, NSError *error);
|
|
typedef void (^RCTURLRequestCancellationBlock)(void);
|
|
typedef void (^RCTURLRequestIncrementalDataBlock)(NSData *data, int64_t progress, int64_t total);
|
|
typedef void (^RCTURLRequestProgressBlock)(int64_t progress, int64_t total);
|
|
typedef void (^RCTURLRequestResponseBlock)(NSURLResponse *response);
|
|
typedef NS_ENUM(NSInteger, RCTNetworkTaskStatus) {
|
|
RCTNetworkTaskPending = 0,
|
|
RCTNetworkTaskInProgress,
|
|
RCTNetworkTaskFinished,
|
|
};
|
|
@interface RCTNetworkTask : NSObject <RCTURLRequestDelegate>
|
|
@property (nonatomic, readonly) NSURLRequest *request;
|
|
@property (nonatomic, readonly) NSNumber *requestID;
|
|
@property (nonatomic, readonly, weak) id requestToken;
|
|
@property (nonatomic, readonly) NSURLResponse *response;
|
|
@property (nonatomic, copy) RCTURLRequestCompletionBlock completionBlock;
|
|
@property (nonatomic, copy) RCTURLRequestProgressBlock downloadProgressBlock;
|
|
@property (nonatomic, copy) RCTURLRequestIncrementalDataBlock incrementalDataBlock;
|
|
@property (nonatomic, copy) RCTURLRequestResponseBlock responseBlock;
|
|
@property (nonatomic, copy) RCTURLRequestProgressBlock uploadProgressBlock;
|
|
@property (atomic, readonly) RCTNetworkTaskStatus status;
|
|
- (instancetype)initWithRequest:(NSURLRequest *)request
|
|
handler:(id<RCTURLRequestHandler>)handler
|
|
callbackQueue:(dispatch_queue_t)callbackQueue NS_DESIGNATED_INITIALIZER;
|
|
- (void)start;
|
|
- (void)cancel;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Network/RCTNetworking.h}:
|
|
@protocol RCTNetworkingRequestHandler <NSObject>
|
|
- (BOOL)canHandleNetworkingRequest:(NSDictionary *)data;
|
|
- (NSDictionary *)handleNetworkingRequest:(NSDictionary *)data;
|
|
@end
|
|
@protocol RCTNetworkingResponseHandler <NSObject>
|
|
- (BOOL)canHandleNetworkingResponse:(NSString *)responseType;
|
|
- (id)handleNetworkingResponse:(NSURLResponse *)response data:(NSData *)data;
|
|
@end
|
|
@interface RCTNetworking : RCTEventEmitter
|
|
- (instancetype)init NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithHandlersProvider:(NSArray<id<RCTURLRequestHandler>> * (^)(RCTModuleRegistry *))getHandlers;
|
|
- (BOOL)canHandleRequest:(NSURLRequest *)request;
|
|
- (RCTNetworkTask *)networkTaskWithRequest:(NSURLRequest *)request
|
|
completionBlock:(RCTURLRequestCompletionBlock)completionBlock;
|
|
- (void)addRequestHandler:(id<RCTNetworkingRequestHandler>)handler;
|
|
- (void)addResponseHandler:(id<RCTNetworkingResponseHandler>)handler;
|
|
- (void)removeRequestHandler:(id<RCTNetworkingRequestHandler>)handler;
|
|
- (void)removeResponseHandler:(id<RCTNetworkingResponseHandler>)handler;
|
|
@end
|
|
@interface RCTBridge (RCTNetworking)
|
|
@property (nonatomic, readonly) RCTNetworking *networking;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTNetworking)
|
|
@property (nonatomic, readonly) RCTNetworking *networking;
|
|
@end
|
|
extern NSString *const RCTNetworkingPHUploadHackScheme;
|
|
|
|
/// @src {packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationManager.h}:
|
|
extern NSString *const RCTRemoteNotificationReceived;
|
|
@interface RCTPushNotificationManager : RCTEventEmitter
|
|
typedef void (^RCTRemoteNotificationCallback)(UIBackgroundFetchResult result);
|
|
+ (void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;
|
|
+ (void)didFailToRegisterForRemoteNotificationsWithError:(NSError *)error;
|
|
+ (void)didReceiveNotification:(UNNotification *)notification;
|
|
+ (void)didReceiveRemoteNotification:(NSDictionary *)notification
|
|
fetchCompletionHandler:(RCTRemoteNotificationCallback)completionHandler;
|
|
+ (void)setInitialNotification:(UNNotification *)notification;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/PushNotificationIOS/RCTPushNotificationPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTPushNotificationClassProvider(const char* name);
|
|
Class RCTPushNotificationManagerCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/Required/RCTRequired.h}:
|
|
template <typename T>
|
|
struct RCTRequired {
|
|
template <typename... Args>
|
|
__attribute__((always_inline)) inline RCTRequired(Args&&... args)
|
|
: _t(std::forward<Args>(args)...) {
|
|
static_assert(
|
|
sizeof...(Args) > 0,
|
|
"Required struct member not initialized. Expand assert trace to see where this was triggered.");
|
|
}
|
|
__attribute__((always_inline)) inline RCTRequired(const RCTRequired&) =
|
|
default;
|
|
__attribute__((always_inline)) inline RCTRequired(RCTRequired&&) = default;
|
|
__attribute__((always_inline)) inline RCTRequired& operator=(
|
|
const RCTRequired&) = default;
|
|
__attribute__((always_inline)) inline RCTRequired& operator=(RCTRequired&&) =
|
|
default;
|
|
__attribute__((always_inline)) inline ~RCTRequired() = default;
|
|
__attribute__((always_inline)) inline const T& get() const {
|
|
return _t;
|
|
}
|
|
__attribute__((always_inline)) inline T& get() {
|
|
return _t;
|
|
}
|
|
__attribute__((always_inline)) inline operator T() const {
|
|
return _t;
|
|
}
|
|
__attribute__((always_inline)) inline operator T&() {
|
|
return _t;
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/Libraries/Settings/RCTSettingsManager.h}:
|
|
@interface RCTSettingsManager : NSObject <RCTBridgeModule>
|
|
- (instancetype)initWithUserDefaults:(NSUserDefaults *)defaults NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Settings/RCTSettingsPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTSettingsClassProvider(const char* name);
|
|
Class RCTSettingsManagerCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/Text/BaseText/RCTBaseTextShadowView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
extern NSString *const RCTBaseTextShadowViewEmbeddedShadowViewAttributeName;
|
|
@interface RCTBaseTextShadowView : RCTShadowView {
|
|
@protected
|
|
NSAttributedString *_Nullable cachedAttributedText;
|
|
@protected
|
|
RCTTextAttributes *_Nullable cachedTextAttributes;
|
|
}
|
|
@property (nonatomic, strong) RCTTextAttributes *textAttributes;
|
|
- (NSAttributedString *)attributedTextWithBaseTextAttributes:(nullable RCTTextAttributes *)baseTextAttributes;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/BaseText/RCTBaseTextViewManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBaseTextViewManager : RCTViewManager
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/RCTConvert+Text.h}:
|
|
/// @dep {packages/react-native/Libraries/Text/RCTTextTransform.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTConvert (Text)
|
|
+ (UITextAutocorrectionType)UITextAutocorrectionType:(nullable id)json;
|
|
+ (UITextSpellCheckingType)UITextSpellCheckingType:(nullable id)json;
|
|
+ (RCTTextTransform)RCTTextTransform:(nullable id)json;
|
|
+ (UITextSmartInsertDeleteType)UITextSmartInsertDeleteType:(nullable id)json;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/RCTTextAttributes.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
extern NSString *const RCTTextAttributesIsHighlightedAttributeName;
|
|
extern NSString *const RCTTextAttributesTagAttributeName;
|
|
@interface RCTTextAttributes : NSObject <NSCopying>
|
|
@property (nonatomic, strong, nullable) UIColor *foregroundColor;
|
|
@property (nonatomic, strong, nullable) UIColor *backgroundColor;
|
|
@property (nonatomic, assign) CGFloat opacity;
|
|
@property (nonatomic, copy, nullable) NSString *fontFamily;
|
|
@property (nonatomic, assign) CGFloat fontSize;
|
|
@property (nonatomic, assign) CGFloat fontSizeMultiplier;
|
|
@property (nonatomic, assign) CGFloat maxFontSizeMultiplier;
|
|
@property (nonatomic, copy, nullable) NSString *fontWeight;
|
|
@property (nonatomic, copy, nullable) NSString *fontStyle;
|
|
@property (nonatomic, copy, nullable) NSArray<NSString *> *fontVariant;
|
|
@property (nonatomic, assign) BOOL allowFontScaling;
|
|
@property (nonatomic, assign) RCTDynamicTypeRamp dynamicTypeRamp;
|
|
@property (nonatomic, assign) CGFloat letterSpacing;
|
|
@property (nonatomic, assign) CGFloat lineHeight;
|
|
@property (nonatomic, assign) NSTextAlignment alignment;
|
|
@property (nonatomic, assign) NSWritingDirection baseWritingDirection;
|
|
@property (nonatomic, assign) NSLineBreakStrategy lineBreakStrategy;
|
|
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;
|
|
@property (nonatomic, strong, nullable) UIColor *textDecorationColor;
|
|
@property (nonatomic, assign) NSUnderlineStyle textDecorationStyle;
|
|
@property (nonatomic, assign) RCTTextDecorationLineType textDecorationLine;
|
|
@property (nonatomic, assign) CGSize textShadowOffset;
|
|
@property (nonatomic, assign) CGFloat textShadowRadius;
|
|
@property (nonatomic, strong, nullable) UIColor *textShadowColor;
|
|
@property (nonatomic, assign) BOOL isHighlighted;
|
|
@property (nonatomic, strong, nullable) NSNumber *tag;
|
|
@property (nonatomic, assign) UIUserInterfaceLayoutDirection layoutDirection;
|
|
@property (nonatomic, assign) RCTTextTransform textTransform;
|
|
- (void)applyTextAttributes:(RCTTextAttributes *)textAttributes;
|
|
- (NSDictionary<NSAttributedStringKey, id> *)effectiveTextAttributes;
|
|
- (NSParagraphStyle *_Nullable)effectiveParagraphStyle;
|
|
- (UIFont *)effectiveFont;
|
|
- (CGFloat)effectiveFontSizeMultiplier;
|
|
- (UIColor *)effectiveForegroundColor;
|
|
- (UIColor *)effectiveBackgroundColor;
|
|
- (NSString *)applyTextAttributesToText:(NSString *)text;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/RCTTextTransform.h}:
|
|
typedef NS_ENUM(NSInteger, RCTTextTransform) {
|
|
RCTTextTransformUndefined = 0,
|
|
RCTTextTransformNone,
|
|
RCTTextTransformCapitalize,
|
|
RCTTextTransformUppercase,
|
|
RCTTextTransformLowercase,
|
|
};
|
|
|
|
/// @src {packages/react-native/Libraries/Text/RawText/RCTRawTextShadowView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTRawTextShadowView : RCTShadowView
|
|
@property (nonatomic, copy, nullable) NSString *text;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/RawText/RCTRawTextViewManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTRawTextViewManager : RCTViewManager
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/Text/NSTextStorage+FontScaling.h}:
|
|
@interface NSTextStorage (FontScaling)
|
|
- (void)scaleFontSizeToFitSize:(CGSize)size
|
|
minimumFontSize:(CGFloat)minimumFontSize
|
|
maximumFontSize:(CGFloat)maximumFontSize;
|
|
- (void)scaleFontSizeWithRatio:(CGFloat)ratio
|
|
minimumFontSize:(CGFloat)minimumFontSize
|
|
maximumFontSize:(CGFloat)maximumFontSize;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/Text/RCTDynamicTypeRamp.h}:
|
|
typedef NS_ENUM(NSInteger, RCTDynamicTypeRamp) {
|
|
RCTDynamicTypeRampUndefined,
|
|
RCTDynamicTypeRampCaption2,
|
|
RCTDynamicTypeRampCaption1,
|
|
RCTDynamicTypeRampFootnote,
|
|
RCTDynamicTypeRampSubheadline,
|
|
RCTDynamicTypeRampCallout,
|
|
RCTDynamicTypeRampBody,
|
|
RCTDynamicTypeRampHeadline,
|
|
RCTDynamicTypeRampTitle3,
|
|
RCTDynamicTypeRampTitle2,
|
|
RCTDynamicTypeRampTitle1,
|
|
RCTDynamicTypeRampLargeTitle
|
|
};
|
|
@interface RCTConvert (DynamicTypeRamp)
|
|
+ (RCTDynamicTypeRamp)RCTDynamicTypeRamp:(nullable id)json;
|
|
@end
|
|
UIFontMetrics *_Nonnull RCTUIFontMetricsForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
|
|
CGFloat RCTBaseSizeForDynamicTypeRamp(RCTDynamicTypeRamp dynamicTypeRamp);
|
|
|
|
/// @src {packages/react-native/Libraries/Text/Text/RCTTextShadowView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTTextShadowView : RCTBaseTextShadowView
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
@property (nonatomic, assign) NSInteger maximumNumberOfLines;
|
|
@property (nonatomic, assign) NSLineBreakMode lineBreakMode;
|
|
@property (nonatomic, assign) BOOL adjustsFontSizeToFit;
|
|
@property (nonatomic, assign) CGFloat minimumFontScale;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onTextLayout;
|
|
- (void)uiManagerWillPerformMounting;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/Text/RCTTextView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTTextView : UIView
|
|
@property (nonatomic, assign) BOOL selectable;
|
|
- (void)setTextStorage:(NSTextStorage *)textStorage
|
|
contentFrame:(CGRect)contentFrame
|
|
descendantViews:(NSArray<UIView *> *)descendantViews;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onClick;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/Text/RCTTextViewManager.h}:
|
|
@interface RCTTextViewManager : RCTBaseTextViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTMultilineTextInputView : RCTBaseTextInputView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/Multiline/RCTMultilineTextInputViewManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTMultilineTextInputViewManager : RCTBaseTextInputViewManager
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/Multiline/RCTUITextView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTUITextView : UITextView <RCTBackedTextInputViewProtocol>
|
|
- (instancetype)initWithFrame:(CGRect)frame textContainer:(nullable NSTextContainer *)textContainer NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE;
|
|
@property (nonatomic, weak) id<RCTBackedTextInputDelegate> textInputDelegate;
|
|
@property (nonatomic, assign) BOOL contextMenuHidden;
|
|
@property (nonatomic, assign, readonly) BOOL textWasPasted;
|
|
@property (nonatomic, assign, readonly) BOOL dictationRecognizing;
|
|
@property (nonatomic, copy, nullable) NSString *placeholder;
|
|
@property (nonatomic, strong, nullable) UIColor *placeholderColor;
|
|
@property (nonatomic, assign) CGFloat preferredMaxLayoutWidth;
|
|
@property (nonatomic, assign) UITextFieldViewMode clearButtonMode;
|
|
@property (nonatomic, assign) BOOL caretHidden;
|
|
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewID;
|
|
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewButtonLabel;
|
|
@property (nonatomic, assign) BOOL disableKeyboardShortcuts;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTBackedTextInputDelegate <NSObject>
|
|
- (BOOL)textInputShouldBeginEditing;
|
|
- (void)textInputDidBeginEditing;
|
|
- (BOOL)textInputShouldEndEditing;
|
|
- (void)textInputDidEndEditing;
|
|
- (BOOL)textInputShouldReturn;
|
|
- (void)textInputDidReturn;
|
|
- (BOOL)textInputShouldSubmitOnReturn;
|
|
- (NSString *)textInputShouldChangeText:(NSString *)text inRange:(NSRange)range;
|
|
- (void)textInputDidChange;
|
|
- (void)textInputDidChangeSelection;
|
|
@optional
|
|
- (void)scrollViewDidScroll:(UIScrollView *)scrollView;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegateAdapter.h}:
|
|
/// @dep {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h}
|
|
/// @dep {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBackedTextFieldDelegateAdapter : NSObject
|
|
- (instancetype)initWithTextField:(UITextField<RCTBackedTextInputViewProtocol> *)backedTextInputView;
|
|
- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange;
|
|
- (void)selectedTextRangeWasSet;
|
|
@end
|
|
@interface RCTBackedTextViewDelegateAdapter : NSObject
|
|
- (instancetype)initWithTextView:(UITextView<RCTBackedTextInputViewProtocol> *)backedTextInputView;
|
|
- (void)skipNextTextInputDidChangeSelectionEventWithTextRange:(UITextRange *)textRange;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTBackedTextInputViewProtocol <UITextInput>
|
|
@property (nonatomic, copy, nullable) NSAttributedString *attributedText;
|
|
@property (nonatomic, copy, nullable) NSString *placeholder;
|
|
@property (nonatomic, strong, nullable) UIColor *placeholderColor;
|
|
@property (nonatomic, assign, readonly) BOOL textWasPasted;
|
|
@property (nonatomic, assign, readonly) BOOL dictationRecognizing;
|
|
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
|
|
@property (nonatomic, strong, nullable) UIView *inputAccessoryView;
|
|
@property (nonatomic, strong, nullable) UIView *inputView;
|
|
@property (nonatomic, weak, nullable) id<RCTBackedTextInputDelegate> textInputDelegate;
|
|
@property (nonatomic, readonly) CGSize contentSize;
|
|
@property (nonatomic, strong, nullable) NSDictionary<NSAttributedStringKey, id> *defaultTextAttributes;
|
|
@property (nonatomic, assign) BOOL contextMenuHidden;
|
|
@property (nonatomic, assign, getter=isEditable) BOOL editable;
|
|
@property (nonatomic, assign) BOOL caretHidden;
|
|
@property (nonatomic, assign) BOOL enablesReturnKeyAutomatically;
|
|
@property (nonatomic, assign) UITextFieldViewMode clearButtonMode;
|
|
@property (nonatomic, assign) UIDataDetectorTypes dataDetectorTypes;
|
|
@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;
|
|
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewID;
|
|
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewButtonLabel;
|
|
@property (nonatomic, assign, readonly) CGFloat zoomScale;
|
|
@property (nonatomic, assign, readonly) CGPoint contentOffset;
|
|
@property (nonatomic, assign, readonly) UIEdgeInsets contentInset;
|
|
@property (nullable, nonatomic, copy) NSDictionary<NSAttributedStringKey, id> *typingAttributes;
|
|
@property (nonatomic, strong, nullable) NSArray<NSString *> *acceptDragAndDropTypes;
|
|
- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange NS_UNAVAILABLE;
|
|
- (void)setSelectedTextRange:(nullable UITextRange *)selectedTextRange notifyDelegate:(BOOL)notifyDelegate;
|
|
- (void)scrollRangeToVisible:(NSRange)selectedTextRange;
|
|
@property (nonatomic, copy, nullable) NSString *text NS_UNAVAILABLE;
|
|
@property (nonatomic, assign) BOOL disableKeyboardShortcuts;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputShadowView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBaseTextInputShadowView : RCTBaseTextShadowView
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
@property (nonatomic, copy, nullable) NSString *text;
|
|
@property (nonatomic, copy, nullable) NSString *placeholder;
|
|
@property (nonatomic, assign) NSInteger maximumNumberOfLines;
|
|
@property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange;
|
|
- (void)uiManagerWillPerformMounting;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputView.h}:
|
|
/// @dep {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputDelegate.h}
|
|
/// @dep {packages/react-native/Libraries/Text/TextInput/RCTBackedTextInputViewProtocol.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBaseTextInputView : RCTView <RCTBackedTextInputDelegate>
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE;
|
|
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
|
|
@property (nonatomic, readonly) UIView<RCTBackedTextInputViewProtocol> *backedTextInputView;
|
|
@property (nonatomic, strong, nullable) RCTTextAttributes *textAttributes;
|
|
@property (nonatomic, assign) UIEdgeInsets reactPaddingInsets;
|
|
@property (nonatomic, assign) UIEdgeInsets reactBorderInsets;
|
|
@property (nonatomic, copy, nullable) RCTDirectEventBlock onContentSizeChange;
|
|
@property (nonatomic, copy, nullable) RCTDirectEventBlock onSelectionChange;
|
|
@property (nonatomic, copy, nullable) RCTDirectEventBlock onChange;
|
|
@property (nonatomic, copy, nullable) RCTDirectEventBlock onChangeSync;
|
|
@property (nonatomic, copy, nullable) RCTDirectEventBlock onScroll;
|
|
@property (nonatomic, assign) NSInteger mostRecentEventCount;
|
|
@property (nonatomic, assign, readonly) NSInteger nativeEventCount;
|
|
@property (nonatomic, assign) BOOL autoFocus;
|
|
@property (nonatomic, copy) NSString *submitBehavior;
|
|
@property (nonatomic, assign) BOOL selectTextOnFocus;
|
|
@property (nonatomic, assign) BOOL clearTextOnFocus;
|
|
@property (nonatomic, assign) BOOL secureTextEntry;
|
|
@property (nonatomic, copy) RCTTextSelection *selection;
|
|
@property (nonatomic, strong, nullable) NSNumber *maxLength;
|
|
@property (nonatomic, copy, nullable) NSAttributedString *attributedText;
|
|
@property (nonatomic, copy) NSString *inputAccessoryViewID;
|
|
@property (nonatomic, strong) NSString *inputAccessoryViewButtonLabel;
|
|
@property (nonatomic, assign) UIKeyboardType keyboardType;
|
|
@property (nonatomic, assign) BOOL showSoftInputOnFocus;
|
|
- (void)setSelectionStart:(NSInteger)start selectionEnd:(NSInteger)end;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTBaseTextInputViewManager.h}:
|
|
@interface RCTBaseTextInputViewManager : RCTBaseTextViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTInputAccessoryShadowView.h}:
|
|
@interface RCTInputAccessoryShadowView : RCTShadowView
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTInputAccessoryView.h}:
|
|
|
|
@interface RCTInputAccessoryView : UIView
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTInputAccessoryViewContent.h}:
|
|
@interface RCTInputAccessoryViewContent : UIView
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTInputAccessoryViewManager.h}:
|
|
@interface RCTInputAccessoryViewManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/RCTTextSelection.h}:
|
|
@interface RCTTextSelection : NSObject
|
|
@property (nonatomic, assign, readonly) NSInteger start;
|
|
@property (nonatomic, assign, readonly) NSInteger end;
|
|
- (instancetype)initWithStart:(NSInteger)start end:(NSInteger)end;
|
|
@end
|
|
@interface RCTConvert (RCTTextSelection)
|
|
+ (RCTTextSelection *)RCTTextSelection:(id)json;
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSinglelineTextInputView : RCTBaseTextInputView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/Singleline/RCTSinglelineTextInputViewManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSinglelineTextInputViewManager : RCTBaseTextInputViewManager
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/TextInput/Singleline/RCTUITextField.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTUITextField : UITextField <RCTBackedTextInputViewProtocol>
|
|
- (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE;
|
|
@property (nonatomic, weak) id<RCTBackedTextInputDelegate> textInputDelegate;
|
|
@property (nonatomic, assign) BOOL caretHidden;
|
|
@property (nonatomic, assign) BOOL contextMenuHidden;
|
|
@property (nonatomic, assign, readonly) BOOL textWasPasted;
|
|
@property (nonatomic, assign, readonly) BOOL dictationRecognizing;
|
|
@property (nonatomic, strong, nullable) UIColor *placeholderColor;
|
|
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
|
|
@property (nonatomic, assign, getter=isEditable) BOOL editable;
|
|
@property (nonatomic, getter=isScrollEnabled) BOOL scrollEnabled;
|
|
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewID;
|
|
@property (nonatomic, strong, nullable) NSString *inputAccessoryViewButtonLabel;
|
|
@property (nonatomic, assign, readonly) CGFloat zoomScale;
|
|
@property (nonatomic, assign, readonly) CGPoint contentOffset;
|
|
@property (nonatomic, assign, readonly) UIEdgeInsets contentInset;
|
|
@property (nonatomic, assign) BOOL disableKeyboardShortcuts;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/VirtualText/RCTVirtualTextShadowView.h}:
|
|
@interface RCTVirtualTextShadowView : RCTBaseTextShadowView
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Text/VirtualText/RCTVirtualTextView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTVirtualTextView : UIView
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onClick;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Text/VirtualText/RCTVirtualTextViewManager.h}:
|
|
@interface RCTVirtualTextViewManager : RCTBaseTextViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/TypeSafety/RCTConvertHelpers.h}:
|
|
namespace facebook::react {
|
|
template <typename T>
|
|
using LazyVector = FB::LazyVector<T, id>;
|
|
}
|
|
template <typename ContainerT>
|
|
NSArray *RCTConvertVecToArray(const ContainerT &vec, id (^convertor)(typename ContainerT::value_type element))
|
|
{
|
|
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:vec.size()];
|
|
for (size_t i = 0, size = vec.size(); i < size; ++i) {
|
|
id object = convertor(vec[i]);
|
|
array[i] = object ?: (id)kCFNull;
|
|
}
|
|
return array;
|
|
}
|
|
template <typename ContainerT>
|
|
NSArray *RCTConvertVecToArray(const ContainerT &vec)
|
|
{
|
|
return RCTConvertVecToArray(vec, ^id(typename ContainerT::value_type element) {
|
|
return element;
|
|
});
|
|
}
|
|
template <typename ContainerT>
|
|
NSArray *RCTConvertOptionalVecToArray(
|
|
const std::optional<ContainerT> &vec,
|
|
id (^convertor)(typename ContainerT::value_type element))
|
|
{
|
|
return vec.has_value() ? RCTConvertVecToArray(vec.value(), convertor) : nil;
|
|
}
|
|
template <typename ContainerT>
|
|
NSArray *RCTConvertOptionalVecToArray(const std::optional<ContainerT> &vec)
|
|
{
|
|
return vec.has_value() ? RCTConvertVecToArray(
|
|
vec.value(),
|
|
^id(typename ContainerT::value_type element) {
|
|
return element;
|
|
})
|
|
: nil;
|
|
}
|
|
bool RCTBridgingToBool(id value);
|
|
std::optional<bool> RCTBridgingToOptionalBool(id value);
|
|
NSString *RCTBridgingToString(id value);
|
|
NSString *RCTBridgingToOptionalString(id value);
|
|
std::optional<double> RCTBridgingToOptionalDouble(id value);
|
|
double RCTBridgingToDouble(id value);
|
|
NSArray *RCTBridgingToArray(id value);
|
|
template <typename T>
|
|
facebook::react::LazyVector<T> RCTBridgingToVec(id value, T (^ctor)(id element))
|
|
{
|
|
NSArray *array = RCTBridgingToArray(value);
|
|
typedef typename facebook::react::LazyVector<T>::size_type _size_t;
|
|
_size_t size = static_cast<_size_t>(array.count);
|
|
return facebook::react::LazyVector<T>::fromUnsafeRawValue(array, size, ctor);
|
|
}
|
|
template <typename T>
|
|
std::optional<facebook::react::LazyVector<T>> RCTBridgingToOptionalVec(id value, T (^ctor)(id element))
|
|
{
|
|
if (value == nil || value == (id)kCFNull) {
|
|
return std::nullopt;
|
|
} else {
|
|
return RCTBridgingToVec(value, ctor);
|
|
}
|
|
}
|
|
|
|
/// @src {packages/react-native/Libraries/TypeSafety/RCTTypedModuleConstants.h}:
|
|
@interface _RCTTypedModuleConstants<StructType> : NSDictionary <NSString *, id>
|
|
+ (instancetype)newWithUnsafeDictionary:(NSDictionary<NSString *, id> *)dictionary;
|
|
@end
|
|
namespace facebook::react {
|
|
template <typename T>
|
|
using ModuleConstants = _RCTTypedModuleConstants<void (^)(T)> *;
|
|
template <typename T>
|
|
ModuleConstants<T> typedConstants(typename T::Builder::Input &&value)
|
|
{
|
|
typename T::Builder builder(std::move(value));
|
|
return [_RCTTypedModuleConstants newWithUnsafeDictionary:builder.buildUnsafeRawValue()];
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/Libraries/Vibration/RCTVibration.h}:
|
|
@interface RCTVibration : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/Libraries/Vibration/RCTVibrationPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTVibrationClassProvider(const char* name);
|
|
Class RCTVibrationCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/Libraries/Wrapper/RCTWrapper.h}:
|
|
|
|
|
|
/// @src {packages/react-native/Libraries/Wrapper/RCTWrapperShadowView.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTWrapperShadowView : RCTShadowView
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Wrapper/RCTWrapperView.h}:
|
|
typedef CGSize (^RCTWrapperMeasureBlock)(CGSize minimumSize, CGSize maximumSize);
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTWrapperView : UIView
|
|
@property (nonatomic, retain, nullable) UIView *contentView;
|
|
@property (nonatomic, readonly) RCTWrapperMeasureBlock measureBlock;
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)decoder NS_UNAVAILABLE;
|
|
- (void)addSubview:(UIView *)view NS_UNAVAILABLE;
|
|
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index NS_UNAVAILABLE;
|
|
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview NS_UNAVAILABLE;
|
|
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview NS_UNAVAILABLE;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Wrapper/RCTWrapperViewControllerHostingView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTWrapperViewControllerHostingView : UIView
|
|
@property (nonatomic, retain, nullable) UIViewController *contentViewController;
|
|
- (void)addSubview:(UIView *)view NS_UNAVAILABLE;
|
|
- (void)insertSubview:(UIView *)view atIndex:(NSInteger)index NS_UNAVAILABLE;
|
|
- (void)insertSubview:(UIView *)view aboveSubview:(UIView *)siblingSubview NS_UNAVAILABLE;
|
|
- (void)insertSubview:(UIView *)view belowSubview:(UIView *)siblingSubview NS_UNAVAILABLE;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/Libraries/Wrapper/RCTWrapperViewManager.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTWrapperViewManager : RCTViewManager
|
|
- (RCTWrapperView *)view NS_REQUIRES_SUPER;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTAssert.h}:
|
|
RCT_EXTERN BOOL RCTIsMainQueue(void);
|
|
RCT_EXTERN void _RCTAssertFormat(const char *, const char *, int, const char *, NSString *, ...)
|
|
NS_FORMAT_FUNCTION(5, 6);
|
|
RCT_EXTERN void RCTFatal(NSError *error);
|
|
RCT_EXTERN void RCTFatalException(NSException *exception);
|
|
RCT_EXTERN NSString *const RCTErrorDomain;
|
|
RCT_EXTERN NSString *const RCTJSStackTraceKey;
|
|
RCT_EXTERN NSString *const RCTJSRawStackTraceKey;
|
|
RCT_EXTERN NSString *const RCTObjCStackTraceKey;
|
|
RCT_EXTERN NSString *const RCTFatalExceptionName;
|
|
RCT_EXTERN NSString *const RCTJSExtraDataKey;
|
|
typedef void (^RCTAssertFunction)(
|
|
NSString *condition,
|
|
NSString *fileName,
|
|
NSNumber *lineNumber,
|
|
NSString *function,
|
|
NSString *message);
|
|
typedef void (^RCTFatalHandler)(NSError *error);
|
|
typedef void (^RCTFatalExceptionHandler)(NSException *exception);
|
|
RCT_EXTERN void RCTSetAssertFunction(RCTAssertFunction assertFunction);
|
|
RCT_EXTERN RCTAssertFunction RCTGetAssertFunction(void);
|
|
RCT_EXTERN void RCTAddAssertFunction(RCTAssertFunction assertFunction);
|
|
RCT_EXTERN void RCTPerformBlockWithAssertFunction(void (^block)(void), RCTAssertFunction assertFunction);
|
|
RCT_EXTERN void RCTSetFatalHandler(RCTFatalHandler fatalHandler);
|
|
RCT_EXTERN RCTFatalHandler RCTGetFatalHandler(void);
|
|
RCT_EXTERN void RCTSetFatalExceptionHandler(RCTFatalExceptionHandler fatalExceptionHandler);
|
|
RCT_EXTERN RCTFatalExceptionHandler RCTGetFatalExceptionHandler(void);
|
|
RCT_EXTERN NSString *RCTCurrentThreadName(void);
|
|
RCT_EXTERN NSString *
|
|
RCTFormatError(NSString *message, NSArray<NSDictionary<NSString *, id> *> *stacktrace, NSUInteger maxMessageLength);
|
|
RCT_EXTERN NSString *RCTFormatStackTrace(NSArray<NSDictionary<NSString *, id> *> *stackTrace);
|
|
typedef enum {
|
|
RCTNotAllowedInBridgeless = 1,
|
|
RCTNotAllowedInFabricWithoutLegacy = 2,
|
|
RCTNotAllowedValidationDisabled = 3,
|
|
} RCTNotAllowedValidation;
|
|
__attribute__((used)) RCT_EXTERN void RCTNewArchitectureSetMinValidationLevel(RCTNotAllowedValidation level);
|
|
__attribute__((used)) RCT_EXTERN void
|
|
RCTEnforceNewArchitectureValidation(RCTNotAllowedValidation type, id context, NSString *extra);
|
|
__attribute__((used)) RCT_EXTERN void
|
|
RCTErrorNewArchitectureValidation(RCTNotAllowedValidation type, id context, NSString *extra);
|
|
__attribute__((used)) RCT_EXTERN void
|
|
RCTLogNewArchitectureValidation(RCTNotAllowedValidation type, id context, NSString *extra);
|
|
__attribute__((used)) RCT_EXTERN void
|
|
RCTNewArchitectureValidationPlaceholder(RCTNotAllowedValidation type, id context, NSString *extra);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridge+Inspector.h}:
|
|
@interface RCTBridge (Inspector)
|
|
@property (nonatomic, assign, readonly) facebook::react::jsinspector_modern::HostTarget *inspectorTarget;
|
|
@property (nonatomic, readonly, getter=isInspectable) BOOL inspectable;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridge+Private.h}:
|
|
|
|
RCT_EXTERN NSArray<Class> *RCTGetModuleClasses(void);
|
|
RCT_EXTERN void RCTRegisterModule(Class);
|
|
@interface RCTBridge ()
|
|
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate
|
|
bundleURL:(NSURL *)bundleURL
|
|
moduleProvider:(RCTBridgeModuleListProvider)block
|
|
launchOptions:(NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
@property (nonatomic, assign) int64_t flowID;
|
|
@property (nonatomic, assign) CFMutableDictionaryRef flowIDMap;
|
|
@property (nonatomic, strong) NSLock *flowIDMapLock;
|
|
@property (nonatomic, copy) NSString *bridgeDescription;
|
|
+ (instancetype)currentBridge;
|
|
+ (void)setCurrentBridge:(RCTBridge *)bridge;
|
|
- (void)setUp;
|
|
- (void)enqueueCallback:(NSNumber *)cbID args:(NSArray *)args;
|
|
@property (atomic, strong) RCTBridge *batchedBridge;
|
|
@property (nonatomic, copy, readonly) RCTBridgeModuleListProvider moduleProvider;
|
|
@property (nonatomic, strong, readwrite) NSURL *bundleURL;
|
|
@property (nonatomic, strong, readonly) RCTModuleRegistry *moduleRegistry;
|
|
@end
|
|
@interface RCTBridge (RCTCxxBridge)
|
|
@property (nonatomic, weak, readonly) RCTBridge *parentBridge;
|
|
@property (nonatomic, assign, readonly) BOOL moduleSetupComplete;
|
|
- (void)start;
|
|
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module withModuleData:(RCTModuleData *)moduleData;
|
|
- (void)dispatchBlock:(dispatch_block_t)block queue:(dispatch_queue_t)queue;
|
|
- (RCTModuleData *)moduleDataForName:(NSString *)moduleName;
|
|
- (void)registerAdditionalModuleClasses:(NSArray<Class> *)newModules;
|
|
- (void)updateModuleWithInstance:(id<RCTBridgeModule>)instance;
|
|
- (void)startProfiling;
|
|
- (void)stopProfiling:(void (^)(NSData *))callback;
|
|
- (id)callNativeModule:(NSUInteger)moduleID method:(NSUInteger)methodID params:(NSArray *)params;
|
|
- (void)logMessage:(NSString *)message level:(NSString *)level;
|
|
- (void)_immediatelyCallTimer:(NSNumber *)timer;
|
|
@end
|
|
@interface RCTCxxBridge : RCTBridge
|
|
@property (nonatomic, readonly) void *runtime;
|
|
- (instancetype)initWithParentBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridge.h}:
|
|
/// @dep {packages/react-native/React/Base/RCTBridgeConstants.h}
|
|
/// @dep {packages/react-native/React/Base/RCTConstants.h}
|
|
typedef NSArray<id<RCTBridgeModule>> * (^RCTBridgeModuleListProvider)(void);
|
|
RCT_EXTERN_C_BEGIN
|
|
NSString *RCTBridgeModuleNameForClass(Class bridgeModuleClass);
|
|
NSMutableArray<NSString *> *getModulesLoadedWithOldArch(void);
|
|
BOOL RCTTurboModuleEnabled(void);
|
|
void RCTEnableTurboModule(BOOL enabled);
|
|
BOOL RCTTurboModuleInteropEnabled(void);
|
|
void RCTEnableTurboModuleInterop(BOOL enabled);
|
|
BOOL RCTTurboModuleInteropBridgeProxyEnabled(void);
|
|
void RCTEnableTurboModuleInteropBridgeProxy(BOOL enabled);
|
|
BOOL RCTFabricInteropLayerEnabled(void);
|
|
void RCTEnableFabricInteropLayer(BOOL enabled);
|
|
BOOL RCTTurboModuleSyncVoidMethodsEnabled(void);
|
|
void RCTEnableTurboModuleSyncVoidMethods(BOOL enabled);
|
|
BOOL RCTUIManagerDispatchAccessibilityManagerInitOntoMain(void);
|
|
void RCTUIManagerSetDispatchAccessibilityManagerInitOntoMain(BOOL enabled);
|
|
typedef enum {
|
|
kRCTBridgeProxyLoggingLevelNone,
|
|
kRCTBridgeProxyLoggingLevelWarning,
|
|
kRCTBridgeProxyLoggingLevelError,
|
|
} RCTBridgeProxyLoggingLevel;
|
|
RCTBridgeProxyLoggingLevel RCTTurboModuleInteropBridgeProxyLogLevel(void);
|
|
void RCTSetTurboModuleInteropBridgeProxyLogLevel(RCTBridgeProxyLoggingLevel logLevel);
|
|
BOOL RCTTurboModuleInteropForAllTurboModulesEnabled(void);
|
|
void RCTEnableTurboModuleInteropForAllTurboModules(BOOL enabled);
|
|
typedef enum {
|
|
kRCTGlobalScope,
|
|
kRCTGlobalScopeUsingRetainJSCallback,
|
|
kRCTTurboModuleManagerScope,
|
|
} RCTTurboModuleCleanupMode;
|
|
RCTTurboModuleCleanupMode RCTGetTurboModuleCleanupMode(void);
|
|
void RCTSetTurboModuleCleanupMode(RCTTurboModuleCleanupMode mode);
|
|
RCT_EXTERN_C_END
|
|
@interface RCTBridge : NSObject <RCTInvalidating>
|
|
- (instancetype)initWithDelegate:(id<RCTBridgeDelegate>)delegate launchOptions:(NSDictionary *)launchOptions;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
moduleProvider:(RCTBridgeModuleListProvider)block
|
|
launchOptions:(NSDictionary *)launchOptions;
|
|
- (void)enqueueJSCall:(NSString *)moduleDotMethod args:(NSArray *)args;
|
|
- (void)enqueueJSCall:(NSString *)module
|
|
method:(NSString *)method
|
|
args:(NSArray *)args
|
|
completion:(dispatch_block_t)completion;
|
|
- (void)registerSegmentWithId:(NSUInteger)segmentId path:(NSString *)path;
|
|
- (id)moduleForName:(NSString *)moduleName;
|
|
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
|
|
- (id)moduleForClass:(Class)moduleClass;
|
|
- (void)setRCTTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry;
|
|
- (RCTBridgeModuleDecorator *)bridgeModuleDecorator;
|
|
- (NSArray *)modulesConformingToProtocol:(Protocol *)protocol;
|
|
- (BOOL)moduleIsInitialized:(Class)moduleClass;
|
|
@property (nonatomic, copy, readonly) NSArray<Class> *moduleClasses;
|
|
@property (nonatomic, strong, readonly) NSURL *bundleURL;
|
|
@property (nonatomic, strong) Class executorClass;
|
|
@property (nonatomic, weak, readonly) id<RCTBridgeDelegate> delegate;
|
|
@property (nonatomic, copy, readonly) NSDictionary *launchOptions;
|
|
@property (nonatomic, readonly, getter=isLoading) BOOL loading;
|
|
@property (nonatomic, readonly, getter=isValid) BOOL valid;
|
|
@property (nonatomic, readonly, strong) RCTPerformanceLogger *performanceLogger;
|
|
- (void)reload __deprecated_msg("Use RCTReloadCommand instead");
|
|
- (void)reloadWithReason:(NSString *)reason __deprecated_msg("Use RCTReloadCommand instead");
|
|
- (void)onFastRefresh;
|
|
- (void)requestReload __deprecated_msg("Use RCTReloadCommand instead");
|
|
- (BOOL)isBatchActive;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeConstants.h}:
|
|
RCT_EXTERN NSString *const RCTBridgeWillReloadNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeFastRefreshNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeWillDownloadScriptNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeWillInvalidateModulesNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeDidInvalidateModulesNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeWillBeInvalidatedNotification;
|
|
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationSourceKey;
|
|
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationReasonKey;
|
|
RCT_EXTERN NSString *const RCTBridgeDidDownloadScriptNotificationBridgeDescriptionKey;
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeDelegate.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTBridgeDelegate <NSObject>
|
|
- (NSURL *__nullable)sourceURLForBridge:(RCTBridge *)bridge;
|
|
@optional
|
|
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge;
|
|
- (BOOL)bridge:(RCTBridge *)bridge didNotFindModule:(NSString *)moduleName;
|
|
- (void)loadSourceForBridge:(RCTBridge *)bridge
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (void)loadSourceForBridge:(RCTBridge *)bridge withBlock:(RCTSourceLoadBlock)loadCallback;
|
|
- (NSDictionary<NSString *, Class> *)extraLazyModuleClassesForBridge:(RCTBridge *)bridge;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeMethod.h}:
|
|
|
|
typedef NS_ENUM(NSInteger, RCTFunctionType) {
|
|
RCTFunctionTypeNormal,
|
|
RCTFunctionTypePromise,
|
|
RCTFunctionTypeSync,
|
|
};
|
|
static inline const char *RCTFunctionDescriptorFromType(RCTFunctionType type)
|
|
{
|
|
switch (type) {
|
|
case RCTFunctionTypePromise:
|
|
return "promise";
|
|
case RCTFunctionTypeSync:
|
|
return "sync";
|
|
case RCTFunctionTypeNormal:
|
|
default:
|
|
return "async";
|
|
}
|
|
};
|
|
@protocol RCTBridgeMethod <NSObject>
|
|
@property (nonatomic, readonly) const char *JSMethodName;
|
|
@property (nonatomic, readonly) RCTFunctionType functionType;
|
|
- (id)invokeWithBridge:(RCTBridge *)bridge module:(id)module arguments:(NSArray *)arguments;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeModule.h}:
|
|
/// @dep {packages/react-native/React/Base/RCTBundleManager.h}
|
|
typedef void (^RCTResponseSenderBlock)(NSArray *response);
|
|
typedef void (^RCTResponseErrorBlock)(NSError *error);
|
|
typedef void (^RCTPromiseResolveBlock)(id result);
|
|
typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError *error);
|
|
RCT_EXTERN_C_BEGIN
|
|
typedef struct RCTMethodInfo {
|
|
const char *const jsName;
|
|
const char *const objcName;
|
|
const BOOL isSync;
|
|
} RCTMethodInfo;
|
|
RCT_EXTERN_C_END
|
|
@protocol RCTBridgeModule <NSObject>
|
|
+ (NSString *)moduleName;
|
|
@optional
|
|
@property (nonatomic, weak, readwrite) RCTModuleRegistry *moduleRegistry;
|
|
@property (nonatomic, weak, readwrite) RCTViewRegistry *viewRegistry_DEPRECATED;
|
|
@property (nonatomic, weak, readwrite) RCTBundleManager *bundleManager;
|
|
@property (nonatomic, weak, readwrite) RCTCallableJSModules *callableJSModules;
|
|
@property (nonatomic, weak, readonly) RCTBridge *bridge RCT_DEPRECATED;
|
|
@property (nonatomic, strong, readonly) dispatch_queue_t methodQueue RCT_DEPRECATED;
|
|
+ (BOOL)requiresMainQueueSetup;
|
|
- (NSArray<id<RCTBridgeMethod>> *)methodsToExport;
|
|
- (NSDictionary *)constantsToExport;
|
|
- (void)batchDidComplete RCT_DEPRECATED;
|
|
@end
|
|
@interface RCTModuleRegistry : NSObject
|
|
- (void)setBridge:(RCTBridge *)bridge;
|
|
- (void)setTurboModuleRegistry:(id<RCTTurboModuleRegistry>)turboModuleRegistry;
|
|
- (id)moduleForName:(const char *)moduleName;
|
|
- (id)moduleForName:(const char *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
|
|
- (BOOL)moduleIsInitialized:(Class)moduleClass;
|
|
- (id)moduleForClass:(Class)moduleClass;
|
|
@end
|
|
typedef UIView * (^RCTBridgelessComponentViewProvider)(NSNumber *);
|
|
typedef void (^RCTViewRegistryUIBlock)(RCTViewRegistry *viewRegistry);
|
|
@interface RCTViewRegistry : NSObject
|
|
- (void)setBridge:(RCTBridge *)bridge;
|
|
- (void)setBridgelessComponentViewProvider:(RCTBridgelessComponentViewProvider)bridgelessComponentViewProvider;
|
|
- (UIView *)viewForReactTag:(NSNumber *)reactTag;
|
|
- (void)addUIBlock:(RCTViewRegistryUIBlock)block;
|
|
@end
|
|
typedef void (^RCTBridgelessJSModuleMethodInvoker)(
|
|
NSString *moduleName,
|
|
NSString *methodName,
|
|
NSArray *args,
|
|
dispatch_block_t onComplete);
|
|
@interface RCTCallableJSModules : NSObject
|
|
- (void)setBridge:(RCTBridge *)bridge;
|
|
- (void)setBridgelessJSModuleMethodInvoker:(RCTBridgelessJSModuleMethodInvoker)bridgelessJSModuleMethodInvoker;
|
|
- (void)invokeModule:(NSString *)moduleName method:(NSString *)methodName withArgs:(NSArray *)args;
|
|
- (void)invokeModule:(NSString *)moduleName
|
|
method:(NSString *)methodName
|
|
withArgs:(NSArray *)args
|
|
onComplete:(dispatch_block_t)onComplete;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeModuleDecorator.h}:
|
|
/// @dep {packages/react-native/React/Base/RCTBridgeModule.h}
|
|
@interface RCTBridgeModuleDecorator : NSObject
|
|
@property (nonatomic, strong, readonly) RCTViewRegistry *viewRegistry_DEPRECATED;
|
|
@property (nonatomic, strong, readonly) RCTModuleRegistry *moduleRegistry;
|
|
@property (nonatomic, strong, readonly) RCTBundleManager *bundleManager;
|
|
@property (nonatomic, strong, readonly) RCTCallableJSModules *callableJSModules;
|
|
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
callableJSModules:(RCTCallableJSModules *)callableJSModules;
|
|
- (void)attachInteropAPIsToModule:(id<RCTBridgeModule>)bridgeModule;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeProxy+Cxx.h}:
|
|
/// @dep {packages/react-native/React/Base/RCTBridgeModule.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBridgeProxy : NSProxy
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
callableJSModules:(RCTCallableJSModules *)callableJSModules
|
|
dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread
|
|
registerSegmentWithId:(void (^)(NSNumber *, NSString *))registerSegmentWithId
|
|
runtime:(void *)runtime
|
|
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
|
|
- (void)forwardInvocation:(NSInvocation *)invocation;
|
|
- (void)logWarning:(NSString *)message cmd:(SEL)cmd;
|
|
- (void)logError:(NSString *)message cmd:(SEL)cmd;
|
|
- (id)moduleForClass:(Class)moduleClass;
|
|
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
@interface RCTBridgeProxy (Cxx)
|
|
@property (nonatomic, readwrite) std::shared_ptr<facebook::react::CallInvoker> jsCallInvoker;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBridgeProxy.h}:
|
|
/// @dep {packages/react-native/React/Base/RCTBridgeModule.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBridgeProxy : NSProxy
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
- (instancetype)initWithViewRegistry:(RCTViewRegistry *)viewRegistry
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
callableJSModules:(RCTCallableJSModules *)callableJSModules
|
|
dispatchToJSThread:(void (^)(dispatch_block_t))dispatchToJSThread
|
|
registerSegmentWithId:(void (^)(NSNumber *, NSString *))registerSegmentWithId
|
|
runtime:(void *)runtime
|
|
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel;
|
|
- (void)forwardInvocation:(NSInvocation *)invocation;
|
|
- (void)logWarning:(NSString *)message cmd:(SEL)cmd;
|
|
- (void)logError:(NSString *)message cmd:(SEL)cmd;
|
|
- (id)moduleForClass:(Class)moduleClass;
|
|
- (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoad;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBundleManager.h}:
|
|
|
|
typedef NSURL * (^RCTBridgelessBundleURLGetter)(void);
|
|
typedef void (^RCTBridgelessBundleURLSetter)(NSURL *bundleURL);
|
|
@interface RCTBundleManager : NSObject
|
|
- (void)setBridge:(RCTBridge *)bridge;
|
|
- (void)setBridgelessBundleURLGetter:(RCTBridgelessBundleURLGetter)getter
|
|
andSetter:(RCTBridgelessBundleURLSetter)setter
|
|
andDefaultGetter:(RCTBridgelessBundleURLGetter)defaultGetter;
|
|
- (void)resetBundleURL;
|
|
@property NSURL *bundleURL;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTBundleURLProvider.h}:
|
|
extern "C" __attribute__((visibility("default"))) NSString *_Nonnull const RCTBundleURLProviderUpdatedNotification;
|
|
extern "C" __attribute__((visibility("default"))) const NSUInteger kRCTBundleURLProviderDefaultPort;
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTBundleURLProvider : NSObject
|
|
- (void)resetToDefaults;
|
|
- (NSString *)packagerServerHost;
|
|
- (NSString *)packagerServerHostPort;
|
|
+ (BOOL)isPackagerRunning:(NSString *)hostPort;
|
|
+ (BOOL)isPackagerRunning:(NSString *)hostPort scheme:(NSString *__nullable)scheme;
|
|
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
|
fallbackURLProvider:(NSURL *__nullable (^)(void))fallbackURLProvider;
|
|
- (NSURL *__nullable)jsBundleURLForSplitBundleRoot:(NSString *)bundleRoot;
|
|
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot fallbackExtension:(NSString *__nullable)extension;
|
|
- (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot;
|
|
- (NSURL *__nullable)jsBundleURLForFallbackExtension:(NSString *__nullable)extension;
|
|
- (NSURL *__nullable)resourceURLForResourceRoot:(NSString *)root
|
|
resourceName:(NSString *)name
|
|
resourceExtension:(NSString *)extension
|
|
offlineBundle:(NSBundle *)offlineBundle;
|
|
@property (nonatomic, copy, nullable) NSString *jsLocation;
|
|
@property (nonatomic, assign) BOOL enableMinification;
|
|
@property (nonatomic, assign) BOOL enableDev;
|
|
@property (nonatomic, assign) BOOL inlineSourceMap;
|
|
@property (nonatomic, copy) NSString *packagerScheme;
|
|
+ (instancetype)sharedSettings;
|
|
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
|
packagerHost:(NSString *)packagerHost
|
|
enableDev:(BOOL)enableDev
|
|
enableMinification:(BOOL)enableMinification
|
|
inlineSourceMap:(BOOL)inlineSourceMap;
|
|
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
|
packagerHost:(NSString *)packagerHost
|
|
enableDev:(BOOL)enableDev
|
|
enableMinification:(BOOL)enableMinification
|
|
inlineSourceMap:(BOOL)inlineSourceMap
|
|
additionalOptions:(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions;
|
|
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
|
packagerHost:(NSString *)packagerHost
|
|
packagerScheme:(NSString *__nullable)scheme
|
|
enableDev:(BOOL)enableDev
|
|
enableMinification:(BOOL)enableMinification
|
|
inlineSourceMap:(BOOL)inlineSourceMap
|
|
modulesOnly:(BOOL)modulesOnly
|
|
runModule:(BOOL)runModule;
|
|
+ (NSURL *__nullable)jsBundleURLForBundleRoot:(NSString *)bundleRoot
|
|
packagerHost:(NSString *)packagerHost
|
|
packagerScheme:(NSString *__nullable)scheme
|
|
enableDev:(BOOL)enableDev
|
|
enableMinification:(BOOL)enableMinification
|
|
inlineSourceMap:(BOOL)inlineSourceMap
|
|
modulesOnly:(BOOL)modulesOnly
|
|
runModule:(BOOL)runModule
|
|
additionalOptions:(NSDictionary<NSString *, NSString *> *__nullable)additionalOptions;
|
|
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
|
|
packagerHost:(NSString *)packagerHost
|
|
scheme:(NSString *__nullable)scheme
|
|
query:(NSString *__nullable)query
|
|
__deprecated_msg("Use version with queryItems parameter instead");
|
|
+ (NSURL *)resourceURLForResourcePath:(NSString *)path
|
|
packagerHost:(NSString *)packagerHost
|
|
scheme:(NSString *)scheme
|
|
queryItems:(NSArray<NSURLQueryItem *> *__nullable)queryItems;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTCallInvoker.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTCallInvoker : NSObject
|
|
- (instancetype)initWithCallInvoker:(std::shared_ptr<facebook::react::CallInvoker>)callInvoker
|
|
NS_DESIGNATED_INITIALIZER;
|
|
- (std::shared_ptr<facebook::react::CallInvoker>)callInvoker;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTCallInvokerModule.h}:
|
|
|
|
@protocol RCTCallInvokerModule <NSObject>
|
|
@property (nonatomic, nullable, readwrite) RCTCallInvoker *callInvoker;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTComponentEvent.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTComponentEvent : NSObject <RCTEvent>
|
|
- (instancetype)initWithName:(NSString *)name viewTag:(NSNumber *)viewTag body:(NSDictionary *)body;
|
|
NS_ASSUME_NONNULL_END
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTConstants.h}:
|
|
RCT_EXTERN NSString *const RCTPlatformName;
|
|
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotification;
|
|
RCT_EXTERN NSString *const RCTUserInterfaceStyleDidChangeNotificationTraitCollectionKey;
|
|
RCT_EXTERN NSString *const RCTWindowFrameDidChangeNotification;
|
|
RCT_EXTERN NSString *const RCTNotifyEventDispatcherObserversOfEvent_DEPRECATED;
|
|
RCT_EXTERN NSString *const RCTJavaScriptWillStartLoadingNotification;
|
|
RCT_EXTERN NSString *const RCTJavaScriptWillStartExecutingNotification;
|
|
RCT_EXTERN NSString *const RCTJavaScriptDidLoadNotification;
|
|
RCT_EXTERN NSString *const RCTJavaScriptDidFailToLoadNotification;
|
|
RCT_EXTERN NSString *const RCTDidInitializeModuleNotification;
|
|
RCT_EXTERN BOOL RCTGetDispatchW3CPointerEvents(void);
|
|
RCT_EXTERN void RCTSetDispatchW3CPointerEvents(BOOL value);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTConvert.h}:
|
|
typedef NS_ENUM(NSInteger, RCTColorSpace) {
|
|
RCTColorSpaceSRGB,
|
|
RCTColorSpaceDisplayP3,
|
|
};
|
|
RCTColorSpace RCTGetDefaultColorSpace(void);
|
|
RCT_EXTERN void RCTSetDefaultColorSpace(RCTColorSpace colorSpace);
|
|
@interface RCTConvert : NSObject
|
|
+ (id)id:(id)json;
|
|
+ (BOOL)BOOL:(id)json;
|
|
+ (double)double:(id)json;
|
|
+ (float)float:(id)json;
|
|
+ (int)int:(id)json;
|
|
+ (int64_t)int64_t:(id)json;
|
|
+ (uint64_t)uint64_t:(id)json;
|
|
+ (NSInteger)NSInteger:(id)json;
|
|
+ (NSUInteger)NSUInteger:(id)json;
|
|
+ (NSArray *)NSArray:(id)json;
|
|
+ (NSDictionary *)NSDictionary:(id)json;
|
|
+ (NSString *)NSString:(id)json;
|
|
+ (NSNumber *)NSNumber:(id)json;
|
|
+ (NSSet *)NSSet:(id)json;
|
|
+ (NSData *)NSData:(id)json;
|
|
+ (NSIndexSet *)NSIndexSet:(id)json;
|
|
+ (NSURLRequestCachePolicy)NSURLRequestCachePolicy:(id)json;
|
|
+ (NSURL *)NSURL:(id)json;
|
|
+ (NSURLRequest *)NSURLRequest:(id)json;
|
|
typedef NSURL RCTFileURL;
|
|
+ (RCTFileURL *)RCTFileURL:(id)json;
|
|
+ (NSDate *)NSDate:(id)json;
|
|
+ (NSLocale *)NSLocale:(id)json;
|
|
+ (NSTimeZone *)NSTimeZone:(id)json;
|
|
+ (NSTimeInterval)NSTimeInterval:(id)json;
|
|
+ (NSLineBreakMode)NSLineBreakMode:(id)json;
|
|
+ (NSTextAlignment)NSTextAlignment:(id)json;
|
|
+ (NSUnderlineStyle)NSUnderlineStyle:(id)json;
|
|
+ (NSWritingDirection)NSWritingDirection:(id)json;
|
|
+ (NSLineBreakStrategy)NSLineBreakStrategy:(id)json;
|
|
+ (UITextAutocapitalizationType)UITextAutocapitalizationType:(id)json;
|
|
+ (UITextFieldViewMode)UITextFieldViewMode:(id)json;
|
|
+ (UIKeyboardType)UIKeyboardType:(id)json;
|
|
+ (UIKeyboardAppearance)UIKeyboardAppearance:(id)json;
|
|
+ (UIReturnKeyType)UIReturnKeyType:(id)json;
|
|
+ (UIUserInterfaceStyle)UIUserInterfaceStyle:(id)json API_AVAILABLE(ios(12));
|
|
+ (UIInterfaceOrientationMask)UIInterfaceOrientationMask:(NSString *)orientation;
|
|
+ (UIModalPresentationStyle)UIModalPresentationStyle:(id)json;
|
|
+ (UIDataDetectorTypes)UIDataDetectorTypes:(id)json;
|
|
+ (UIViewContentMode)UIViewContentMode:(id)json;
|
|
+ (RCTCursor)RCTCursor:(id)json;
|
|
+ (CGFloat)CGFloat:(id)json;
|
|
+ (CGPoint)CGPoint:(id)json;
|
|
+ (CGSize)CGSize:(id)json;
|
|
+ (CGRect)CGRect:(id)json;
|
|
+ (UIEdgeInsets)UIEdgeInsets:(id)json;
|
|
+ (CGLineCap)CGLineCap:(id)json;
|
|
+ (CGLineJoin)CGLineJoin:(id)json;
|
|
+ (CGAffineTransform)CGAffineTransform:(id)json;
|
|
+ (UIColor *)UIColorWithRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
|
|
+ (UIColor *)UIColorWithRed:(CGFloat)red
|
|
green:(CGFloat)green
|
|
blue:(CGFloat)blue
|
|
alpha:(CGFloat)alpha
|
|
andColorSpace:(RCTColorSpace)colorSpace;
|
|
+ (RCTColorSpace)RCTColorSpaceFromString:(NSString *)colorSpace;
|
|
+ (UIColor *)UIColor:(id)json;
|
|
+ (CGColorRef)CGColor:(id)json CF_RETURNS_NOT_RETAINED;
|
|
+ (YGValue)YGValue:(id)json;
|
|
+ (NSArray<NSArray *> *)NSArrayArray:(id)json;
|
|
+ (NSArray<NSString *> *)NSStringArray:(id)json;
|
|
+ (NSArray<NSArray<NSString *> *> *)NSStringArrayArray:(id)json;
|
|
+ (NSArray<NSDictionary *> *)NSDictionaryArray:(id)json;
|
|
+ (NSArray<NSURL *> *)NSURLArray:(id)json;
|
|
+ (NSArray<RCTFileURL *> *)RCTFileURLArray:(id)json;
|
|
+ (NSArray<NSNumber *> *)NSNumberArray:(id)json;
|
|
+ (NSArray<UIColor *> *)UIColorArray:(id)json;
|
|
typedef NSArray CGColorArray;
|
|
+ (CGColorArray *)CGColorArray:(id)json;
|
|
typedef id NSPropertyList;
|
|
+ (NSPropertyList)NSPropertyList:(id)json;
|
|
typedef BOOL css_backface_visibility_t;
|
|
+ (YGOverflow)YGOverflow:(id)json;
|
|
+ (YGDisplay)YGDisplay:(id)json;
|
|
+ (css_backface_visibility_t)css_backface_visibility_t:(id)json;
|
|
+ (YGFlexDirection)YGFlexDirection:(id)json;
|
|
+ (YGJustify)YGJustify:(id)json;
|
|
+ (YGAlign)YGAlign:(id)json;
|
|
+ (YGPositionType)YGPositionType:(id)json;
|
|
+ (YGWrap)YGWrap:(id)json;
|
|
+ (YGDirection)YGDirection:(id)json;
|
|
+ (RCTPointerEvents)RCTPointerEvents:(id)json;
|
|
+ (RCTAnimationType)RCTAnimationType:(id)json;
|
|
+ (RCTBorderStyle)RCTBorderStyle:(id)json;
|
|
+ (RCTBorderCurve)RCTBorderCurve:(id)json;
|
|
+ (RCTTextDecorationLineType)RCTTextDecorationLineType:(id)json;
|
|
@end
|
|
@interface RCTConvert (Deprecated)
|
|
typedef NSArray NSArrayArray __deprecated_msg("Use NSArray<NSArray *>");
|
|
typedef NSArray NSStringArray __deprecated_msg("Use NSArray<NSString *>");
|
|
typedef NSArray NSStringArrayArray __deprecated_msg("Use NSArray<NSArray<NSString *> *>");
|
|
typedef NSArray NSDictionaryArray __deprecated_msg("Use NSArray<NSDictionary *>");
|
|
typedef NSArray NSURLArray __deprecated_msg("Use NSArray<NSURL *>");
|
|
typedef NSArray RCTFileURLArray __deprecated_msg("Use NSArray<RCTFileURL *>");
|
|
typedef NSArray NSNumberArray __deprecated_msg("Use NSArray<NSNumber *>");
|
|
typedef NSArray UIColorArray __deprecated_msg("Use NSArray<UIColor *>");
|
|
+ (UIImage *)UIImage:(id)json;
|
|
+ (CGImageRef)CGImage:(id)json CF_RETURNS_NOT_RETAINED;
|
|
@end
|
|
RCT_EXTERN NSNumber *RCTConvertEnumValue(const char *, NSDictionary *, NSNumber *, id);
|
|
RCT_EXTERN NSNumber *RCTConvertMultiEnumValue(const char *, NSDictionary *, NSNumber *, id);
|
|
RCT_EXTERN NSArray *RCTConvertArrayValue(SEL, id);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTCxxConvert.h}:
|
|
@interface RCTCxxConvert : NSObject
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTDefines.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Base/RCTDisplayLink.h}:
|
|
|
|
@protocol RCTDisplayLinkModuleHolder
|
|
- (id<RCTBridgeModule>)instance;
|
|
- (Class)moduleClass;
|
|
- (dispatch_queue_t)methodQueue;
|
|
@end
|
|
@interface RCTDisplayLink : NSObject
|
|
- (instancetype)init;
|
|
- (void)invalidate;
|
|
- (void)registerModuleForFrameUpdates:(id<RCTBridgeModule>)module
|
|
withModuleHolder:(id<RCTDisplayLinkModuleHolder>)moduleHolder;
|
|
- (void)addToRunLoop:(NSRunLoop *)runLoop;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTErrorCustomizer.h}:
|
|
|
|
@protocol RCTErrorCustomizer <NSObject>
|
|
- (nonnull RCTErrorInfo *)customizeErrorInfo:(nonnull RCTErrorInfo *)info;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTErrorInfo.h}:
|
|
|
|
@interface RCTErrorInfo : NSObject
|
|
@property (nonatomic, copy, readonly) NSString *errorMessage;
|
|
@property (nonatomic, copy, readonly) NSArray<RCTJSStackFrame *> *stack;
|
|
- (instancetype)initWithErrorMessage:(NSString *)errorMessage stack:(NSArray<RCTJSStackFrame *> *)stack;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTEventDispatcherProtocol.h}:
|
|
RCT_EXTERN const NSInteger RCTTextUpdateLagWarningThreshold;
|
|
RCT_EXTERN NSString *RCTNormalizeInputEventName(NSString *eventName);
|
|
typedef NS_ENUM(NSInteger, RCTTextEventType) {
|
|
RCTTextEventTypeFocus,
|
|
RCTTextEventTypeBlur,
|
|
RCTTextEventTypeChange,
|
|
RCTTextEventTypeSubmit,
|
|
RCTTextEventTypeEnd,
|
|
RCTTextEventTypeKeyPress
|
|
};
|
|
@protocol RCTEvent <NSObject>
|
|
@required
|
|
@property (nonatomic, strong, readonly) NSNumber *viewTag;
|
|
@property (nonatomic, copy, readonly) NSString *eventName;
|
|
- (BOOL)canCoalesce;
|
|
+ (NSString *)moduleDotMethod;
|
|
- (NSArray *)arguments;
|
|
@optional
|
|
@property (nonatomic, assign, readonly) uint16_t coalescingKey;
|
|
- (id<RCTEvent>)coalesceWithEvent:(id<RCTEvent>)newEvent;
|
|
@end
|
|
@protocol RCTEventDispatcherObserver <NSObject>
|
|
- (void)eventDispatcherWillDispatchEvent:(id<RCTEvent>)event;
|
|
@end
|
|
@protocol RCTJSDispatcherModule
|
|
@property (nonatomic, copy) void (^dispatchToJSThread)(dispatch_block_t block);
|
|
@end
|
|
@protocol RCTEventDispatcherProtocol <RCTBridgeModule, RCTJSDispatcherModule>
|
|
- (void)sendViewEventWithName:(NSString *)name reactTag:(NSNumber *)reactTag;
|
|
- (void)sendAppEventWithName:(NSString *)name body:(id)body __deprecated_msg("Subclass RCTEventEmitter instead");
|
|
- (void)sendDeviceEventWithName:(NSString *)name body:(id)body __deprecated_msg("Subclass RCTEventEmitter instead");
|
|
- (void)sendTextEventWithType:(RCTTextEventType)type
|
|
reactTag:(NSNumber *)reactTag
|
|
text:(NSString *)text
|
|
key:(NSString *)key
|
|
eventCount:(NSInteger)eventCount;
|
|
- (void)notifyObserversOfEvent:(id<RCTEvent>)event;
|
|
- (void)sendEvent:(id<RCTEvent>)event;
|
|
- (void)addDispatchObserver:(id<RCTEventDispatcherObserver>)observer;
|
|
- (void)removeDispatchObserver:(id<RCTEventDispatcherObserver>)observer;
|
|
@end
|
|
@interface RCTBridge (RCTEventDispatcher)
|
|
- (id<RCTEventDispatcherProtocol>)eventDispatcher;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTEventDispatcher)
|
|
- (id<RCTEventDispatcherProtocol>)eventDispatcher;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTFrameUpdate.h}:
|
|
|
|
@interface RCTFrameUpdate : NSObject
|
|
@property (nonatomic, readonly) NSTimeInterval timestamp;
|
|
@property (nonatomic, readonly) NSTimeInterval deltaTime;
|
|
- (instancetype)initWithDisplayLink:(CADisplayLink *)displayLink NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
@protocol RCTFrameUpdateObserver <NSObject>
|
|
- (void)didUpdateFrame:(RCTFrameUpdate *)update;
|
|
@property (nonatomic, readonly, getter=isPaused) BOOL paused;
|
|
@property (nonatomic, copy) dispatch_block_t pauseCallback;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTImageSource.h}:
|
|
@interface RCTImageSource : NSObject
|
|
@property (nonatomic, copy, readonly) NSURLRequest *request;
|
|
@property (nonatomic, assign, readonly) CGSize size;
|
|
@property (nonatomic, assign, readonly) CGFloat scale;
|
|
- (instancetype)initWithURLRequest:(NSURLRequest *)request size:(CGSize)size scale:(CGFloat)scale;
|
|
- (instancetype)imageSourceWithSize:(CGSize)size scale:(CGFloat)scale;
|
|
@end
|
|
@interface RCTConvert (ImageSource)
|
|
+ (RCTImageSource *)RCTImageSource:(id)json;
|
|
+ (NSArray<RCTImageSource *> *)RCTImageSourceArray:(id)json;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTInitializing.h}:
|
|
@protocol RCTInitializing <NSObject>
|
|
- (void)initialize;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTInvalidating.h}:
|
|
@protocol RCTInvalidating <NSObject>
|
|
- (void)invalidate;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTJSStackFrame.h}:
|
|
@interface RCTJSStackFrame : NSObject
|
|
@property (nonatomic, copy, readonly) NSString *methodName;
|
|
@property (nonatomic, copy, readonly) NSString *file;
|
|
@property (nonatomic, readonly) NSInteger lineNumber;
|
|
@property (nonatomic, readonly) NSInteger column;
|
|
@property (nonatomic, readonly) BOOL collapse;
|
|
- (instancetype)initWithMethodName:(NSString *)methodName
|
|
file:(NSString *)file
|
|
lineNumber:(NSInteger)lineNumber
|
|
column:(NSInteger)column
|
|
collapse:(BOOL)collapse;
|
|
- (NSDictionary *)toDictionary;
|
|
+ (instancetype)stackFrameWithLine:(NSString *)line;
|
|
+ (instancetype)stackFrameWithDictionary:(NSDictionary *)dict;
|
|
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithLines:(NSString *)lines;
|
|
+ (NSArray<RCTJSStackFrame *> *)stackFramesWithDictionaries:(NSArray<NSDictionary *> *)dicts;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTJSThread.h}:
|
|
RCT_EXTERN dispatch_queue_t RCTJSThread;
|
|
RCT_EXTERN void _RCTInitializeJSThreadConstantInternal(void);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTJavaScriptExecutor.h}:
|
|
typedef void (^RCTJavaScriptCompleteBlock)(NSError *error);
|
|
typedef void (^RCTJavaScriptCallback)(id result, NSError *error);
|
|
@protocol RCTJavaScriptExecutor <RCTInvalidating, RCTBridgeModule>
|
|
- (void)setUp;
|
|
@property (nonatomic, readonly, getter=isValid) BOOL valid;
|
|
- (void)flushedQueue:(RCTJavaScriptCallback)onComplete;
|
|
- (void)callFunctionOnModule:(NSString *)module
|
|
method:(NSString *)method
|
|
arguments:(NSArray *)args
|
|
callback:(RCTJavaScriptCallback)onComplete;
|
|
- (void)invokeCallbackID:(NSNumber *)cbID arguments:(NSArray *)args callback:(RCTJavaScriptCallback)onComplete;
|
|
- (void)executeApplicationScript:(NSData *)script
|
|
sourceURL:(NSURL *)sourceURL
|
|
onComplete:(RCTJavaScriptCompleteBlock)onComplete;
|
|
- (void)injectJSONText:(NSString *)script
|
|
asGlobalObjectNamed:(NSString *)objectName
|
|
callback:(RCTJavaScriptCompleteBlock)onComplete;
|
|
- (void)executeBlockOnJavaScriptQueue:(dispatch_block_t)block;
|
|
- (void)executeAsyncBlockOnJavaScriptQueue:(dispatch_block_t)block;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTJavaScriptLoader.h}:
|
|
extern NSString *const RCTJavaScriptLoaderErrorDomain;
|
|
NS_ENUM(NSInteger){
|
|
RCTJavaScriptLoaderErrorNoScriptURL = 1,
|
|
RCTJavaScriptLoaderErrorFailedOpeningFile = 2,
|
|
RCTJavaScriptLoaderErrorFailedReadingFile = 3,
|
|
RCTJavaScriptLoaderErrorFailedStatingFile = 3,
|
|
RCTJavaScriptLoaderErrorURLLoadFailed = 3,
|
|
RCTJavaScriptLoaderErrorBCVersion = 4,
|
|
RCTJavaScriptLoaderErrorBCNotSupported = 4,
|
|
RCTJavaScriptLoaderErrorCannotBeLoadedSynchronously = 1000,
|
|
};
|
|
NS_ENUM(NSInteger){
|
|
RCTSourceFilesChangedCountNotBuiltByBundler = -2,
|
|
RCTSourceFilesChangedCountRebuiltFromScratch = -1,
|
|
};
|
|
@interface RCTLoadingProgress : NSObject
|
|
@property (nonatomic, copy) NSString *status;
|
|
@property (strong, nonatomic) NSNumber *done;
|
|
@property (strong, nonatomic) NSNumber *total;
|
|
@end
|
|
@interface RCTSource : NSObject
|
|
@property (strong, nonatomic, readonly) NSURL *url;
|
|
@property (strong, nonatomic, readonly) NSData *data;
|
|
@property (nonatomic, readonly) NSUInteger length;
|
|
@property (nonatomic, readonly) NSInteger filesChangedCount;
|
|
@end
|
|
typedef void (^RCTSourceLoadProgressBlock)(RCTLoadingProgress *progressData);
|
|
typedef void (^RCTSourceLoadBlock)(NSError *error, RCTSource *source);
|
|
@interface RCTJavaScriptLoader : NSObject
|
|
+ (void)loadBundleAtURL:(NSURL *)scriptURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)onComplete;
|
|
+ (NSData *)attemptSynchronousLoadOfBundleAtURL:(NSURL *)scriptURL
|
|
sourceLength:(int64_t *)sourceLength
|
|
error:(NSError **)error;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTKeyCommands.h}:
|
|
@interface RCTKeyCommands : NSObject
|
|
+ (instancetype)sharedInstance;
|
|
- (void)registerKeyCommandWithInput:(NSString *)input
|
|
modifierFlags:(UIKeyModifierFlags)flags
|
|
action:(void (^)(UIKeyCommand *command))block;
|
|
- (void)unregisterKeyCommandWithInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
|
|
- (BOOL)isKeyCommandRegisteredForInput:(NSString *)input modifierFlags:(UIKeyModifierFlags)flags;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTLog.h}:
|
|
|
|
typedef NS_ENUM(NSInteger, RCTLogLevel) {
|
|
RCTLogLevelTrace = 0,
|
|
RCTLogLevelInfo = 1,
|
|
RCTLogLevelWarning = 2,
|
|
RCTLogLevelError = 3,
|
|
RCTLogLevelFatal = 4
|
|
};
|
|
typedef NS_ENUM(NSInteger, RCTLogSource) { RCTLogSourceNative = 1, RCTLogSourceJavaScript = 2 };
|
|
typedef void (^RCTLogFunction)(
|
|
RCTLogLevel level,
|
|
RCTLogSource source,
|
|
NSString *fileName,
|
|
NSNumber *lineNumber,
|
|
NSString *message);
|
|
RCT_EXTERN NSString *
|
|
RCTFormatLog(NSDate *timestamp, RCTLogLevel level, NSString *fileName, NSNumber *lineNumber, NSString *message);
|
|
RCT_EXTERN NSString *RCTFormatLogLevel(RCTLogLevel);
|
|
RCT_EXTERN NSString *RCTFormatLogSource(RCTLogSource);
|
|
extern RCTLogFunction RCTDefaultLogFunction;
|
|
RCT_EXTERN void RCTSetLogThreshold(RCTLogLevel threshold);
|
|
RCT_EXTERN RCTLogLevel RCTGetLogThreshold(void);
|
|
RCT_EXTERN void RCTSetLogFunction(RCTLogFunction logFunction);
|
|
RCT_EXTERN RCTLogFunction RCTGetLogFunction(void);
|
|
RCT_EXTERN void RCTAddLogFunction(RCTLogFunction logFunction);
|
|
RCT_EXTERN void RCTPerformBlockWithLogFunction(void (^block)(void), RCTLogFunction logFunction);
|
|
RCT_EXTERN void RCTPerformBlockWithLogPrefix(void (^block)(void), NSString *prefix);
|
|
RCT_EXTERN void RCTLogSetBridgeModuleRegistry(RCTModuleRegistry *moduleRegistry);
|
|
RCT_EXTERN void RCTLogSetBridgelessModuleRegistry(RCTModuleRegistry *moduleRegistry);
|
|
RCT_EXTERN void RCTLogSetBridgeCallableJSModules(RCTCallableJSModules *callableJSModules);
|
|
RCT_EXTERN void RCTLogSetBridgelessCallableJSModules(RCTCallableJSModules *callableJSModules);
|
|
RCT_EXTERN void _RCTLogNativeInternal(RCTLogLevel, const char *, int, NSString *, ...) NS_FORMAT_FUNCTION(4, 5);
|
|
RCT_EXTERN void _RCTLogJavaScriptInternal(RCTLogLevel, NSString *);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTManagedPointer.h}:
|
|
@interface RCTManagedPointer : NSObject
|
|
@property (nonatomic, readonly) void *voidPointer;
|
|
- (instancetype)initWithPointer:(std::shared_ptr<void>)pointer;
|
|
@end
|
|
namespace facebook::react {
|
|
template <typename T, typename P>
|
|
RCTManagedPointer *managedPointer(P initializer)
|
|
{
|
|
auto ptr = std::shared_ptr<void>(new T(initializer));
|
|
return [[RCTManagedPointer alloc] initWithPointer:std::move(ptr)];
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/Base/RCTMockDef.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Base/RCTModuleData.h}:
|
|
|
|
typedef id<RCTBridgeModule> (^RCTBridgeModuleProvider)(void);
|
|
@protocol RCTModuleDataCallInvokerProvider <NSObject>
|
|
- (RCTCallInvoker *)callInvokerForModuleData:(RCTModuleData *)moduleData;
|
|
@end
|
|
@interface RCTModuleData : NSObject <RCTInvalidating>
|
|
- (instancetype)initWithModuleClass:(Class)moduleClass
|
|
bridge:(RCTBridge *)bridge
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithModuleInstance:(id<RCTBridgeModule>)instance
|
|
bridge:(RCTBridge *)bridge
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
viewRegistry_DEPRECATED:(RCTViewRegistry *)viewRegistry_DEPRECATED
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
callableJSModules:(RCTCallableJSModules *)callableJSModules NS_DESIGNATED_INITIALIZER;
|
|
- (void)gatherConstants;
|
|
@property (nonatomic, strong, readonly) Class moduleClass;
|
|
@property (nonatomic, copy, readonly) NSString *name;
|
|
@property (nonatomic, copy, readonly) NSArray<id<RCTBridgeMethod>> *methods;
|
|
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id<RCTBridgeMethod>> *methodsByName;
|
|
@property (nonatomic, copy, readonly) NSDictionary<NSString *, id> *exportedConstants;
|
|
@property (nonatomic, assign, readonly) BOOL hasInstance;
|
|
@property (nonatomic, assign) BOOL requiresMainQueueSetup;
|
|
@property (nonatomic, assign, readonly) BOOL hasConstantsToExport;
|
|
@property (nonatomic, strong, readwrite) id<RCTBridgeModule> instance;
|
|
@property (nonatomic, strong, readonly) dispatch_queue_t methodQueue;
|
|
@property (nonatomic, assign, readonly) BOOL implementsBatchDidComplete;
|
|
@property (nonatomic, weak, readwrite) id<RCTModuleDataCallInvokerProvider> callInvokerProvider;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTModuleMethod.h}:
|
|
|
|
@interface RCTMethodArgument : NSObject
|
|
@property (nonatomic, copy, readonly) NSString *type;
|
|
@property (nonatomic, readonly) RCTNullability nullability;
|
|
@property (nonatomic, readonly) BOOL unused;
|
|
@end
|
|
@interface RCTModuleMethod : NSObject <RCTBridgeMethod>
|
|
@property (nonatomic, readonly) Class moduleClass;
|
|
@property (nonatomic, readonly) SEL selector;
|
|
- (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportMethod
|
|
moduleClass:(Class)moduleClass NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
RCT_EXTERN NSString *RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *> **arguments);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTMultipartDataTask.h}:
|
|
typedef void (^RCTMultipartDataTaskCallback)(
|
|
NSInteger statusCode,
|
|
NSDictionary *headers,
|
|
NSData *content,
|
|
NSError *error,
|
|
BOOL done);
|
|
@interface RCTMultipartDataTask : NSObject
|
|
- (instancetype)initWithURL:(NSURL *)url
|
|
partHandler:(RCTMultipartDataTaskCallback)partHandler
|
|
progressHandler:(RCTMultipartProgressCallback)progressHandler;
|
|
- (void)startTask;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTMultipartStreamReader.h}:
|
|
typedef void (^RCTMultipartCallback)(NSDictionary *headers, NSData *content, BOOL done);
|
|
typedef void (^RCTMultipartProgressCallback)(NSDictionary *headers, NSNumber *loaded, NSNumber *total);
|
|
@interface RCTMultipartStreamReader : NSObject
|
|
- (instancetype)initWithInputStream:(NSInputStream *)stream boundary:(NSString *)boundary;
|
|
- (BOOL)readAllPartsWithCompletionCallback:(RCTMultipartCallback)callback
|
|
progressCallback:(RCTMultipartProgressCallback)progressCallback;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTNullability.h}:
|
|
typedef NS_ENUM(NSInteger, RCTNullability) {
|
|
RCTNullabilityUnspecified,
|
|
RCTNullable,
|
|
RCTNonnullable,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Base/RCTPLTag.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Base/RCTParserUtils.h}:
|
|
@interface RCTParserUtils : NSObject
|
|
RCT_EXTERN BOOL RCTReadChar(const char **input, char c);
|
|
RCT_EXTERN BOOL RCTReadString(const char **input, const char *string);
|
|
RCT_EXTERN void RCTSkipWhitespace(const char **input);
|
|
RCT_EXTERN BOOL RCTParseSelectorIdentifier(const char **input, NSString **string);
|
|
RCT_EXTERN BOOL RCTParseArgumentIdentifier(const char **input, NSString **string);
|
|
RCT_EXTERN NSString *RCTParseType(const char **input);
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTPerformanceLogger.h}:
|
|
typedef NS_ENUM(NSInteger, RCTPLTag) {
|
|
RCTPLScriptDownload = 0,
|
|
RCTPLScriptExecution,
|
|
RCTPLRAMBundleLoad,
|
|
RCTPLRAMStartupCodeSize,
|
|
RCTPLRAMStartupNativeRequires,
|
|
RCTPLRAMStartupNativeRequiresCount,
|
|
RCTPLRAMNativeRequires,
|
|
RCTPLRAMNativeRequiresCount,
|
|
RCTPLNativeModuleInit,
|
|
RCTPLNativeModuleMainThread,
|
|
RCTPLNativeModulePrepareConfig,
|
|
RCTPLNativeModuleMainThreadUsesCount,
|
|
RCTPLNativeModuleSetup,
|
|
RCTPLTurboModuleSetup,
|
|
RCTPLJSCWrapperOpenLibrary,
|
|
RCTPLBridgeStartup,
|
|
RCTPLTTI,
|
|
RCTPLBundleSize,
|
|
RCTPLReactInstanceInit,
|
|
RCTPLAppStartup,
|
|
RCTPLInitReactRuntime,
|
|
RCTPLSize
|
|
};
|
|
|
|
@interface RCTPerformanceLogger : NSObject
|
|
- (void)markStartForTag:(RCTPLTag)tag;
|
|
- (void)markStopForTag:(RCTPLTag)tag;
|
|
- (void)setValue:(int64_t)value forTag:(RCTPLTag)tag;
|
|
- (void)addValue:(int64_t)value forTag:(RCTPLTag)tag;
|
|
- (void)appendStartForTag:(RCTPLTag)tag;
|
|
- (void)appendStopForTag:(RCTPLTag)tag;
|
|
- (NSArray<NSNumber *> *)valuesForTags;
|
|
- (int64_t)durationForTag:(RCTPLTag)tag;
|
|
- (int64_t)valueForTag:(RCTPLTag)tag;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTPerformanceLoggerLabels.h}:
|
|
typedef NS_ENUM(NSInteger, RCTPLTag) {
|
|
RCTPLScriptDownload = 0,
|
|
RCTPLScriptExecution,
|
|
RCTPLRAMBundleLoad,
|
|
RCTPLRAMStartupCodeSize,
|
|
RCTPLRAMStartupNativeRequires,
|
|
RCTPLRAMStartupNativeRequiresCount,
|
|
RCTPLRAMNativeRequires,
|
|
RCTPLRAMNativeRequiresCount,
|
|
RCTPLNativeModuleInit,
|
|
RCTPLNativeModuleMainThread,
|
|
RCTPLNativeModulePrepareConfig,
|
|
RCTPLNativeModuleMainThreadUsesCount,
|
|
RCTPLNativeModuleSetup,
|
|
RCTPLTurboModuleSetup,
|
|
RCTPLJSCWrapperOpenLibrary,
|
|
RCTPLBridgeStartup,
|
|
RCTPLTTI,
|
|
RCTPLBundleSize,
|
|
RCTPLReactInstanceInit,
|
|
RCTPLAppStartup,
|
|
RCTPLInitReactRuntime,
|
|
RCTPLSize
|
|
};
|
|
__attribute__((used)) RCT_EXTERN NSString *RCTPLLabelForTag(RCTPLTag tag);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTRedBoxSetEnabled.h}:
|
|
RCT_EXTERN void RCTRedBoxSetEnabled(BOOL enabled);
|
|
RCT_EXTERN BOOL RCTRedBoxGetEnabled(void);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTReloadCommand.h}:
|
|
@protocol RCTReloadListener
|
|
- (void)didReceiveReloadCommand;
|
|
@end
|
|
RCT_EXTERN void RCTRegisterReloadCommandListener(id<RCTReloadListener> listener);
|
|
RCT_EXTERN void RCTTriggerReloadCommandListeners(NSString *reason);
|
|
RCT_EXTERN NSString *const RCTTriggerReloadCommandNotification;
|
|
RCT_EXTERN NSString *const RCTTriggerReloadCommandReasonKey;
|
|
RCT_EXTERN NSString *const RCTTriggerReloadCommandBundleURLKey;
|
|
RCT_EXTERN void RCTReloadCommandSetBundleURL(NSURL *URL);
|
|
|
|
/// @src {packages/react-native/React/Base/RCTRootContentView.h}:
|
|
|
|
@interface RCTRootContentView : RCTView <RCTInvalidating>
|
|
@property (nonatomic, readonly, weak) RCTBridge *bridge;
|
|
@property (nonatomic, readonly, assign) BOOL contentHasAppeared;
|
|
@property (nonatomic, readonly, strong) RCTTouchHandler *touchHandler;
|
|
@property (nonatomic, readonly, assign) CGSize availableSize;
|
|
@property (nonatomic, assign) BOOL passThroughTouches;
|
|
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
bridge:(RCTBridge *)bridge
|
|
reactTag:(NSNumber *)reactTag
|
|
sizeFlexibility:(RCTRootViewSizeFlexibility)sizeFlexibility NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTRootView.h}:
|
|
|
|
typedef NS_ENUM(NSInteger, RCTRootViewSizeFlexibility) {
|
|
RCTRootViewSizeFlexibilityNone = 0,
|
|
RCTRootViewSizeFlexibilityWidth = 1 << 0,
|
|
RCTRootViewSizeFlexibilityHeight = 1 << 1,
|
|
RCTRootViewSizeFlexibilityWidthAndHeight = RCTRootViewSizeFlexibilityWidth | RCTRootViewSizeFlexibilityHeight,
|
|
};
|
|
extern "C" NS_ASSUME_NONNULL_BEGIN NSString *const RCTContentDidAppearNotification;
|
|
@interface RCTRootView : UIView
|
|
- (instancetype)initWithFrame:(CGRect)frame
|
|
bridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initialProperties:(nullable NSDictionary *)initialProperties NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initialProperties:(nullable NSDictionary *)initialProperties;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
moduleName:(NSString *)moduleName
|
|
initialProperties:(nullable NSDictionary *)initialProperties
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
@property (nonatomic, copy, readonly) NSString *moduleName;
|
|
@property (nonatomic, strong, readonly) RCTBridge *bridge;
|
|
@property (nonatomic, copy, readwrite, nullable) NSDictionary *appProperties;
|
|
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
|
@property (nonatomic, assign) CGSize minimumSize;
|
|
@property (nonatomic, weak, nullable) id<RCTRootViewDelegate> delegate;
|
|
@property (nonatomic, weak, nullable) UIViewController *reactViewController;
|
|
@property (nonatomic, strong, readonly) UIView *view;
|
|
@property (nonatomic, strong, readonly) UIView *contentView;
|
|
@property (nonatomic, strong, nullable) UIView *loadingView;
|
|
@property (nonatomic, assign) BOOL passThroughTouches;
|
|
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
|
|
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;
|
|
@end
|
|
@interface RCTRootView (Deprecated)
|
|
@property (readonly, nonatomic, assign) CGSize intrinsicSize __deprecated_msg("Use `intrinsicContentSize` instead.");
|
|
- (void)cancelTouches;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTRootViewDelegate.h}:
|
|
|
|
@protocol RCTRootViewDelegate <NSObject>
|
|
- (void)rootViewDidChangeIntrinsicSize:(RCTRootView *)rootView;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTRootViewInternal.h}:
|
|
@interface RCTRootView ()
|
|
@property (readwrite, nonatomic, assign) CGSize intrinsicContentSize;
|
|
- (void)contentViewInvalidated;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTTouchEvent.h}:
|
|
@interface RCTTouchEvent : NSObject <RCTEvent>
|
|
- (instancetype)initWithEventName:(NSString *)eventName
|
|
reactTag:(NSNumber *)reactTag
|
|
reactTouches:(NSArray<NSDictionary *> *)reactTouches
|
|
changedIndexes:(NSArray<NSNumber *> *)changedIndexes
|
|
coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTTouchHandler.h}:
|
|
|
|
@interface RCTTouchHandler : UIGestureRecognizer
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
- (void)attachToView:(UIView *)view;
|
|
- (void)detachFromView:(UIView *)view;
|
|
- (void)cancel;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTTurboModuleRegistry.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Base/RCTURLRequestDelegate.h}:
|
|
@protocol RCTURLRequestDelegate <NSObject>
|
|
- (void)URLRequest:(id)requestToken didSendDataWithProgress:(int64_t)bytesSent;
|
|
- (void)URLRequest:(id)requestToken didReceiveResponse:(NSURLResponse *)response;
|
|
- (void)URLRequest:(id)requestToken didReceiveData:(NSData *)data;
|
|
- (void)URLRequest:(id)requestToken didCompleteWithError:(NSError *)error;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTURLRequestHandler.h}:
|
|
@protocol RCTURLRequestHandler <RCTBridgeModule>
|
|
- (BOOL)canHandleRequest:(NSURLRequest *)request;
|
|
- (id)sendRequest:(NSURLRequest *)request withDelegate:(id<RCTURLRequestDelegate>)delegate;
|
|
@optional
|
|
- (void)cancelRequest:(id)requestToken;
|
|
- (float)handlerPriority;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN BOOL RCTIsNewArchEnabled(void);
|
|
RCT_EXTERN void RCTSetNewArchEnabled(BOOL enabled) __attribute__((deprecated(
|
|
"This function is now no-op. You need to modify the Info.plist adding a RCTNewArchEnabled bool property to control whether the New Arch is enabled or not")));
|
|
;
|
|
RCT_EXTERN BOOL RCTAreLegacyLogsEnabled(void);
|
|
RCT_EXTERN NSString *__nullable RCTJSONStringify(id __nullable jsonObject, NSError **error);
|
|
RCT_EXTERN id __nullable RCTJSONParse(NSString *__nullable jsonString, NSError **error);
|
|
RCT_EXTERN id __nullable RCTJSONParseMutable(NSString *__nullable jsonString, NSError **error);
|
|
RCT_EXTERN id RCTJSONClean(id object);
|
|
RCT_EXTERN NSString *RCTMD5Hash(NSString *string);
|
|
RCT_EXTERN BOOL RCTIsMainQueue(void);
|
|
RCT_EXTERN void RCTExecuteOnMainQueue(dispatch_block_t block);
|
|
RCT_EXTERN void RCTUnsafeExecuteOnMainQueueSync(dispatch_block_t block);
|
|
RCT_EXTERN CGFloat RCTScreenScale(void);
|
|
RCT_EXTERN CGFloat RCTFontSizeMultiplier(void);
|
|
RCT_EXTERN CGSize RCTScreenSize(void);
|
|
RCT_EXTERN CGSize RCTViewportSize(void);
|
|
RCT_EXTERN CGFloat RCTRoundPixelValue(CGFloat value);
|
|
RCT_EXTERN CGFloat RCTCeilPixelValue(CGFloat value);
|
|
RCT_EXTERN CGSize RCTSizeInPixels(CGSize pointSize, CGFloat scale);
|
|
RCT_EXTERN void RCTSwapClassMethods(Class cls, SEL original, SEL replacement);
|
|
RCT_EXTERN void RCTSwapInstanceMethods(Class cls, SEL original, SEL replacement);
|
|
RCT_EXTERN void RCTSwapInstanceMethodWithBlock(Class cls, SEL original, id replacementBlock, SEL replacementSelector);
|
|
RCT_EXTERN BOOL RCTClassOverridesClassMethod(Class cls, SEL selector);
|
|
RCT_EXTERN BOOL RCTClassOverridesInstanceMethod(Class cls, SEL selector);
|
|
RCT_EXTERN NSDictionary<NSString *, id> *
|
|
RCTMakeError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
|
|
RCT_EXTERN NSDictionary<NSString *, id> *
|
|
RCTMakeAndLogError(NSString *message, id __nullable toStringify, NSDictionary<NSString *, id> *__nullable extraData);
|
|
RCT_EXTERN NSDictionary<NSString *, id> *RCTJSErrorFromNSError(NSError *error);
|
|
RCT_EXTERN NSDictionary<NSString *, id> *
|
|
RCTJSErrorFromCodeMessageAndNSError(NSString *code, NSString *message, NSError *__nullable error);
|
|
RCT_EXTERN NSString *const RCTErrorUnspecified;
|
|
RCT_EXTERN BOOL RCTRunningInTestEnvironment(void);
|
|
RCT_EXTERN BOOL RCTRunningInAppExtension(void);
|
|
RCT_EXTERN UIApplication *__nullable RCTSharedApplication(void);
|
|
RCT_EXTERN UIWindow *__nullable RCTKeyWindow(void);
|
|
RCT_EXTERN UIViewController *__nullable RCTPresentedViewController(void);
|
|
RCT_EXTERN UIStatusBarManager *__nullable RCTUIStatusBarManager(void) API_AVAILABLE(ios(13));
|
|
RCT_EXTERN BOOL RCTForceTouchAvailable(void);
|
|
RCT_EXTERN NSError *RCTErrorWithMessage(NSString *message);
|
|
RCT_EXTERN NSError *RCTErrorWithNSException(NSException *exception);
|
|
RCT_EXTERN double RCTZeroIfNaN(double value);
|
|
RCT_EXTERN double RCTSanitizeNaNValue(double value, NSString *property);
|
|
RCT_EXTERN NSURL *RCTDataURL(NSString *mimeType, NSData *data);
|
|
RCT_EXTERN NSData *__nullable RCTGzipData(NSData *__nullable data, float level);
|
|
RCT_EXTERN NSString *__nullable RCTBundlePathForURL(NSURL *__nullable URL);
|
|
RCT_EXTERN NSString *__nullable RCTLibraryPath(void);
|
|
RCT_EXTERN NSString *__nullable RCTLibraryPathForURL(NSURL *__nullable URL);
|
|
RCT_EXTERN BOOL RCTIsBundleAssetURL(NSURL *__nullable imageURL);
|
|
RCT_EXTERN BOOL RCTIsLibraryAssetURL(NSURL *__nullable imageURL);
|
|
RCT_EXTERN BOOL RCTIsLocalAssetURL(NSURL *__nullable imageURL);
|
|
RCT_EXTERN UIImage *__nullable RCTImageFromLocalAssetURL(NSURL *imageURL);
|
|
RCT_EXTERN UIImage *__nullable RCTImageFromLocalBundleAssetURL(NSURL *imageURL);
|
|
RCT_EXTERN NSString *__nullable RCTTempFilePath(NSString *__nullable extension, NSError **error);
|
|
RCT_EXTERN void RCTGetRGBAColorComponents(CGColorRef color, CGFloat rgba[_Nonnull 4]);
|
|
RCT_EXTERN NSString *RCTColorToHexString(CGColorRef color);
|
|
RCT_EXTERN NSString *RCTUIKitLocalizedString(NSString *string);
|
|
RCT_EXTERN NSString *RCTHumanReadableType(NSObject *obj);
|
|
RCT_EXTERN NSString *__nullable RCTGetURLQueryParam(NSURL *__nullable URL, NSString *param);
|
|
RCT_EXTERN NSURL *__nullable
|
|
RCTURLByReplacingQueryParam(NSURL *__nullable URL, NSString *param, NSString *__nullable value);
|
|
RCT_EXTERN NSString *RCTDropReactPrefixes(NSString *s);
|
|
RCT_EXTERN BOOL RCTUIManagerTypeForTagIsFabric(NSNumber *reactTag);
|
|
RCT_EXTERN BOOL RCTValidateTypeOfViewCommandArgument(
|
|
NSObject *obj,
|
|
id expectedClass,
|
|
const NSString *expectedType,
|
|
const NSString *componentName,
|
|
const NSString *commandName,
|
|
const NSString *argPos);
|
|
RCT_EXTERN BOOL RCTIsAppActive(void);
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/RCTUtilsUIOverride.h}:
|
|
@interface RCTUtilsUIOverride : NSObject
|
|
+ (void)setPresentedViewController:(UIViewController *)presentedViewController;
|
|
+ (UIViewController *)presentedViewController;
|
|
+ (BOOL)hasPresentedViewController;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/RCTVersion.h}:
|
|
RCT_EXTERN NSString *const RCTVersionMajor;
|
|
RCT_EXTERN NSString *const RCTVersionMinor;
|
|
RCT_EXTERN NSString *const RCTVersionPatch;
|
|
RCT_EXTERN NSString *const RCTVersionPrerelease;
|
|
RCT_EXTERN NSDictionary *RCTGetReactNativeVersion(void);
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurface.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurface : NSObject <RCTSurfaceProtocol>
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *)initialProperties;
|
|
@property (atomic, assign, readonly) CGSize minimumSize;
|
|
@property (atomic, assign, readonly) CGSize maximumSize;
|
|
- (void)setSize:(CGSize)size;
|
|
- (BOOL)synchronouslyWaitForStage:(RCTSurfaceStage)stage timeout:(NSTimeInterval)timeout;
|
|
- (void)mountReactComponentWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
params:(NSDictionary *)params;
|
|
- (void)unmountReactComponentWithBridge:(RCTBridge *)bridge rootViewTag:(NSNumber *)rootViewTag;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceDelegate.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTSurfaceDelegate <NSObject>
|
|
@optional
|
|
- (void)surface:(RCTSurface *)surface didChangeStage:(RCTSurfaceStage)stage;
|
|
- (void)surface:(RCTSurface *)surface didChangeIntrinsicSize:(CGSize)intrinsicSize;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceProtocol.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTSurfaceProtocol <NSObject>
|
|
@property (atomic, readonly) RCTSurfaceStage stage;
|
|
@property (atomic, readonly) NSString *moduleName;
|
|
@property (atomic, readwrite, weak, nullable) id<RCTSurfaceDelegate> delegate;
|
|
@property (atomic, readonly) NSNumber *rootViewTag;
|
|
@property (atomic, copy, readwrite) NSDictionary *properties;
|
|
@property (atomic, readonly) NSInteger rootTag;
|
|
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
|
|
- (void)setMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize viewportOffset:(CGPoint)viewportOffset;
|
|
- (RCTSurfaceView *)view;
|
|
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
|
|
@property (atomic, assign, readonly) CGSize intrinsicSize;
|
|
- (void)start;
|
|
- (void)stop;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceRootShadowView.h}:
|
|
@interface RCTSurfaceRootShadowView : RCTShadowView
|
|
@property (nonatomic, assign, readonly) CGSize minimumSize;
|
|
@property (nonatomic, assign, readonly) CGSize maximumSize;
|
|
- (void)setMinimumSize:(CGSize)size maximumSize:(CGSize)maximumSize;
|
|
@property (nonatomic, assign, readonly) CGSize intrinsicSize;
|
|
@property (nonatomic, weak) id<RCTSurfaceRootShadowViewDelegate> delegate;
|
|
@property (nonatomic, assign) YGDirection baseDirection;
|
|
- (void)layoutWithAffectedShadowViews:(NSPointerArray *)affectedShadowViews;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceRootShadowViewDelegate.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTSurfaceRootShadowViewDelegate <NSObject>
|
|
- (void)rootShadowView:(RCTSurfaceRootShadowView *)rootShadowView didChangeIntrinsicSize:(CGSize)intrinsicSize;
|
|
- (void)rootShadowViewDidStartRendering:(RCTSurfaceRootShadowView *)rootShadowView;
|
|
- (void)rootShadowViewDidStartLayingOut:(RCTSurfaceRootShadowView *)rootShadowView;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceRootView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfaceRootView : RCTView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceStage.h}:
|
|
typedef NS_OPTIONS(NSInteger, RCTSurfaceStage) {
|
|
RCTSurfaceStageSurfaceDidInitialize = 1 << 0,
|
|
RCTSurfaceStageBridgeDidLoad = 1 << 1,
|
|
RCTSurfaceStageModuleDidLoad = 1 << 2,
|
|
RCTSurfaceStageSurfaceDidRun = 1 << 3,
|
|
RCTSurfaceStageSurfaceDidInitialRendering = 1 << 4,
|
|
RCTSurfaceStageSurfaceDidInitialLayout = 1 << 5,
|
|
RCTSurfaceStageSurfaceDidInitialMounting = 1 << 6,
|
|
RCTSurfaceStageSurfaceDidStop = 1 << 7,
|
|
RCTSurfaceStagePreparing = RCTSurfaceStageSurfaceDidInitialize | RCTSurfaceStageBridgeDidLoad |
|
|
RCTSurfaceStageModuleDidLoad,
|
|
RCTSurfaceStageRunning = RCTSurfaceStagePreparing | RCTSurfaceStageSurfaceDidRun |
|
|
RCTSurfaceStageSurfaceDidInitialRendering | RCTSurfaceStageSurfaceDidInitialLayout |
|
|
RCTSurfaceStageSurfaceDidInitialMounting,
|
|
};
|
|
RCT_EXTERN BOOL RCTSurfaceStageIsRunning(RCTSurfaceStage stage);
|
|
RCT_EXTERN BOOL RCTSurfaceStageIsPreparing(RCTSurfaceStage stage);
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceView+Internal.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfaceView (Internal)
|
|
@property (nonatomic, nullable, strong) RCTSurfaceRootView *rootView;
|
|
@property (nonatomic, assign) RCTSurfaceStage stage;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/RCTSurfaceView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfaceView : UIView
|
|
- (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface NS_DESIGNATED_INITIALIZER;
|
|
@property (nonatomic, weak, readonly, nullable) id<RCTSurfaceProtocol> surface;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingProxyRootView.h}:
|
|
/// @dep {packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfaceHostingProxyRootView : RCTSurfaceHostingView
|
|
@property (nonatomic, copy, readonly) NSString *moduleName;
|
|
@property (nonatomic, strong, readonly) RCTBridge *bridge;
|
|
@property (nonatomic, copy, readwrite) NSDictionary *appProperties;
|
|
@property (nonatomic, assign) RCTRootViewSizeFlexibility sizeFlexibility;
|
|
@property (nonatomic, weak) id<RCTRootViewDelegate> delegate;
|
|
@property (nonatomic, weak) UIViewController *reactViewController;
|
|
@property (nonatomic, strong, readonly) UIView *view;
|
|
@property (nonatomic, strong, readonly) UIView *contentView;
|
|
@property (nonatomic, strong) UIView *loadingView;
|
|
@property (nonatomic, assign) BOOL passThroughTouches;
|
|
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDelay;
|
|
@property (nonatomic, assign) NSTimeInterval loadingViewFadeDuration;
|
|
@property (nonatomic, assign) CGSize minimumSize;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
- (instancetype)initWithFrame:(CGRect)frame NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE;
|
|
- (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface
|
|
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode NS_UNAVAILABLE;
|
|
- (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface NS_DESIGNATED_INITIALIZER;
|
|
- (void)cancelTouches;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceHostingView.h}:
|
|
|
|
typedef UIView *_Nullable (^RCTSurfaceHostingViewActivityIndicatorViewFactory)(void);
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfaceHostingView : UIView <RCTSurfaceDelegate>
|
|
- (instancetype)initWithSurface:(id<RCTSurfaceProtocol>)surface
|
|
sizeMeasureMode:(RCTSurfaceSizeMeasureMode)sizeMeasureMode NS_DESIGNATED_INITIALIZER;
|
|
@property (nonatomic, strong, readonly) id<RCTSurfaceProtocol> surface;
|
|
@property (nonatomic, assign) RCTSurfaceSizeMeasureMode sizeMeasureMode;
|
|
@property (nonatomic, copy, nullable) RCTSurfaceHostingViewActivityIndicatorViewFactory activityIndicatorViewFactory;
|
|
- (void)disableActivityIndicatorAutoHide:(BOOL)disabled;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Base/Surface/SurfaceHostingView/RCTSurfaceSizeMeasureMode.h}:
|
|
typedef NS_OPTIONS(NSInteger, RCTSurfaceSizeMeasureMode) {
|
|
RCTSurfaceSizeMeasureModeWidthUndefined = 0 << 0,
|
|
RCTSurfaceSizeMeasureModeWidthExact = 1 << 0,
|
|
RCTSurfaceSizeMeasureModeWidthAtMost = 2 << 0,
|
|
RCTSurfaceSizeMeasureModeHeightUndefined = 0 << 2,
|
|
RCTSurfaceSizeMeasureModeHeightExact = 1 << 2,
|
|
RCTSurfaceSizeMeasureModeHeightAtMost = 2 << 2,
|
|
};
|
|
RCT_EXTERN void RCTSurfaceMinimumSizeAndMaximumSizeFromSizeAndSizeMeasureMode(
|
|
CGSize size,
|
|
RCTSurfaceSizeMeasureMode sizeMeasureMode,
|
|
CGSize *minimumSize,
|
|
CGSize *maximumSize);
|
|
|
|
/// @src {packages/react-native/React/CoreModules/CoreModulesPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class RCTCoreModulesClassProvider(const char* name);
|
|
Class RCTAccessibilityManagerCls(void) __attribute__((used));
|
|
Class RCTActionSheetManagerCls(void) __attribute__((used));
|
|
Class RCTAlertManagerCls(void) __attribute__((used));
|
|
Class RCTAppStateCls(void) __attribute__((used));
|
|
Class RCTAppearanceCls(void) __attribute__((used));
|
|
Class RCTClipboardCls(void) __attribute__((used));
|
|
Class RCTDevLoadingViewCls(void) __attribute__((used));
|
|
Class RCTDevMenuCls(void) __attribute__((used));
|
|
Class RCTDevSettingsCls(void) __attribute__((used));
|
|
Class RCTDeviceInfoCls(void) __attribute__((used));
|
|
Class RCTEventDispatcherCls(void) __attribute__((used));
|
|
Class RCTExceptionsManagerCls(void) __attribute__((used));
|
|
Class RCTI18nManagerCls(void) __attribute__((used));
|
|
Class RCTKeyboardObserverCls(void) __attribute__((used));
|
|
Class RCTLogBoxCls(void) __attribute__((used));
|
|
Class RCTPerfMonitorCls(void) __attribute__((used));
|
|
Class RCTPlatformCls(void) __attribute__((used));
|
|
Class RCTRedBoxCls(void) __attribute__((used));
|
|
Class RCTSourceCodeCls(void) __attribute__((used));
|
|
Class RCTStatusBarManagerCls(void) __attribute__((used));
|
|
Class RCTTimingCls(void) __attribute__((used));
|
|
Class RCTWebSocketModuleCls(void) __attribute__((used));
|
|
Class RCTBlobManagerCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTAccessibilityManager+Internal.h}:
|
|
/// @dep {packages/react-native/React/CoreModules/RCTAccessibilityManager.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN_C_BEGIN
|
|
void RCTAccessibilityManagerSetIsVoiceOverEnabled(
|
|
RCTAccessibilityManager *accessibilityManager,
|
|
BOOL isVoiceOverEnabled);
|
|
RCT_EXTERN_C_END
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTAccessibilityManager.h}:
|
|
extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification;
|
|
@interface RCTAccessibilityManager : NSObject <RCTBridgeModule>
|
|
@property (nonatomic, readonly) CGFloat multiplier;
|
|
@property (nonatomic, copy) NSDictionary<NSString *, NSNumber *> *multipliers;
|
|
@property (nonatomic, assign) BOOL isBoldTextEnabled;
|
|
@property (nonatomic, assign) BOOL isGrayscaleEnabled;
|
|
@property (nonatomic, assign) BOOL isInvertColorsEnabled;
|
|
@property (nonatomic, assign) BOOL isReduceMotionEnabled;
|
|
@property (nonatomic, assign) BOOL isDarkerSystemColorsEnabled;
|
|
@property (nonatomic, assign) BOOL prefersCrossFadeTransitions;
|
|
@property (nonatomic, assign) BOOL isReduceTransparencyEnabled;
|
|
@property (nonatomic, assign) BOOL isVoiceOverEnabled;
|
|
@end
|
|
@interface RCTBridge (RCTAccessibilityManager)
|
|
@property (nonatomic, readonly) RCTAccessibilityManager *accessibilityManager;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTAccessibilityManager)
|
|
@property (nonatomic, readonly) RCTAccessibilityManager *accessibilityManager;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTActionSheetManager.h}:
|
|
@interface RCTActionSheetManager : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTAlertController.h}:
|
|
@interface RCTAlertController : UIAlertController
|
|
- (void)show:(BOOL)animated completion:(void (^)(void))completion;
|
|
- (void)hide;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTAlertManager.h}:
|
|
typedef NS_ENUM(NSInteger, RCTAlertViewStyle) {
|
|
RCTAlertViewStyleDefault = 0,
|
|
RCTAlertViewStyleSecureTextInput,
|
|
RCTAlertViewStylePlainTextInput,
|
|
RCTAlertViewStyleLoginAndPasswordInput
|
|
};
|
|
@interface RCTAlertManager : NSObject <RCTBridgeModule, RCTInvalidating>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTAppState.h}:
|
|
@interface RCTAppState : RCTEventEmitter
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTAppearance.h}:
|
|
RCT_EXTERN void RCTEnableAppearancePreference(BOOL enabled);
|
|
RCT_EXTERN void RCTOverrideAppearancePreference(NSString *const);
|
|
RCT_EXTERN void RCTUseKeyWindowForSystemStyle(BOOL useMainScreen);
|
|
RCT_EXTERN NSString *RCTCurrentOverrideAppearancePreference(void);
|
|
RCT_EXTERN NSString *RCTColorSchemePreference(UITraitCollection *traitCollection);
|
|
@interface RCTAppearance : RCTEventEmitter <RCTBridgeModule>
|
|
- (instancetype)init;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTClipboard.h}:
|
|
@interface RCTClipboard : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTDevLoadingView.h}:
|
|
@interface RCTDevLoadingView : NSObject <RCTDevLoadingViewProtocol, RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTDevMenu.h}:
|
|
|
|
@interface RCTDevMenu : NSObject
|
|
@property (nonatomic, assign) BOOL shakeToShow DEPRECATED_ATTRIBUTE;
|
|
@property (nonatomic, assign) BOOL profilingEnabled DEPRECATED_ATTRIBUTE;
|
|
@property (nonatomic, assign) BOOL hotLoadingEnabled DEPRECATED_ATTRIBUTE;
|
|
@property (nonatomic, assign) BOOL hotkeysEnabled;
|
|
@property (nonatomic, copy, readonly) NSArray<RCTDevMenuItem *> *presentedItems;
|
|
- (BOOL)isActionSheetShown;
|
|
- (void)show;
|
|
- (void)reload DEPRECATED_ATTRIBUTE;
|
|
- (void)addItem:(NSString *)title handler:(void (^)(void))handler DEPRECATED_ATTRIBUTE;
|
|
- (void)addItem:(RCTDevMenuItem *)item;
|
|
@end
|
|
typedef NSString * (^RCTDevMenuItemTitleBlock)(void);
|
|
@interface RCTDevMenuItem : NSObject
|
|
+ (instancetype)buttonItemWithTitle:(NSString *)title handler:(dispatch_block_t)handler;
|
|
+ (instancetype)buttonItemWithTitleBlock:(RCTDevMenuItemTitleBlock)titleBlock handler:(dispatch_block_t)handler;
|
|
@property (nonatomic, assign, getter=isDisabled) BOOL disabled;
|
|
@end
|
|
@interface RCTBridge (RCTDevMenu)
|
|
@property (nonatomic, readonly) RCTDevMenu *devMenu;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTDevMenu)
|
|
@property (nonatomic, readonly) RCTDevMenu *devMenu;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTDevSettings.h}:
|
|
|
|
@protocol RCTDevSettingsDataSource <NSObject>
|
|
- (void)updateSettingWithValue:(id)value forKey:(NSString *)key;
|
|
- (id)settingForKey:(NSString *)key;
|
|
@end
|
|
@protocol RCTDevSettingsInspectable <NSObject>
|
|
@property (nonatomic, assign, readwrite) BOOL isInspectable;
|
|
@end
|
|
@interface RCTDevSettings : RCTEventEmitter <RCTInitializing>
|
|
- (instancetype)initWithDataSource:(id<RCTDevSettingsDataSource>)dataSource;
|
|
@property (nonatomic, readonly) BOOL isHotLoadingAvailable;
|
|
@property (nonatomic, readonly) BOOL isDeviceDebuggingAvailable;
|
|
@property (nonatomic, assign) BOOL isShakeToShowDevMenuEnabled;
|
|
@property (nonatomic, assign, setter=setProfilingEnabled:) BOOL isProfilingEnabled;
|
|
@property (nonatomic, assign, setter=setHotLoadingEnabled:) BOOL isHotLoadingEnabled;
|
|
@property (nonatomic, assign) BOOL startSamplingProfilerOnLaunch;
|
|
@property (nonatomic, readonly) BOOL isElementInspectorShown;
|
|
@property (nonatomic, assign) BOOL isPerfMonitorShown;
|
|
- (void)toggleElementInspector;
|
|
- (void)setupHMRClientWithBundleURL:(NSURL *)bundleURL;
|
|
- (void)setupHMRClientWithAdditionalBundleURL:(NSURL *)bundleURL;
|
|
@end
|
|
@interface RCTBridge (RCTDevSettings)
|
|
@property (nonatomic, readonly) RCTDevSettings *devSettings;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTDevSettings)
|
|
@property (nonatomic, readonly) RCTDevSettings *devSettings;
|
|
@end
|
|
RCT_EXTERN void RCTDevSettingsSetEnabled(BOOL enabled);
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTDevToolsRuntimeSettingsModule.h}:
|
|
@interface RCTDevToolsRuntimeSettingsModule : NSObject
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTDeviceInfo.h}:
|
|
@interface RCTDeviceInfo : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTEventDispatcher.h}:
|
|
@interface RCTEventDispatcher : NSObject <RCTEventDispatcherProtocol, RCTInitializing>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTExceptionsManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTExceptionsManagerDelegate <NSObject>
|
|
- (void)handleSoftJSExceptionWithMessage:(nullable NSString *)message
|
|
stack:(nullable NSArray *)stack
|
|
exceptionId:(NSNumber *)exceptionId
|
|
extraDataAsJSON:(nullable NSString *)extraDataAsJSON;
|
|
- (void)handleFatalJSExceptionWithMessage:(nullable NSString *)message
|
|
stack:(nullable NSArray *)stack
|
|
exceptionId:(NSNumber *)exceptionId
|
|
extraDataAsJSON:(nullable NSString *)extraDataAsJSON;
|
|
@optional
|
|
- (NSDictionary<NSString *, id> *)decorateJSExceptionData:(NSDictionary<NSString *, id> *)exceptionData;
|
|
@end
|
|
@interface RCTExceptionsManager : NSObject <RCTBridgeModule>
|
|
- (instancetype)initWithDelegate:(id<RCTExceptionsManagerDelegate>)delegate;
|
|
- (void)reportSoftException:(nullable NSString *)message
|
|
stack:(nullable NSArray<NSDictionary *> *)stack
|
|
exceptionId:(double)exceptionId;
|
|
- (void)reportFatalException:(nullable NSString *)message
|
|
stack:(nullable NSArray<NSDictionary *> *)stack
|
|
exceptionId:(double)exceptionId;
|
|
- (void)reportJsException:(nullable NSString *)message
|
|
stack:(nullable NSArray<NSDictionary *> *)stack
|
|
exceptionId:(double)exceptionId
|
|
isFatal:(bool)isFatal __attribute__((deprecated));
|
|
@property (nonatomic, weak) id<RCTExceptionsManagerDelegate> delegate;
|
|
@property (nonatomic, assign) NSUInteger maxReloadAttempts;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTFPSGraph.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTI18nManager.h}:
|
|
@interface RCTI18nManager : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTKeyboardObserver.h}:
|
|
@interface RCTKeyboardObserver : RCTEventEmitter
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTLogBox.h}:
|
|
/// @dep {packages/react-native/React/CoreModules/RCTLogBoxView.h}
|
|
|
|
@interface RCTLogBox : NSObject
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTLogBoxView.h}:
|
|
@interface RCTLogBoxView : UIWindow
|
|
- (instancetype)initWithFrame:(CGRect)frame;
|
|
- (void)createRootViewController:(UIView *)view;
|
|
- (instancetype)initWithWindow:(UIWindow *)window bridge:(RCTBridge *)bridge;
|
|
- (instancetype)initWithWindow:(UIWindow *)window surfacePresenter:(id<RCTSurfacePresenterStub>)surfacePresenter;
|
|
- (void)show;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTPlatform.h}:
|
|
@interface RCTPlatform : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTRedBox.h}:
|
|
|
|
typedef void (^RCTRedBoxButtonPressHandler)(void);
|
|
@interface RCTRedBox : NSObject <RCTBridgeModule>
|
|
- (void)registerErrorCustomizer:(id<RCTErrorCustomizer>)errorCustomizer;
|
|
- (void)showError:(NSError *)error;
|
|
- (void)showErrorMessage:(NSString *)message;
|
|
- (void)showErrorMessage:(NSString *)message withDetails:(NSString *)details;
|
|
- (void)showErrorMessage:(NSString *)message withRawStack:(NSString *)rawStack;
|
|
- (void)showErrorMessage:(NSString *)message withRawStack:(NSString *)rawStack errorCookie:(int)errorCookie;
|
|
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack;
|
|
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack;
|
|
- (void)showErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack errorCookie:(int)errorCookie;
|
|
- (void)updateErrorMessage:(NSString *)message withStack:(NSArray<NSDictionary *> *)stack errorCookie:(int)errorCookie;
|
|
- (void)showErrorMessage:(NSString *)message withParsedStack:(NSArray<RCTJSStackFrame *> *)stack;
|
|
- (void)updateErrorMessage:(NSString *)message withParsedStack:(NSArray<RCTJSStackFrame *> *)stack;
|
|
- (void)showErrorMessage:(NSString *)message
|
|
withParsedStack:(NSArray<RCTJSStackFrame *> *)stack
|
|
errorCookie:(int)errorCookie;
|
|
- (void)updateErrorMessage:(NSString *)message
|
|
withParsedStack:(NSArray<RCTJSStackFrame *> *)stack
|
|
errorCookie:(int)errorCookie;
|
|
- (void)dismiss;
|
|
- (void)addCustomButton:(NSString *)title onPressHandler:(RCTRedBoxButtonPressHandler)handler;
|
|
@property (nonatomic, strong) NSURL *overrideBundleURL;
|
|
@property (nonatomic, strong) dispatch_block_t overrideReloadAction;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTSourceCode.h}:
|
|
@interface RCTSourceCode : NSObject <RCTBridgeModule>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTStatusBarManager.h}:
|
|
@interface RCTConvert (UIStatusBar)
|
|
+ (UIStatusBarStyle)UIStatusBarStyle:(id)json;
|
|
+ (UIStatusBarAnimation)UIStatusBarAnimation:(id)json;
|
|
@end
|
|
@interface RCTStatusBarManager : RCTEventEmitter
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTTiming.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTTimingDelegate
|
|
- (void)callTimers:(NSArray<NSNumber *> *)timers;
|
|
- (void)immediatelyCallTimer:(NSNumber *)callbackID;
|
|
- (void)callIdleCallbacks:(NSNumber *)absoluteFrameStartMS;
|
|
@end
|
|
@interface RCTTiming : NSObject <RCTBridgeModule, RCTInvalidating, RCTFrameUpdateObserver, RCTInitializing>
|
|
- (instancetype)initWithDelegate:(id<RCTTimingDelegate>)delegate;
|
|
- (void)createTimerForNextFrame:(NSNumber *)callbackID
|
|
duration:(NSTimeInterval)jsDuration
|
|
jsSchedulingTime:(nullable NSDate *)jsSchedulingTime
|
|
repeats:(BOOL)repeats;
|
|
- (void)deleteTimer:(double)timerID;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/CoreModules/RCTWebSocketModule.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTWebSocketContentHandler <NSObject>
|
|
- (id)processWebsocketMessage:(id __nullable)message
|
|
forSocketID:(NSNumber *)socketID
|
|
withType:(NSString *__nonnull __autoreleasing *__nonnull)type;
|
|
@end
|
|
@interface RCTWebSocketModule : RCTEventEmitter
|
|
- (void)setContentHandler:(id<RCTWebSocketContentHandler> __nullable)handler forSocketID:(NSNumber *)socketID;
|
|
- (void)sendData:(NSData *)data forSocketID:(nonnull NSNumber *)socketID;
|
|
@end
|
|
@interface RCTBridge (RCTWebSocketModule)
|
|
- (RCTWebSocketModule *)webSocketModule;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTWebSocketModule)
|
|
- (RCTWebSocketModule *)webSocketModule;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/CxxBridge/NSDataBigString.h}:
|
|
namespace facebook::react {
|
|
class NSDataBigString : public JSBigString {
|
|
public:
|
|
NSDataBigString(NSData *data);
|
|
bool isAscii() const override
|
|
{
|
|
return false;
|
|
}
|
|
const char *c_str() const override
|
|
{
|
|
return (const char *)[m_data bytes];
|
|
}
|
|
size_t size() const override
|
|
{
|
|
return m_length;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/CxxBridge/RCTCxxBridgeDelegate.h}:
|
|
namespace facebook::react {
|
|
}
|
|
@protocol RCTCxxBridgeDelegate <RCTBridgeDelegate>
|
|
- (std::unique_ptr<facebook::react::JSExecutorFactory>)jsExecutorFactoryForBridge:(RCTBridge *)bridge;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CxxBridge/RCTJSIExecutorRuntimeInstaller.h}:
|
|
namespace facebook::react {
|
|
JSIExecutor::RuntimeInstaller RCTJSIExecutorRuntimeInstaller(
|
|
JSIExecutor::RuntimeInstaller runtimeInstallerToWrap);
|
|
}
|
|
|
|
/// @src {packages/react-native/React/CxxBridge/RCTMessageThread.h}:
|
|
namespace facebook::react {
|
|
class RCTMessageThread : public MessageQueueThread,
|
|
public std::enable_shared_from_this<RCTMessageThread> {
|
|
public:
|
|
RCTMessageThread(NSRunLoop* runLoop, RCTJavaScriptCompleteBlock errorBlock);
|
|
~RCTMessageThread() override;
|
|
void runOnQueue(std::function<void()>&&) override;
|
|
void runOnQueueSync(std::function<void()>&&) override;
|
|
void quitSynchronous() override;
|
|
void setRunLoop(NSRunLoop* runLoop);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/CxxBridge/RCTObjcExecutor.h}:
|
|
namespace facebook::react {
|
|
class RCTObjcExecutorFactory : public JSExecutorFactory {
|
|
public:
|
|
RCTObjcExecutorFactory(
|
|
id<RCTJavaScriptExecutor> jse,
|
|
RCTJavaScriptCompleteBlock errorBlock);
|
|
std::unique_ptr<JSExecutor> createJSExecutor(
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
std::shared_ptr<MessageQueueThread> jsQueue) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/CxxLogUtils/RCTDefaultCxxLogFunction.h}:
|
|
namespace facebook::react {
|
|
void RCTDefaultCxxLogFunction(ReactNativeLogLevel level, const char* message);
|
|
}
|
|
|
|
/// @src {packages/react-native/React/CxxModule/DispatchMessageQueueThread.h}:
|
|
namespace facebook::react {
|
|
class DispatchMessageQueueThread : public MessageQueueThread {
|
|
public:
|
|
DispatchMessageQueueThread(RCTModuleData *moduleData) : moduleData_(moduleData) {}
|
|
void runOnQueue(std::function<void()> &&func) override
|
|
{
|
|
dispatch_queue_t queue = moduleData_.methodQueue;
|
|
dispatch_block_t block = [func = std::move(func)] { func(); };
|
|
RCTAssert(block != nullptr, @"Invalid block generated in call to %@", moduleData_);
|
|
if (queue && block) {
|
|
dispatch_async(queue, block);
|
|
}
|
|
}
|
|
void runOnQueueSync(std::function<void()> &&__unused func) override
|
|
{
|
|
LOG(FATAL) << "Unsupported operation";
|
|
}
|
|
void quitSynchronous() override
|
|
{
|
|
LOG(FATAL) << "Unsupported operation";
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/CxxModule/RCTCxxMethod.h}:
|
|
@interface RCTCxxMethod : NSObject <RCTBridgeMethod>
|
|
- (instancetype)initWithCxxMethod:(const facebook::xplat::module::CxxModule::Method &)cxxMethod;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CxxModule/RCTCxxModule.h}:
|
|
namespace facebook::xplat::module {
|
|
}
|
|
@interface RCTCxxModule : NSObject <RCTBridgeModule>
|
|
- (std::unique_ptr<facebook::xplat::module::CxxModule>)createModule;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/CxxModule/RCTCxxUtils.h}:
|
|
|
|
namespace facebook::react {
|
|
std::vector<std::unique_ptr<NativeModule>>
|
|
createNativeModules(NSArray<RCTModuleData *> *modules, RCTBridge *bridge, const std::shared_ptr<Instance> &instance);
|
|
NSError *tryAndReturnError(const std::function<void()> &func);
|
|
NSString *deriveSourceURL(NSURL *url);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/CxxModule/RCTNativeModule.h}:
|
|
namespace facebook::react {
|
|
class RCTNativeModule : public NativeModule {
|
|
public:
|
|
RCTNativeModule(RCTBridge* bridge, RCTModuleData* moduleData);
|
|
std::string getName() override;
|
|
std::string getSyncMethodName(unsigned int methodId) override;
|
|
std::vector<MethodDescriptor> getMethods() override;
|
|
folly::dynamic getConstants() override;
|
|
void invoke(unsigned int methodId, folly::dynamic&& params, int callId)
|
|
override;
|
|
MethodCallResult callSerializableNativeHook(
|
|
unsigned int reactMethodId,
|
|
folly::dynamic&& params) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/CxxUtils/RCTFollyConvert.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTDevLoadingViewProtocol.h}:
|
|
|
|
@protocol RCTDevLoadingViewProtocol <NSObject>
|
|
+ (void)setEnabled:(BOOL)enabled;
|
|
- (void)showMessage:(NSString *)message color:(UIColor *)color backgroundColor:(UIColor *)backgroundColor;
|
|
- (void)showWithURL:(NSURL *)URL;
|
|
- (void)updateProgress:(RCTLoadingProgress *)progress;
|
|
- (void)hide;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTDevLoadingViewSetEnabled.h}:
|
|
RCT_EXTERN void RCTDevLoadingViewSetEnabled(BOOL enabled);
|
|
RCT_EXTERN BOOL RCTDevLoadingViewGetEnabled(void);
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTInspectorDevServerHelper.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTInspectorNetworkHelper.h}:
|
|
using RCTInspectorNetworkListener = facebook::react::jsinspector_modern::NetworkRequestListener;
|
|
using RCTInspectorNetworkExecutor = facebook::react::jsinspector_modern::ScopedExecutor<RCTInspectorNetworkListener>;
|
|
using RCTInspectorLoadNetworkResourceRequest = facebook::react::jsinspector_modern::LoadNetworkResourceRequest;
|
|
@interface RCTInspectorNetworkHelper : NSObject
|
|
- (instancetype)init;
|
|
- (void)loadNetworkResourceWithParams:(const RCTInspectorLoadNetworkResourceRequest &)params
|
|
executor:(RCTInspectorNetworkExecutor)executor;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTInspectorUtils.h}:
|
|
@interface CommonHostMetadata : NSObject
|
|
@property (nonatomic, strong) NSString *appDisplayName;
|
|
@property (nonatomic, strong) NSString *appIdentifier;
|
|
@property (nonatomic, strong) NSString *deviceName;
|
|
@property (nonatomic, strong) NSString *platform;
|
|
@property (nonatomic, strong) NSString *reactNativeVersion;
|
|
@end
|
|
@interface RCTInspectorUtils : NSObject
|
|
+ (CommonHostMetadata *)getHostMetadata;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTPackagerClient.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTPackagerConnection.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/DevSupport/RCTPausedInDebuggerOverlayController.h}:
|
|
@interface RCTPausedInDebuggerOverlayController : NSObject
|
|
- (void)showWithMessage:(NSString *)message onResume:(void (^)(void))onResume;
|
|
- (void)hide;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/AppleEventBeat.h}:
|
|
namespace facebook::react {
|
|
class AppleEventBeat : public EventBeat, public RunLoopObserver::Delegate {
|
|
public:
|
|
AppleEventBeat(
|
|
std::shared_ptr<OwnerBox> ownerBox,
|
|
std::unique_ptr<const RunLoopObserver> uiRunLoopObserver,
|
|
RuntimeScheduler& RuntimeScheduler);
|
|
void activityDidChange(
|
|
const RunLoopObserver::Delegate* delegate,
|
|
RunLoopObserver::Activity activity) const noexcept override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/ActivityIndicator/RCTActivityIndicatorViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTActivityIndicatorViewComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/DebuggingOverlay/RCTDebuggingOverlayComponentView.h}:
|
|
@interface RCTDebuggingOverlayComponentView : RCTViewComponentView <RCTDebuggingOverlayViewProtocol>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTImageComponentView : RCTViewComponentView <RCTImageResponseDelegate> {
|
|
@protected
|
|
RCTUIImageViewAnimated *_imageView;
|
|
}
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTInputAccessoryComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/InputAccessory/RCTInputAccessoryContentView.h}:
|
|
@interface RCTInputAccessoryContentView : UIView
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTLegacyViewManagerInteropComponentView : RCTViewComponentView
|
|
+ (BOOL)isSupported:(NSString *)componentName;
|
|
+ (void)supportLegacyViewManagerWithName:(NSString *)componentName;
|
|
+ (void)supportLegacyViewManagersWithPrefix:(NSString *)prefix;
|
|
- (UIView *)paperView;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropCoordinatorAdapter.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTLegacyViewManagerInteropCoordinatorAdapter : NSObject
|
|
- (instancetype)initWithCoordinator:(RCTLegacyViewManagerInteropCoordinator *)coordinator reactTag:(NSInteger)tag;
|
|
@property (strong, nonatomic) UIView *paperView;
|
|
@property (nonatomic, copy, nullable) void (^eventInterceptor)(std::string eventName, folly::dynamic &&event);
|
|
- (void)setProps:(const folly::dynamic &)props;
|
|
- (void)handleCommand:(NSString *)commandName args:(NSArray *)args;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTFabricModalHostViewController.h}:
|
|
@protocol RCTFabricModalHostViewControllerDelegate <NSObject>
|
|
- (void)boundsDidChange:(CGRect)newBounds;
|
|
@end
|
|
@interface RCTFabricModalHostViewController : UIViewController
|
|
@property (nonatomic, weak) id<RCTFabricModalHostViewControllerDelegate> delegate;
|
|
@property (nonatomic, assign) UIInterfaceOrientationMask supportedInterfaceOrientations;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Modal/RCTModalHostViewComponentView.h}:
|
|
@interface RCTModalHostViewComponentView : RCTViewComponentView <UIAdaptivePresentationControllerDelegate>
|
|
- (void)presentViewController:(UIViewController *)modalViewController
|
|
animated:(BOOL)animated
|
|
completion:(void (^)(void))completion;
|
|
- (void)dismissViewController:(UIViewController *)modalViewController
|
|
animated:(BOOL)animated
|
|
completion:(void (^)(void))completion;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h}:
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wreturn-type-c-linkage"
|
|
extern "C" {
|
|
Class<RCTComponentViewProtocol> RCTFabricComponentsProvider(const char* name);
|
|
Class<RCTComponentViewProtocol> RCTActivityIndicatorViewCls(void)
|
|
__attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTDebuggingOverlayCls(void)
|
|
__attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTInputAccessoryCls(void)
|
|
__attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTParagraphCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTPullToRefreshViewCls(void)
|
|
__attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTSafeAreaViewCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTScrollViewCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTSwitchCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTTextInputCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTUnimplementedNativeViewCls(void)
|
|
__attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTViewCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTImageCls(void) __attribute__((used));
|
|
Class<RCTComponentViewProtocol> RCTModalHostViewCls(void) __attribute__((used));
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Root/RCTRootComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTRootComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/SafeAreaView/RCTSafeAreaViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSafeAreaViewComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTCustomPullToRefreshViewProtocol.h}:
|
|
@protocol RCTCustomPullToRefreshViewProtocol
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTEnhancedScrollView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTEnhancedScrollViewOverridingDelegate <NSObject>
|
|
- (BOOL)touchesShouldCancelInContentView:(UIView *)view;
|
|
@end
|
|
@interface RCTEnhancedScrollView : UIScrollView
|
|
@property (nonatomic, strong, readonly) RCTGenericDelegateSplitter<id<UIScrollViewDelegate>> *delegateSplitter;
|
|
@property (nonatomic, weak) id<RCTEnhancedScrollViewOverridingDelegate> overridingDelegate;
|
|
@property (nonatomic, assign) BOOL pinchGestureEnabled;
|
|
@property (nonatomic, assign) BOOL centerContent;
|
|
@property (nonatomic, assign) CGFloat snapToInterval;
|
|
@property (nonatomic, copy) NSString *snapToAlignment;
|
|
@property (nonatomic, assign) BOOL disableIntervalMomentum;
|
|
@property (nonatomic, assign) BOOL snapToStart;
|
|
@property (nonatomic, assign) BOOL snapToEnd;
|
|
@property (nonatomic, copy) NSArray<NSNumber *> *snapToOffsets;
|
|
- (void)preserveContentOffsetWithBlock:(void (^)())block;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTPullToRefreshViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTPullToRefreshViewComponentView : RCTViewComponentView <RCTCustomPullToRefreshViewProtocol>
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/ScrollView/RCTScrollViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTScrollViewComponentView : RCTViewComponentView <RCTMountingTransactionObserving>
|
|
+ (nullable RCTScrollViewComponentView *)findScrollViewComponentViewForView:(UIView *)view;
|
|
@property (nonatomic, strong, readonly) UIScrollView *scrollView;
|
|
@property (nonatomic, assign) CGRect firstResponderFocus;
|
|
@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView;
|
|
@property (nonatomic, strong, readonly) UIView *containerView;
|
|
@property (nonatomic, strong, readonly)
|
|
RCTGenericDelegateSplitter<id<UIScrollViewDelegate>> *scrollViewDelegateSplitter;
|
|
@end
|
|
@interface RCTScrollViewComponentView (ScrollableProtocol) <RCTScrollableProtocol>
|
|
@end
|
|
@interface UIView (RCTScrollViewComponentView)
|
|
- (void)reactUpdateResponderOffsetForScrollView:(RCTScrollViewComponentView *)scrollView;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Switch/RCTSwitchComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSwitchComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTAccessibilityElement.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTAccessibilityElement : UIAccessibilityElement
|
|
@property (nonatomic, assign) CGRect frameInContainerSpace;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentAccessibilityProvider.h}:
|
|
/// @dep {packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.h}
|
|
|
|
@interface RCTParagraphComponentAccessibilityProvider : NSObject
|
|
- (instancetype)initWithString:(facebook::react::AttributedString)attributedString
|
|
layoutManager:(RCTTextLayoutManager *)layoutManager
|
|
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
|
|
frame:(CGRect)frame
|
|
view:(UIView *)view;
|
|
- (NSArray<UIAccessibilityElement *> *)accessibilityElements;
|
|
- (BOOL)isUpToDate:(facebook::react::AttributedString)currentAttributedString;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/Text/RCTParagraphComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTParagraphComponentView : RCTViewComponentView
|
|
@property (nonatomic, nullable, readonly) NSAttributedString *attributedText;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTTextInputComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputNativeCommands.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTTextInputViewProtocol <NSObject>
|
|
- (void)focus;
|
|
- (void)blur;
|
|
- (void)setTextAndSelection:(NSInteger)eventCount
|
|
value:(NSString *__nullable)value
|
|
start:(NSInteger)start
|
|
end:(NSInteger)end;
|
|
@end
|
|
RCT_EXTERN inline void
|
|
RCTTextInputHandleCommand(id<RCTTextInputViewProtocol> componentView, const NSString *commandName, const NSArray *args)
|
|
{
|
|
if ([commandName isEqualToString:@"focus"]) {
|
|
[componentView focus];
|
|
return;
|
|
}
|
|
if ([commandName isEqualToString:@"blur"]) {
|
|
[componentView blur];
|
|
return;
|
|
}
|
|
if ([commandName isEqualToString:@"setTextAndSelection"]) {
|
|
NSObject *arg0 = args[0];
|
|
NSInteger eventCount = [(NSNumber *)arg0 intValue];
|
|
NSObject *arg1 = args[1];
|
|
NSString *value = [arg1 isKindOfClass:[NSNull class]] ? nil : (NSString *)arg1;
|
|
NSObject *arg2 = args[2];
|
|
NSInteger start = [(NSNumber *)arg2 intValue];
|
|
NSObject *arg3 = args[3];
|
|
NSInteger end = [(NSNumber *)arg3 intValue];
|
|
[componentView setTextAndSelection:eventCount value:value start:start end:end];
|
|
return;
|
|
}
|
|
}
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
void RCTCopyBackedTextInput(
|
|
UIView<RCTBackedTextInputViewProtocol> *fromTextInput,
|
|
UIView<RCTBackedTextInputViewProtocol> *toTextInput);
|
|
UITextAutocorrectionType RCTUITextAutocorrectionTypeFromOptionalBool(std::optional<bool> autoCorrect);
|
|
UITextAutocapitalizationType RCTUITextAutocapitalizationTypeFromAutocapitalizationType(
|
|
facebook::react::AutocapitalizationType autocapitalizationType);
|
|
UIKeyboardAppearance RCTUIKeyboardAppearanceFromKeyboardAppearance(
|
|
facebook::react::KeyboardAppearance keyboardAppearance);
|
|
UITextSpellCheckingType RCTUITextSpellCheckingTypeFromOptionalBool(std::optional<bool> spellCheck);
|
|
UITextFieldViewMode RCTUITextFieldViewModeFromTextInputAccessoryVisibilityMode(
|
|
facebook::react::TextInputAccessoryVisibilityMode mode);
|
|
UIKeyboardType RCTUIKeyboardTypeFromKeyboardType(facebook::react::KeyboardType keyboardType);
|
|
UIReturnKeyType RCTUIReturnKeyTypeFromReturnKeyType(facebook::react::ReturnKeyType returnKeyType);
|
|
UITextContentType RCTUITextContentTypeFromString(const std::string &contentType);
|
|
UITextInputPasswordRules *RCTUITextInputPasswordRulesFromString(const std::string &passwordRules);
|
|
UITextSmartInsertDeleteType RCTUITextSmartInsertDeleteTypeFromOptionalBool(std::optional<bool> smartInsertDelete);
|
|
UIDataDetectorTypes RCTUITextViewDataDetectorTypesFromStringVector(const std::vector<std::string> &dataDetectorTypes);
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/UnimplementedComponent/RCTUnimplementedNativeComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTUnimplementedNativeComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/UnimplementedView/RCTUnimplementedViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTUnimplementedViewComponentView : RCTViewComponentView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTViewComponentView : UIView <RCTComponentViewProtocol, RCTTouchableComponentViewProtocol> {
|
|
@protected
|
|
facebook::react::LayoutMetrics _layoutMetrics;
|
|
facebook::react::SharedViewProps _props;
|
|
facebook::react::SharedViewEventEmitter _eventEmitter;
|
|
}
|
|
@property (nonatomic, strong, nullable) UIView *contentView;
|
|
@property (nonatomic, strong, nullable) NSString *nativeId;
|
|
@property (nonatomic, strong, nullable, readonly) NSObject *accessibilityElement;
|
|
@property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
|
|
- (void)updateProps:(const facebook::react::Props::Shared &)props
|
|
oldProps:(const facebook::react::Props::Shared &)oldProps NS_REQUIRES_SUPER;
|
|
- (void)updateEventEmitter:(const facebook::react::EventEmitter::Shared &)eventEmitter NS_REQUIRES_SUPER;
|
|
- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
|
|
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics NS_REQUIRES_SUPER;
|
|
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask NS_REQUIRES_SUPER;
|
|
- (void)prepareForRecycle NS_REQUIRES_SUPER;
|
|
- (UIView *)betterHitTest:(CGPoint)point withEvent:(UIEvent *)event;
|
|
- (NSString *)accessibilityLabelForCoopting;
|
|
- (BOOL)wantsToCooptLabel;
|
|
- (NSString *)componentViewName_DO_NOT_USE_THIS_IS_BROKEN;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/VirtualView/RCTVirtualViewComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTVirtualViewComponentView : RCTViewComponentView
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
|
|
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/ComponentViews/VirtualViewExperimental/RCTVirtualViewExperimentalComponentView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTVirtualViewExperimentalComponentView : RCTViewComponentView
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
- (instancetype)initWithCoder:(NSCoder *)coder NS_UNAVAILABLE;
|
|
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTComponentViewClassDescriptor.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
class RCTComponentViewClassDescriptor final {
|
|
public:
|
|
Class<RCTComponentViewProtocol> viewClass;
|
|
bool observesMountingTransactionWillMount{false};
|
|
bool observesMountingTransactionDidMount{false};
|
|
bool shouldBeRecycled{true};
|
|
};
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTComponentViewDescriptor.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
class RCTComponentViewDescriptor final {
|
|
public:
|
|
__strong UIView<RCTComponentViewProtocol> *view = nil;
|
|
bool observesMountingTransactionWillMount{false};
|
|
bool observesMountingTransactionDidMount{false};
|
|
bool shouldBeRecycled{true};
|
|
};
|
|
inline bool operator==(const RCTComponentViewDescriptor &lhs, const RCTComponentViewDescriptor &rhs)
|
|
{
|
|
return lhs.view == rhs.view;
|
|
}
|
|
inline bool operator!=(const RCTComponentViewDescriptor &lhs, const RCTComponentViewDescriptor &rhs)
|
|
{
|
|
return lhs.view != rhs.view;
|
|
}
|
|
template <>
|
|
struct std::hash<RCTComponentViewDescriptor> {
|
|
size_t operator()(const RCTComponentViewDescriptor &componentViewDescriptor) const
|
|
{
|
|
return std::hash<void *>()((__bridge void *)componentViewDescriptor.view);
|
|
}
|
|
};
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTComponentViewFactory.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
void RCTInstallNativeComponentRegistryBinding(facebook::jsi::Runtime &runtime);
|
|
@protocol RCTComponentViewFactoryComponentProvider <NSObject>
|
|
- (NSDictionary<NSString *, Class<RCTComponentViewProtocol>> *)thirdPartyFabricComponents;
|
|
@end
|
|
@interface RCTComponentViewFactory : NSObject
|
|
@property (nonatomic, weak) id<RCTComponentViewFactoryComponentProvider> thirdPartyFabricComponentsProvider;
|
|
+ (RCTComponentViewFactory *)currentComponentViewFactory;
|
|
- (void)registerComponentViewClass:(Class<RCTComponentViewProtocol>)componentViewClass;
|
|
- (RCTComponentViewDescriptor)createComponentViewWithComponentHandle:(facebook::react::ComponentHandle)componentHandle;
|
|
- (facebook::react::ComponentDescriptorRegistry::Shared)createComponentDescriptorRegistryWithParameters:
|
|
(facebook::react::ComponentDescriptorParameters)parameters;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTComponentViewProtocol.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_OPTIONS(NSInteger, RNComponentViewUpdateMask) {
|
|
RNComponentViewUpdateMaskNone = 0,
|
|
RNComponentViewUpdateMaskProps = 1 << 0,
|
|
RNComponentViewUpdateMaskEventEmitter = 1 << 1,
|
|
RNComponentViewUpdateMaskState = 1 << 2,
|
|
RNComponentViewUpdateMaskLayoutMetrics = 1 << 3,
|
|
RNComponentViewUpdateMaskAll = RNComponentViewUpdateMaskProps | RNComponentViewUpdateMaskEventEmitter |
|
|
RNComponentViewUpdateMaskState | RNComponentViewUpdateMaskLayoutMetrics
|
|
};
|
|
@protocol RCTComponentViewProtocol <NSObject>
|
|
+ (facebook::react::ComponentDescriptorProvider)componentDescriptorProvider;
|
|
+ (std::vector<facebook::react::ComponentDescriptorProvider>)supplementalComponentDescriptorProviders;
|
|
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
|
|
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
|
|
- (void)updateProps:(const facebook::react::Props::Shared &)props
|
|
oldProps:(const facebook::react::Props::Shared &)oldProps;
|
|
- (void)updateState:(const facebook::react::State::Shared &)state
|
|
oldState:(const facebook::react::State::Shared &)oldState;
|
|
- (void)updateEventEmitter:(const facebook::react::EventEmitter::Shared &)eventEmitter;
|
|
- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
|
|
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics;
|
|
- (void)handleCommand:(const NSString *)commandName args:(const NSArray *)args;
|
|
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask;
|
|
- (void)prepareForRecycle;
|
|
- (facebook::react::Props::Shared)props;
|
|
- (BOOL)isJSResponder;
|
|
- (void)setIsJSResponder:(BOOL)isJSResponder;
|
|
- (void)setPropKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN:(nullable NSSet<NSString *> *)props;
|
|
- (nullable NSSet<NSString *> *)propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTComponentViewRegistry.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTComponentViewRegistry : NSObject
|
|
@property (nonatomic, strong, readonly) RCTComponentViewFactory *componentViewFactory;
|
|
- (const RCTComponentViewDescriptor &)dequeueComponentViewWithComponentHandle:
|
|
(facebook::react::ComponentHandle)componentHandle
|
|
tag:(facebook::react::Tag)tag;
|
|
- (void)enqueueComponentViewWithComponentHandle:(facebook::react::ComponentHandle)componentHandle
|
|
tag:(facebook::react::Tag)tag
|
|
componentViewDescriptor:(RCTComponentViewDescriptor)componentViewDescriptor;
|
|
- (const RCTComponentViewDescriptor &)componentViewDescriptorWithTag:(facebook::react::Tag)tag;
|
|
- (nullable UIView<RCTComponentViewProtocol> *)findComponentViewWithTag:(facebook::react::Tag)tag;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTMountingManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTMountingManager : NSObject
|
|
@property (nonatomic, weak) id<RCTMountingManagerDelegate> delegate;
|
|
@property (nonatomic, strong) RCTComponentViewRegistry *componentViewRegistry;
|
|
- (void)setContextContainer:(std::shared_ptr<const facebook::react::ContextContainer>)contextContainer;
|
|
- (void)attachSurfaceToView:(UIView *)view surfaceId:(facebook::react::SurfaceId)surfaceId;
|
|
- (void)detachSurfaceFromView:(UIView *)view surfaceId:(facebook::react::SurfaceId)surfaceId;
|
|
- (void)scheduleTransaction:(std::shared_ptr<const facebook::react::MountingCoordinator>)mountingCoordinator;
|
|
- (void)dispatchCommand:(ReactTag)reactTag commandName:(NSString *)commandName args:(NSArray *)args;
|
|
- (void)sendAccessibilityEvent:(ReactTag)reactTag eventType:(NSString *)eventType;
|
|
- (void)setIsJSResponder:(BOOL)isJSResponder
|
|
blockNativeResponder:(BOOL)blockNativeResponder
|
|
forShadowView:(const facebook::react::ShadowView &)shadowView;
|
|
- (void)synchronouslyUpdateViewOnUIThread:(ReactTag)reactTag
|
|
changedProps:(folly::dynamic)props
|
|
componentDescriptor:(const facebook::react::ComponentDescriptor &)componentDescriptor;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTMountingManagerDelegate.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTMountingManagerDelegate <NSObject>
|
|
- (void)mountingManager:(RCTMountingManager *)mountingManager willMountComponentsWithRootTag:(ReactTag)MountingManager;
|
|
- (void)mountingManager:(RCTMountingManager *)mountingManager didMountComponentsWithRootTag:(ReactTag)rootTag;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTMountingTransactionObserverCoordinator.h}:
|
|
class RCTMountingTransactionObserverCoordinator final {
|
|
public:
|
|
void registerViewComponentDescriptor(
|
|
const RCTComponentViewDescriptor& componentViewDescriptor,
|
|
facebook::react::SurfaceId surfaceId);
|
|
void unregisterViewComponentDescriptor(
|
|
const RCTComponentViewDescriptor& componentViewDescriptor,
|
|
facebook::react::SurfaceId surfaceId);
|
|
void notifyObserversMountingTransactionWillMount(
|
|
const facebook::react::MountingTransaction& transaction,
|
|
const facebook::react::SurfaceTelemetry& surfaceTelemetry) const;
|
|
void notifyObserversMountingTransactionDidMount(
|
|
const facebook::react::MountingTransaction& transaction,
|
|
const facebook::react::SurfaceTelemetry& surfaceTelemetry) const;
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/RCTMountingTransactionObserving.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTMountingTransactionObserving <NSObject>
|
|
@optional
|
|
- (void)mountingTransactionWillMount:(const facebook::react::MountingTransaction &)transaction
|
|
withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry;
|
|
- (void)mountingTransactionDidMount:(const facebook::react::MountingTransaction &)transaction
|
|
withSurfaceTelemetry:(const facebook::react::SurfaceTelemetry &)surfaceTelemetry;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Mounting/UIView+ComponentViewProtocol.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface UIView (ComponentViewProtocol) <RCTComponentViewProtocol>
|
|
+ (std::vector<facebook::react::ComponentDescriptorProvider>)supplementalComponentDescriptorProviders;
|
|
- (void)mountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
|
|
- (void)unmountChildComponentView:(UIView<RCTComponentViewProtocol> *)childComponentView index:(NSInteger)index;
|
|
- (void)updateProps:(const facebook::react::Props::Shared &)props
|
|
oldProps:(const facebook::react::Props::Shared &)oldProps;
|
|
- (void)updateEventEmitter:(const facebook::react::EventEmitter::Shared &)eventEmitter;
|
|
- (void)updateState:(const facebook::react::State::Shared &)state
|
|
oldState:(const facebook::react::State::Shared &)oldState;
|
|
- (void)updateLayoutMetrics:(const facebook::react::LayoutMetrics &)layoutMetrics
|
|
oldLayoutMetrics:(const facebook::react::LayoutMetrics &)oldLayoutMetrics;
|
|
- (void)finalizeUpdates:(RNComponentViewUpdateMask)updateMask;
|
|
- (void)prepareForRecycle;
|
|
- (facebook::react::Props::Shared)props;
|
|
- (void)setIsJSResponder:(BOOL)isJSResponder;
|
|
- (void)setPropKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN:(nullable NSSet<NSString *> *)props;
|
|
- (nullable NSSet<NSString *> *)propKeysManagedByAnimated_DO_NOT_USE_THIS_IS_BROKEN;
|
|
- (void)updateClippedSubviewsWithClipRect:(CGRect)clipRect relativeToView:(UIView *)clipView;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTConversions.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
inline NSString *RCTNSStringFromString(
|
|
const std::string &string,
|
|
const NSStringEncoding &encoding = NSUTF8StringEncoding)
|
|
{
|
|
return [NSString stringWithCString:string.c_str() encoding:encoding] ?: @"";
|
|
}
|
|
inline NSString *_Nullable RCTNSStringFromStringNilIfEmpty(
|
|
const std::string &string,
|
|
const NSStringEncoding &encoding = NSUTF8StringEncoding)
|
|
{
|
|
return string.empty() ? nil : RCTNSStringFromString(string, encoding);
|
|
}
|
|
inline std::string RCTStringFromNSString(NSString *string)
|
|
{
|
|
return std::string{string.UTF8String ?: ""};
|
|
}
|
|
inline UIColor *_Nullable RCTUIColorFromSharedColor(const facebook::react::SharedColor &sharedColor)
|
|
{
|
|
return RCTPlatformColorFromColor(*sharedColor);
|
|
}
|
|
inline CF_RETURNS_RETAINED CGColorRef _Nullable RCTCreateCGColorRefFromSharedColor(
|
|
const facebook::react::SharedColor &sharedColor)
|
|
{
|
|
return CGColorRetain(RCTUIColorFromSharedColor(sharedColor).CGColor);
|
|
}
|
|
inline CGPoint RCTCGPointFromPoint(const facebook::react::Point &point)
|
|
{
|
|
return {point.x, point.y};
|
|
}
|
|
inline CGSize RCTCGSizeFromSize(const facebook::react::Size &size)
|
|
{
|
|
return {size.width, size.height};
|
|
}
|
|
inline CGRect RCTCGRectFromRect(const facebook::react::Rect &rect)
|
|
{
|
|
return {RCTCGPointFromPoint(rect.origin), RCTCGSizeFromSize(rect.size)};
|
|
}
|
|
inline UIEdgeInsets RCTUIEdgeInsetsFromEdgeInsets(const facebook::react::EdgeInsets &edgeInsets)
|
|
{
|
|
return {edgeInsets.top, edgeInsets.left, edgeInsets.bottom, edgeInsets.right};
|
|
}
|
|
const UIAccessibilityTraits AccessibilityTraitSwitch = 0x20000000000001;
|
|
inline UIAccessibilityTraits RCTUIAccessibilityTraitsFromAccessibilityTraits(
|
|
facebook::react::AccessibilityTraits accessibilityTraits)
|
|
{
|
|
using AccessibilityTraits = facebook::react::AccessibilityTraits;
|
|
UIAccessibilityTraits result = UIAccessibilityTraitNone;
|
|
if ((accessibilityTraits & AccessibilityTraits::Button) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitButton;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::Link) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitLink;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::Image) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitImage;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::Selected) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitSelected;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::PlaysSound) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitPlaysSound;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::KeyboardKey) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitKeyboardKey;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::StaticText) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitStaticText;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::SummaryElement) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitSummaryElement;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::NotEnabled) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitNotEnabled;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::UpdatesFrequently) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitUpdatesFrequently;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::SearchField) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitSearchField;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::StartsMediaSession) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitStartsMediaSession;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::Adjustable) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitAdjustable;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::AllowsDirectInteraction) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitAllowsDirectInteraction;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::CausesPageTurn) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitCausesPageTurn;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::Header) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitHeader;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::Switch) != AccessibilityTraits::None) {
|
|
result |= AccessibilityTraitSwitch;
|
|
}
|
|
if ((accessibilityTraits & AccessibilityTraits::TabBar) != AccessibilityTraits::None) {
|
|
result |= UIAccessibilityTraitTabBar;
|
|
}
|
|
return result;
|
|
};
|
|
inline CATransform3D RCTCATransform3DFromTransformMatrix(const facebook::react::Transform &transformMatrix)
|
|
{
|
|
return {
|
|
(CGFloat)transformMatrix.matrix[0],
|
|
(CGFloat)transformMatrix.matrix[1],
|
|
(CGFloat)transformMatrix.matrix[2],
|
|
(CGFloat)transformMatrix.matrix[3],
|
|
(CGFloat)transformMatrix.matrix[4],
|
|
(CGFloat)transformMatrix.matrix[5],
|
|
(CGFloat)transformMatrix.matrix[6],
|
|
(CGFloat)transformMatrix.matrix[7],
|
|
(CGFloat)transformMatrix.matrix[8],
|
|
(CGFloat)transformMatrix.matrix[9],
|
|
(CGFloat)transformMatrix.matrix[10],
|
|
(CGFloat)transformMatrix.matrix[11],
|
|
(CGFloat)transformMatrix.matrix[12],
|
|
(CGFloat)transformMatrix.matrix[13],
|
|
(CGFloat)transformMatrix.matrix[14],
|
|
(CGFloat)transformMatrix.matrix[15]};
|
|
}
|
|
inline facebook::react::Point RCTPointFromCGPoint(const CGPoint &point)
|
|
{
|
|
return {point.x, point.y};
|
|
}
|
|
inline facebook::react::Float RCTFloatFromCGFloat(CGFloat value)
|
|
{
|
|
if (value == CGFLOAT_MAX) {
|
|
return std::numeric_limits<facebook::react::Float>::infinity();
|
|
}
|
|
return value;
|
|
}
|
|
inline facebook::react::Size RCTSizeFromCGSize(const CGSize &size)
|
|
{
|
|
return {RCTFloatFromCGFloat(size.width), RCTFloatFromCGFloat(size.height)};
|
|
}
|
|
inline facebook::react::Rect RCTRectFromCGRect(const CGRect &rect)
|
|
{
|
|
return {RCTPointFromCGPoint(rect.origin), RCTSizeFromCGSize(rect.size)};
|
|
}
|
|
inline facebook::react::EdgeInsets RCTEdgeInsetsFromUIEdgeInsets(const UIEdgeInsets &edgeInsets)
|
|
{
|
|
return {edgeInsets.left, edgeInsets.top, edgeInsets.right, edgeInsets.bottom};
|
|
}
|
|
inline facebook::react::LayoutDirection RCTLayoutDirection(BOOL isRTL)
|
|
{
|
|
return isRTL ? facebook::react::LayoutDirection::RightToLeft : facebook::react::LayoutDirection::LeftToRight;
|
|
}
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTImageResponseDelegate.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTImageResponseDelegate <NSObject>
|
|
- (void)didReceiveImage:(UIImage *)image metadata:(id)metadata fromObserver:(const void *)observer;
|
|
- (void)didReceiveProgress:(float)progress
|
|
loaded:(int64_t)loaded
|
|
total:(int64_t)total
|
|
fromObserver:(const void *)observer;
|
|
- (void)didReceiveFailure:(NSError *)error fromObserver:(const void *)observer;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTImageResponseObserverProxy.h}:
|
|
/// @dep {packages/react-native/React/Fabric/RCTImageResponseDelegate.h}
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
namespace facebook::react {
|
|
class RCTImageResponseObserverProxy final : public ImageResponseObserver {
|
|
public:
|
|
RCTImageResponseObserverProxy(id<RCTImageResponseDelegate> delegate = nil);
|
|
void didReceiveImage(const ImageResponse &imageResponse) const override;
|
|
void didReceiveProgress(float progress, int64_t loaded, int64_t total) const override;
|
|
void didReceiveFailure(const ImageLoadError &error) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTLocalizationProvider.h}:
|
|
@protocol RCTLocalizationProtocol <NSObject>
|
|
- (NSString *)localizedString:(NSString *)oldString withDescription:(NSString *)description;
|
|
@end
|
|
RCT_EXTERN void setLocalizationDelegate(id<RCTLocalizationProtocol> delegate);
|
|
RCT_EXTERN void setLocalizationLanguagePack(NSDictionary<NSString *, NSString *> *pack);
|
|
@interface RCTLocalizationProvider : NSObject
|
|
+ (NSString *)RCTLocalizedString:(NSString *)oldString withDescription:(NSString *)description;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTPrimitives.h}:
|
|
using ReactTag = NSInteger;
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTScheduler.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTSchedulerDelegate
|
|
- (void)schedulerDidFinishTransaction:(std::shared_ptr<const facebook::react::MountingCoordinator>)mountingCoordinator;
|
|
- (void)schedulerShouldRenderTransactions:
|
|
(std::shared_ptr<const facebook::react::MountingCoordinator>)mountingCoordinator;
|
|
- (void)schedulerDidDispatchCommand:(const facebook::react::ShadowView &)shadowView
|
|
commandName:(const std::string &)commandName
|
|
args:(const folly::dynamic &)args;
|
|
- (void)schedulerDidSendAccessibilityEvent:(const facebook::react::ShadowView &)shadowView
|
|
eventType:(const std::string &)eventType;
|
|
- (void)schedulerDidSetIsJSResponder:(BOOL)isJSResponder
|
|
blockNativeResponder:(BOOL)blockNativeResponder
|
|
forShadowView:(const facebook::react::ShadowView &)shadowView;
|
|
- (void)schedulerDidSynchronouslyUpdateViewOnUIThread:(facebook::react::Tag)reactTag props:(folly::dynamic)props;
|
|
@end
|
|
@interface RCTScheduler : NSObject
|
|
@property (atomic, weak, nullable) id<RCTSchedulerDelegate> delegate;
|
|
@property (readonly) const std::shared_ptr<facebook::react::UIManager> uiManager;
|
|
- (instancetype)initWithToolbox:(facebook::react::SchedulerToolbox)toolbox;
|
|
- (void)registerSurface:(const facebook::react::SurfaceHandler &)surfaceHandler;
|
|
- (void)unregisterSurface:(const facebook::react::SurfaceHandler &)surfaceHandler;
|
|
- (const facebook::react::ComponentDescriptor *)findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN:
|
|
(facebook::react::ComponentHandle)handle;
|
|
- (void)setupAnimationDriver:(const facebook::react::SurfaceHandler &)surfaceHandler;
|
|
- (void)onAnimationStarted;
|
|
- (void)onAllAnimationsComplete;
|
|
- (void)animationTick;
|
|
- (void)reportMount:(facebook::react::SurfaceId)surfaceId;
|
|
- (void)addEventListener:(const std::shared_ptr<facebook::react::EventListener> &)listener;
|
|
- (void)removeEventListener:(const std::shared_ptr<facebook::react::EventListener> &)listener;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTSurfacePointerHandler.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfacePointerHandler : UIGestureRecognizer
|
|
- (void)attachToView:(UIView *)view;
|
|
- (void)detachFromView:(UIView *)view;
|
|
@property (nonatomic, assign) CGPoint viewOriginOffset;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTSurfacePresenter.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfacePresenter : NSObject
|
|
- (instancetype)initWithContextContainer:(std::shared_ptr<const facebook::react::ContextContainer>)contextContainer
|
|
runtimeExecutor:(facebook::react::RuntimeExecutor)runtimeExecutor
|
|
bridgelessBindingsExecutor:(std::optional<facebook::react::RuntimeExecutor>)bridgelessBindingsExecutor;
|
|
@property (nonatomic) std::shared_ptr<const facebook::react::ContextContainer> contextContainer;
|
|
@property (nonatomic) facebook::react::RuntimeExecutor runtimeExecutor;
|
|
- (BOOL)suspend;
|
|
- (BOOL)resume;
|
|
@end
|
|
@interface RCTSurfacePresenter (Surface) <RCTSurfacePresenterStub>
|
|
- (void)registerSurface:(RCTFabricSurface *)surface;
|
|
- (void)unregisterSurface:(RCTFabricSurface *)surface;
|
|
@property (readonly) RCTMountingManager *mountingManager;
|
|
@property (readonly, nullable) RCTScheduler *scheduler;
|
|
- (id<RCTSurfaceProtocol>)createFabricSurfaceForModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *)initialProperties;
|
|
- (nullable RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag;
|
|
- (void)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
|
|
- (void)schedulerDidSynchronouslyUpdateViewOnUIThread:(ReactTag)tag props:(folly::dynamic)props;
|
|
- (void)setupAnimationDriverWithSurfaceHandler:(const facebook::react::SurfaceHandler &)surfaceHandler;
|
|
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
|
|
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
|
|
- (nullable UIView *)findComponentViewWithTag_DO_NOT_USE_DEPRECATED:(NSInteger)tag;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTSurfacePresenterBridgeAdapter.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
facebook::react::RuntimeExecutor RCTRuntimeExecutorFromBridge(RCTBridge *bridge);
|
|
@interface RCTSurfacePresenterBridgeAdapter : NSObject
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
contextContainer:(std::shared_ptr<const facebook::react::ContextContainer>)contextContainer;
|
|
@property (nonatomic, readonly) RCTSurfacePresenter *surfacePresenter;
|
|
@property (nonatomic, weak) RCTBridge *bridge;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTSurfaceRegistry.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
using RCTSurfaceEnumeratorBlock = void (^)(NSEnumerator<RCTFabricSurface *> *_Nonnull __strong);
|
|
@interface RCTSurfaceRegistry : NSObject
|
|
- (void)enumerateWithBlock:(RCTSurfaceEnumeratorBlock)block;
|
|
- (void)registerSurface:(RCTFabricSurface *)surface;
|
|
- (void)unregisterSurface:(RCTFabricSurface *)surface;
|
|
- (nullable RCTFabricSurface *)surfaceForRootTag:(ReactTag)rootTag;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTSurfaceTouchHandler.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSurfaceTouchHandler : UIGestureRecognizer
|
|
- (void)attachToView:(UIView *)view;
|
|
- (void)detachFromView:(UIView *)view;
|
|
@property (nonatomic, assign) CGPoint viewOriginOffset;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/RCTTouchableComponentViewProtocol.h}:
|
|
@protocol RCTTouchableComponentViewProtocol <NSObject>
|
|
- (facebook::react::SharedTouchEventEmitter)touchEventEmitterAtPoint:(CGPoint)point;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Surface/RCTFabricSurface.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTFabricSurface : NSObject <RCTSurfaceProtocol>
|
|
- (instancetype)initWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter
|
|
moduleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *)initialProperties;
|
|
- (void)resetWithSurfacePresenter:(RCTSurfacePresenter *)surfacePresenter;
|
|
- (RCTSurfaceView *)view;
|
|
@property (atomic, assign, readonly) CGSize minimumSize;
|
|
@property (atomic, assign, readonly) CGSize maximumSize;
|
|
@property (atomic, assign, readonly) CGPoint viewportOffset;
|
|
- (void)setSize:(CGSize)size;
|
|
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
|
|
@property (atomic, assign, readonly) CGSize intrinsicSize;
|
|
- (BOOL)synchronouslyWaitFor:(NSTimeInterval)timeout;
|
|
@end
|
|
@interface RCTFabricSurface (Internal)
|
|
- (const facebook::react::SurfaceHandler &)surfaceHandler;
|
|
@end
|
|
@interface RCTFabricSurface (Deprecated)
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
moduleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *)initialProperties;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/PlatformRunLoopObserver.h}:
|
|
namespace facebook::react {
|
|
class PlatformRunLoopObserver : public RunLoopObserver {
|
|
public:
|
|
PlatformRunLoopObserver(
|
|
RunLoopObserver::Activity activities,
|
|
RunLoopObserver::WeakOwner owner,
|
|
CFRunLoopRef runLoop);
|
|
~PlatformRunLoopObserver();
|
|
virtual bool isOnRunLoopThread() const noexcept override;
|
|
};
|
|
class MainRunLoopObserver final : public PlatformRunLoopObserver {
|
|
public:
|
|
MainRunLoopObserver(
|
|
RunLoopObserver::Activity activities,
|
|
RunLoopObserver::WeakOwner owner)
|
|
: PlatformRunLoopObserver(
|
|
activities,
|
|
std::move(owner),
|
|
CFRunLoopGetMain()) {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTBoxShadow.h}:
|
|
RCT_EXTERN CALayer *RCTGetBoxShadowLayer(
|
|
const facebook::react::BoxShadow &shadow,
|
|
RCTCornerRadii cornerRadii,
|
|
UIEdgeInsets edgeInsets,
|
|
CGSize layerSize);
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTColorSpaceUtils.h}:
|
|
@interface RCTColorSpaceUtils : NSObject
|
|
+ (void)applyDefaultColorSpace:(RCTColorSpace)colorSpace;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTGenericDelegateSplitter.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTGenericDelegateSplitter<DelegateT> : NSObject
|
|
@property (nonatomic, copy, nullable) void (^delegateUpdateBlock)(DelegateT _Nullable delegate);
|
|
- (instancetype)initWithDelegateUpdateBlock:(void (^)(DelegateT _Nullable delegate))block;
|
|
- (void)addDelegate:(DelegateT)delegate;
|
|
- (void)removeDelegate:(DelegateT)delegate;
|
|
- (void)removeAllDelegates;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTGradientUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTGradientUtils : NSObject
|
|
+ (std::vector<facebook::react::ProcessedColorStop>)getFixedColorStops:
|
|
(const std::vector<facebook::react::ColorStop> &)colorStops
|
|
gradientLineLength:(CGFloat)gradientLineLength;
|
|
+ (std::pair<CGPoint, CGPoint>)pointsForCAGradientLayerLinearGradient:(CGPoint)startPoint
|
|
endPoint:(CGPoint)endPoint
|
|
bounds:(CGSize)bounds;
|
|
+ (void)getColors:(NSMutableArray<id> *)colors
|
|
andLocations:(NSMutableArray<NSNumber *> *)locations
|
|
fromColorStops:(const std::vector<facebook::react::ProcessedColorStop> &)colorStops;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTIdentifierPool.h}:
|
|
namespace facebook::react {
|
|
template <size_t size>
|
|
class RCTIdentifierPool {
|
|
public:
|
|
void enqueue(int index) {
|
|
usage[index] = false;
|
|
}
|
|
int dequeue() {
|
|
while (true) {
|
|
if (!usage[lastIndex]) {
|
|
usage[lastIndex] = true;
|
|
return lastIndex;
|
|
}
|
|
lastIndex = (lastIndex + 1) % size;
|
|
}
|
|
}
|
|
void reset() {
|
|
for (int i = 0; i < size; i++) {
|
|
usage[i] = false;
|
|
}
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTLinearGradient.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTLinearGradient : NSObject
|
|
+ (CALayer *)gradientLayerWithSize:(CGSize)size gradient:(const facebook::react::LinearGradient &)gradient;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTRadialGradient.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTRadialGradient : NSObject
|
|
+ (CALayer *)gradientLayerWithSize:(CGSize)size gradient:(const facebook::react::RadialGradient &)gradient;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Fabric/Utils/RCTReactTaggedView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTReactTaggedView : NSObject {
|
|
UIView *_view;
|
|
NSInteger _tag;
|
|
}
|
|
+ (RCTReactTaggedView *)wrap:(UIView *)view;
|
|
- (instancetype)initWithView:(UIView *)view;
|
|
- (nullable UIView *)view;
|
|
- (NSInteger)tag;
|
|
- (BOOL)isEqual:(id)other;
|
|
- (NSUInteger)hash;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/I18n/FBXXHashUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
static const uint64_t METAXXHASHUTILS_PRIME_1 = 11400714785074694791ULL;
|
|
static const uint64_t METAXXHASHUTILS_PRIME_2 = 14029467366897019727ULL;
|
|
static const uint64_t METAXXHASHUTILS_PRIME_3 = 1609587929392839161ULL;
|
|
static const uint64_t METAXXHASHUTILS_PRIME_4 = 9650029242287828579ULL;
|
|
static const uint64_t METAXXHASHUTILS_PRIME_5 = 2870177450012600261ULL;
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.") NS_INLINE uint64_t rotl(uint64_t x, int r)
|
|
{
|
|
return ((x << r) | (x >> (64 - r)));
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t mix1(const uint64_t h, const uint64_t prime, int rshift)
|
|
{
|
|
return (h ^ (h >> rshift)) * prime;
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t mix2(const uint64_t p, const uint64_t v)
|
|
{
|
|
return rotl(v + p * METAXXHASHUTILS_PRIME_2, 31) * METAXXHASHUTILS_PRIME_1;
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t mix3(const uint64_t h, const uint64_t v)
|
|
{
|
|
return (h ^ mix2(v, 0)) * METAXXHASHUTILS_PRIME_1 + METAXXHASHUTILS_PRIME_4;
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.") NS_INLINE uint32_t endian32(const char *v)
|
|
{
|
|
return (uint32_t)((uint8_t)(v[0])) | ((uint32_t)((uint8_t)(v[1])) << 8) | ((uint32_t)((uint8_t)(v[2])) << 16) |
|
|
((uint32_t)((uint8_t)(v[3])) << 24);
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.") NS_INLINE uint64_t endian64(const char *v)
|
|
{
|
|
return (uint64_t)((uint8_t)(v[0])) | ((uint64_t)((uint8_t)(v[1])) << 8) | ((uint64_t)((uint8_t)(v[2])) << 16) |
|
|
((uint64_t)((uint8_t)(v[3])) << 24) | ((uint64_t)((uint8_t)(v[4])) << 32) | ((uint64_t)((uint8_t)(v[5])) << 40) |
|
|
((uint64_t)((uint8_t)(v[6])) << 48) | ((uint64_t)((uint8_t)(v[7])) << 56);
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t fetch64(const char *p, const uint64_t v)
|
|
{
|
|
return mix2(endian64(p), v);
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.") NS_INLINE uint64_t fetch32(const char *p)
|
|
{
|
|
return (uint64_t)(endian32(p))*METAXXHASHUTILS_PRIME_1;
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.") NS_INLINE uint64_t fetch8(const char *p)
|
|
{
|
|
return (uint8_t)(*p) * METAXXHASHUTILS_PRIME_5;
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t finalize(const uint64_t h, const char *p, uint64_t len)
|
|
{
|
|
return (len >= 8)
|
|
? (finalize(rotl(h ^ fetch64(p, 0), 27) * METAXXHASHUTILS_PRIME_1 + METAXXHASHUTILS_PRIME_4, p + 8, len - 8))
|
|
: ((len >= 4)
|
|
? (finalize(rotl(h ^ fetch32(p), 23) * METAXXHASHUTILS_PRIME_2 + METAXXHASHUTILS_PRIME_3, p + 4, len - 4))
|
|
: ((len > 0) ? (finalize(rotl(h ^ fetch8(p), 11) * METAXXHASHUTILS_PRIME_1, p + 1, len - 1))
|
|
: (mix1(mix1(mix1(h, METAXXHASHUTILS_PRIME_2, 33), METAXXHASHUTILS_PRIME_3, 29), 1, 32))));
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t h32bytes_compute(
|
|
const char *p,
|
|
uint64_t len,
|
|
const uint64_t v1,
|
|
const uint64_t v2,
|
|
const uint64_t v3,
|
|
const uint64_t v4)
|
|
{
|
|
return (len >= 32)
|
|
? h32bytes_compute(p + 32, len - 32, fetch64(p, v1), fetch64(p + 8, v2), fetch64(p + 16, v3), fetch64(p + 24, v4))
|
|
: mix3(mix3(mix3(mix3(rotl(v1, 1) + rotl(v2, 7) + rotl(v3, 12) + rotl(v4, 18), v1), v2), v3), v4);
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t h32bytes(const char *p, uint64_t len, const uint64_t seed)
|
|
{
|
|
return h32bytes_compute(
|
|
p,
|
|
len,
|
|
seed + METAXXHASHUTILS_PRIME_1 + METAXXHASHUTILS_PRIME_2,
|
|
seed + METAXXHASHUTILS_PRIME_2,
|
|
seed,
|
|
seed - METAXXHASHUTILS_PRIME_1);
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t meta_xxhash64(const char *p, uint64_t len, uint64_t seed)
|
|
{
|
|
return finalize(
|
|
(len >= 32 ? h32bytes(p, len, seed) : seed + METAXXHASHUTILS_PRIME_5) + len, p + (len & ~0x1FULL), len & 0x1FULL);
|
|
}
|
|
NS_SWIFT_UNAVAILABLE("You'll need to bridge to C/ObjC to use this API.")
|
|
NS_INLINE uint64_t FBxxHash64(const char *p, uint64_t len, uint64_t seed)
|
|
{
|
|
return meta_xxhash64(p, len, seed);
|
|
}
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/I18n/RCTLocalizedString.h}:
|
|
extern "C" {
|
|
uint64_t FBcoreLocalexxHash48(const char *input, uint64_t length, uint64_t seed);
|
|
NSString *RCTLocalizedStringFromKey(uint64_t key, NSString *defaultValue);
|
|
}
|
|
|
|
/// @src {packages/react-native/React/Inspector/RCTCxxInspectorPackagerConnection.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Inspector/RCTCxxInspectorPackagerConnectionDelegate.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Inspector/RCTCxxInspectorWebSocketAdapter.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Inspector/RCTInspector.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Inspector/RCTInspectorPackagerConnection.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTEventEmitter.h}:
|
|
@interface RCTEventEmitter : NSObject <RCTBridgeModule, RCTInvalidating>
|
|
@property (nonatomic, weak) RCTBridge *bridge;
|
|
@property (nonatomic, weak) RCTModuleRegistry *moduleRegistry;
|
|
@property (nonatomic, weak) RCTViewRegistry *viewRegistry_DEPRECATED;
|
|
- (instancetype)initWithDisabledObservation;
|
|
- (NSArray<NSString *> *)supportedEvents;
|
|
- (void)sendEventWithName:(NSString *)name body:(id)body;
|
|
- (void)startObserving;
|
|
- (void)stopObserving;
|
|
- (void)invalidate NS_REQUIRES_SUPER;
|
|
- (void)addListener:(NSString *)eventName;
|
|
- (void)removeListeners:(double)count;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTI18nUtil.h}:
|
|
@interface RCTI18nUtil : NSObject
|
|
+ (instancetype)sharedInstance;
|
|
- (BOOL)isRTL;
|
|
- (BOOL)isRTLAllowed;
|
|
- (void)allowRTL:(BOOL)value;
|
|
- (BOOL)isRTLForced;
|
|
- (void)forceRTL:(BOOL)value;
|
|
- (BOOL)doLeftAndRightSwapInRTL;
|
|
- (void)swapLeftAndRightInRTL:(BOOL)value;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTLayoutAnimation.h}:
|
|
@interface RCTLayoutAnimation : NSObject
|
|
@property (nonatomic, readonly) NSTimeInterval duration;
|
|
@property (nonatomic, readonly) NSTimeInterval delay;
|
|
@property (nonatomic, readonly, copy) NSString *property ;
|
|
@property (nonatomic, readonly) CGFloat springDamping;
|
|
@property (nonatomic, readonly) CGFloat initialVelocity;
|
|
@property (nonatomic, readonly) RCTAnimationType animationType;
|
|
+ (void)initializeStatics;
|
|
- (instancetype)initWithDuration:(NSTimeInterval)duration
|
|
delay:(NSTimeInterval)delay
|
|
property:(NSString *)property
|
|
springDamping:(CGFloat)springDamping
|
|
initialVelocity:(CGFloat)initialVelocity
|
|
animationType:(RCTAnimationType)animationType;
|
|
- (instancetype)initWithDuration:(NSTimeInterval)duration config:(NSDictionary *)config;
|
|
- (void)performAnimations:(void (^)(void))animations withCompletionBlock:(void (^)(BOOL completed))completionBlock;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTLayoutAnimationGroup.h}:
|
|
|
|
@interface RCTLayoutAnimationGroup : NSObject
|
|
@property (nonatomic, readonly) RCTLayoutAnimation *creatingLayoutAnimation;
|
|
@property (nonatomic, readonly) RCTLayoutAnimation *updatingLayoutAnimation;
|
|
@property (nonatomic, readonly) RCTLayoutAnimation *deletingLayoutAnimation;
|
|
@property (nonatomic, copy) RCTResponseSenderBlock callback;
|
|
- (instancetype)initWithCreatingLayoutAnimation:(RCTLayoutAnimation *)creatingLayoutAnimation
|
|
updatingLayoutAnimation:(RCTLayoutAnimation *)updatingLayoutAnimation
|
|
deletingLayoutAnimation:(RCTLayoutAnimation *)deletingLayoutAnimation
|
|
callback:(RCTResponseSenderBlock)callback;
|
|
- (instancetype)initWithConfig:(NSDictionary *)config callback:(RCTResponseSenderBlock)callback;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTRedBoxExtraDataViewController.h}:
|
|
@protocol RCTRedBoxExtraDataActionDelegate <NSObject>
|
|
- (void)reload;
|
|
@end
|
|
@interface RCTRedBoxExtraDataViewController : UIViewController <UITableViewDelegate, UITableViewDataSource>
|
|
@property (nonatomic, weak) id<RCTRedBoxExtraDataActionDelegate> actionDelegate;
|
|
- (void)addExtraData:(NSDictionary *)data forIdentifier:(NSString *)identifier;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTSurfacePresenterStub.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTSurfacePresenterObserver <NSObject>
|
|
@optional
|
|
- (void)willMountComponentsWithRootTag:(NSInteger)rootTag;
|
|
- (void)didMountComponentsWithRootTag:(NSInteger)rootTag;
|
|
@end
|
|
@protocol RCTSurfacePresenterStub <NSObject>
|
|
- (id<RCTSurfaceProtocol>)createFabricSurfaceForModuleName:(NSString *)moduleName
|
|
initialProperties:(NSDictionary *)initialProperties;
|
|
- (nullable UIView *)findComponentViewWithTag_DO_NOT_USE_DEPRECATED:(NSInteger)tag;
|
|
- (void)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag props:(NSDictionary *)props;
|
|
- (void)addObserver:(id<RCTSurfacePresenterObserver>)observer;
|
|
- (void)removeObserver:(id<RCTSurfacePresenterObserver>)observer;
|
|
@end
|
|
@interface RCTBridge (RCTSurfacePresenterStub)
|
|
- (id<RCTSurfacePresenterStub>)surfacePresenter;
|
|
- (void)setSurfacePresenter:(id<RCTSurfacePresenterStub>)presenter;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTSurfacePresenterStub)
|
|
- (id<RCTSurfacePresenterStub>)surfacePresenter;
|
|
- (void)setSurfacePresenter:(id<RCTSurfacePresenterStub>)presenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTUIManager.h}:
|
|
RCT_EXTERN NSString *const RCTUIManagerWillUpdateViewsDueToContentSizeMultiplierChangeNotification;
|
|
@interface RCTUIManager : NSObject <RCTBridgeModule, RCTInvalidating>
|
|
- (void)registerRootViewTag:(NSNumber *)rootTag;
|
|
- (void)registerRootView:(UIView *)rootView;
|
|
- (NSString *)viewNameForReactTag:(NSNumber *)reactTag;
|
|
- (UIView *)viewForReactTag:(NSNumber *)reactTag;
|
|
- (RCTShadowView *)shadowViewForReactTag:(NSNumber *)reactTag;
|
|
- (void)setAvailableSize:(CGSize)availableSize forRootView:(UIView *)rootView;
|
|
- (void)setLocalData:(NSObject *)localData forView:(UIView *)view;
|
|
- (void)setSize:(CGSize)size forView:(UIView *)view;
|
|
- (void)setIntrinsicContentSize:(CGSize)intrinsicContentSize forView:(UIView *)view;
|
|
- (void)setNextLayoutAnimationGroup:(RCTLayoutAnimationGroup *)layoutAnimationGroup;
|
|
- (void)addUIBlock:(RCTViewManagerUIBlock)block;
|
|
- (void)prependUIBlock:(RCTViewManagerUIBlock)block;
|
|
- (void)synchronouslyUpdateViewOnUIThread:(NSNumber *)reactTag
|
|
viewName:(NSString *)viewName
|
|
props:(NSDictionary *)props;
|
|
- (void)rootViewForReactTag:(NSNumber *)reactTag withCompletion:(void (^)(UIView *view))completion;
|
|
- (UIView *)viewForNativeID:(NSString *)nativeID withRootTag:(NSNumber *)rootTag;
|
|
- (void)setNativeID:(NSString *)nativeID forView:(UIView *)view;
|
|
+ (UIView *)JSResponder;
|
|
- (void)setNeedsLayout;
|
|
+ (UIView *)paperViewOrCurrentView:(UIView *)view;
|
|
@property (atomic, retain, readonly) RCTUIManagerObserverCoordinator *observerCoordinator;
|
|
@end
|
|
@interface RCTBridge (RCTUIManager)
|
|
@property (nonatomic, readonly) RCTUIManager *uiManager;
|
|
@end
|
|
@interface RCTBridgeProxy (RCTUIManager)
|
|
@property (nonatomic, readonly) RCTUIManager *uiManager;
|
|
@end
|
|
@interface RCTComposedViewRegistry : NSMutableDictionary
|
|
- (instancetype)initWithUIManager:(RCTUIManager *)uiManager andRegistry:(NSDictionary<NSNumber *, UIView *> *)registry;
|
|
@end
|
|
@protocol RCTRendererInteropLayerAdapting
|
|
- (UIView *)paperView;
|
|
@end
|
|
RCT_EXTERN NSMutableDictionary<NSString *, id> *RCTModuleConstantsForDestructuredComponent(
|
|
NSMutableDictionary<NSString *, NSDictionary *> *directEvents,
|
|
NSMutableDictionary<NSString *, NSDictionary *> *bubblingEvents,
|
|
Class managerClass,
|
|
NSString *name,
|
|
NSDictionary<NSString *, id> *viewConfig);
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTUIManagerObserverCoordinator.h}:
|
|
typedef dispatch_block_t RCTUIManagerMountingBlock;
|
|
@protocol RCTUIManagerObserver <NSObject>
|
|
@optional
|
|
- (void)uiManagerWillPerformLayout:(RCTUIManager *)manager;
|
|
- (void)uiManagerDidPerformLayout:(RCTUIManager *)manager;
|
|
- (void)uiManagerWillPerformMounting:(RCTUIManager *)manager;
|
|
- (BOOL)uiManager:(RCTUIManager *)manager performMountingWithBlock:(RCTUIManagerMountingBlock)block;
|
|
- (void)uiManagerDidPerformMounting:(RCTUIManager *)manager;
|
|
@end
|
|
@interface RCTUIManagerObserverCoordinator : NSObject <RCTUIManagerObserver>
|
|
- (void)addObserver:(id<RCTUIManagerObserver>)observer;
|
|
- (void)removeObserver:(id<RCTUIManagerObserver>)observer;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Modules/RCTUIManagerUtils.h}:
|
|
RCT_EXTERN dispatch_queue_t RCTGetUIManagerQueue(void);
|
|
RCT_EXTERN char *const RCTUIManagerQueueName;
|
|
RCT_EXTERN BOOL RCTIsUIManagerQueue(void);
|
|
RCT_EXTERN BOOL RCTIsPseudoUIManagerQueue(void);
|
|
RCT_EXTERN void RCTExecuteOnUIManagerQueue(dispatch_block_t block);
|
|
RCT_EXTERN void RCTUnsafeExecuteOnUIManagerQueueSync(dispatch_block_t block);
|
|
RCT_EXTERN NSNumber *RCTAllocateRootViewTag(void);
|
|
|
|
/// @src {packages/react-native/React/Profiler/RCTMacros.h}:
|
|
|
|
|
|
/// @src {packages/react-native/React/Profiler/RCTProfile.h}:
|
|
RCT_EXTERN NSString *const RCTProfileDidStartProfiling;
|
|
RCT_EXTERN NSString *const RCTProfileDidEndProfiling;
|
|
RCT_EXTERN const uint64_t RCTProfileTagAlways;
|
|
|
|
/// @src {packages/react-native/React/Runtime/RCTHermesInstanceFactory.h}:
|
|
extern "C" {
|
|
JSRuntimeFactoryRef jsrt_create_hermes_factory(void);
|
|
}
|
|
|
|
/// @src {packages/react-native/React/Views/RCTActivityIndicatorView.h}:
|
|
@interface RCTActivityIndicatorView : UIActivityIndicatorView
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTActivityIndicatorViewManager.h}:
|
|
@interface RCTConvert (UIActivityIndicatorView)
|
|
+ (UIActivityIndicatorViewStyle)UIActivityIndicatorViewStyle:(id)json;
|
|
@end
|
|
@interface RCTActivityIndicatorViewManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTAnimationType.h}:
|
|
typedef NS_ENUM(NSInteger, RCTAnimationType) {
|
|
RCTAnimationTypeSpring = 0,
|
|
RCTAnimationTypeLinear,
|
|
RCTAnimationTypeEaseIn,
|
|
RCTAnimationTypeEaseOut,
|
|
RCTAnimationTypeEaseInEaseOut,
|
|
RCTAnimationTypeKeyboard,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Views/RCTAutoInsetsProtocol.h}:
|
|
@protocol RCTAutoInsetsProtocol
|
|
@property (nonatomic, assign, readwrite) UIEdgeInsets contentInset;
|
|
@property (nonatomic, assign, readwrite) BOOL automaticallyAdjustContentInsets;
|
|
- (void)refreshContentInset;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTBorderCurve.h}:
|
|
typedef NS_ENUM(NSInteger, RCTBorderCurve) {
|
|
RCTBorderCurveContinuous = 0,
|
|
RCTBorderCurveCircular,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Views/RCTBorderDrawing.h}:
|
|
typedef struct {
|
|
CGFloat topLeftHorizontal;
|
|
CGFloat topLeftVertical;
|
|
CGFloat topRightHorizontal;
|
|
CGFloat topRightVertical;
|
|
CGFloat bottomLeftHorizontal;
|
|
CGFloat bottomLeftVertical;
|
|
CGFloat bottomRightHorizontal;
|
|
CGFloat bottomRightVertical;
|
|
} RCTCornerRadii;
|
|
typedef struct {
|
|
CGSize topLeft;
|
|
CGSize topRight;
|
|
CGSize bottomLeft;
|
|
CGSize bottomRight;
|
|
} RCTCornerInsets;
|
|
typedef struct {
|
|
UIColor *top;
|
|
UIColor *left;
|
|
UIColor *bottom;
|
|
UIColor *right;
|
|
} RCTBorderColors;
|
|
RCT_EXTERN CGFloat RCTMaxBorderInset(UIEdgeInsets borderInsets);
|
|
RCT_EXTERN BOOL RCTBorderInsetsAreEqual(UIEdgeInsets borderInsets);
|
|
RCT_EXTERN BOOL RCTCornerRadiiAreEqualAndSymmetrical(RCTCornerRadii cornerRadii);
|
|
RCT_EXTERN BOOL RCTBorderColorsAreEqual(RCTBorderColors borderColors);
|
|
RCT_EXTERN RCTCornerInsets RCTGetCornerInsets(RCTCornerRadii cornerRadii, UIEdgeInsets borderInsets);
|
|
RCT_EXTERN CGPathRef RCTPathCreateWithRoundedRect(
|
|
CGRect bounds,
|
|
RCTCornerInsets cornerInsets,
|
|
const CGAffineTransform *transform,
|
|
const BOOL inverted);
|
|
RCT_EXTERN UIImage *RCTGetBorderImage(
|
|
RCTBorderStyle borderStyle,
|
|
CGSize viewSize,
|
|
RCTCornerRadii cornerRadii,
|
|
UIEdgeInsets borderInsets,
|
|
RCTBorderColors borderColors,
|
|
UIColor *backgroundColor,
|
|
BOOL drawToEdge);
|
|
|
|
/// @src {packages/react-native/React/Views/RCTBorderStyle.h}:
|
|
typedef NS_ENUM(NSInteger, RCTBorderStyle) {
|
|
RCTBorderStyleUnset = 0,
|
|
RCTBorderStyleSolid,
|
|
RCTBorderStyleDotted,
|
|
RCTBorderStyleDashed,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Views/RCTComponent.h}:
|
|
typedef void (^RCTDirectEventBlock)(NSDictionary *body);
|
|
typedef void (^RCTBubblingEventBlock)(NSDictionary *body);
|
|
typedef void (^RCTCapturingEventBlock)(NSDictionary *body);
|
|
@protocol RCTComponent <NSObject>
|
|
@property (nonatomic, copy) NSNumber *reactTag;
|
|
@property (nonatomic, copy) NSNumber *rootTag;
|
|
- (void)insertReactSubview:(id<RCTComponent>)subview atIndex:(NSInteger)atIndex;
|
|
- (void)removeReactSubview:(id<RCTComponent>)subview;
|
|
- (NSArray<id<RCTComponent>> *)reactSubviews;
|
|
- (id<RCTComponent>)reactSuperview;
|
|
- (NSNumber *)reactTagAtPoint:(CGPoint)point;
|
|
- (BOOL)isReactRootView;
|
|
- (void)didSetProps:(NSArray<NSString *> *)changedProps;
|
|
- (void)didUpdateReactSubviews;
|
|
@end
|
|
static inline BOOL RCTIsReactRootView(NSNumber *reactTag)
|
|
{
|
|
return reactTag.integerValue % 10 == 1;
|
|
}
|
|
|
|
/// @src {packages/react-native/React/Views/RCTComponentData.h}:
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTComponentData : NSObject
|
|
@property (nonatomic, readonly) Class managerClass;
|
|
@property (nonatomic, copy, readonly) NSString *name;
|
|
@property (nonatomic, weak, readonly) RCTViewManager *manager;
|
|
@property (nonatomic, strong, readonly) RCTViewManager *bridgelessViewManager;
|
|
- (instancetype)initWithManagerClass:(Class)managerClass
|
|
bridge:(RCTBridge *)bridge
|
|
eventDispatcher:(id<RCTEventDispatcherProtocol>)eventDispatcher NS_DESIGNATED_INITIALIZER;
|
|
- (UIView *)createViewWithTag:(nullable NSNumber *)tag rootTag:(nullable NSNumber *)rootTag;
|
|
- (RCTShadowView *)createShadowViewWithTag:(NSNumber *)tag;
|
|
- (void)setProps:(NSDictionary<NSString *, id> *)props forView:(id<RCTComponent>)view;
|
|
- (void)setProps:(NSDictionary<NSString *, id> *)props forShadowView:(RCTShadowView *)shadowView;
|
|
@property (nonatomic, copy, nullable) void (^eventInterceptor)
|
|
(NSString *eventName, NSDictionary *event, NSNumber *reactTag);
|
|
+ (NSDictionary<NSString *, id> *)viewConfigForViewMangerClass:(Class)managerClass;
|
|
- (NSDictionary<NSString *, id> *)viewConfig;
|
|
@end
|
|
RCT_EXTERN NSString *RCTViewManagerModuleNameForClass(Class managerClass);
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/RCTConvert+CoreLocation.h}:
|
|
@interface RCTConvert (CoreLocation)
|
|
+ (CLLocationDegrees)CLLocationDegrees:(id)json;
|
|
+ (CLLocationDistance)CLLocationDistance:(id)json;
|
|
+ (CLLocationCoordinate2D)CLLocationCoordinate2D:(id)json;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTConvert+Transform.h}:
|
|
/// @dep {packages/react-native/React/Views/UIView+React.h}
|
|
|
|
@interface RCTConvert (Transform)
|
|
+ (CATransform3D)CATransform3D:(id)json;
|
|
+ (RCTTransformOrigin)RCTTransformOrigin:(id)json;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTCursor.h}:
|
|
typedef NS_ENUM(NSInteger, RCTCursor) {
|
|
RCTCursorAuto,
|
|
RCTCursorPointer,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Views/RCTDebuggingOverlay.h}:
|
|
@interface TraceUpdateTuple : NSObject
|
|
@property (nonatomic, strong, readonly) UIView *view;
|
|
@property (nonatomic, copy, readonly) dispatch_block_t cleanupBlock;
|
|
- (instancetype)initWithView:(UIView *)view cleanupBlock:(dispatch_block_t)cleanupBlock;
|
|
@end
|
|
@interface RCTDebuggingOverlay : RCTView
|
|
- (void)highlightTraceUpdates:(NSArray *)updates;
|
|
- (void)highlightElements:(NSArray *)rectangles;
|
|
- (void)clearElementsHighlights;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTDebuggingOverlayManager.h}:
|
|
@interface RCTDebuggingOverlayManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTFont.h}:
|
|
typedef UIFont * (^RCTFontHandler)(CGFloat fontSize, NSString *fontWeightDescription);
|
|
typedef CGFloat RCTFontWeight;
|
|
RCT_EXTERN void RCTSetDefaultFontHandler(RCTFontHandler handler);
|
|
RCT_EXTERN BOOL RCTHasFontHandlerSet(void);
|
|
RCT_EXTERN RCTFontWeight RCTGetFontWeight(UIFont *font);
|
|
@interface RCTFont : NSObject
|
|
+ (UIFont *)updateFont:(UIFont *)font
|
|
withFamily:(NSString *)family
|
|
size:(NSNumber *)size
|
|
weight:(NSString *)weight
|
|
style:(NSString *)style
|
|
variant:(NSArray<NSString *> *)variant
|
|
scaleMultiplier:(CGFloat)scaleMultiplier;
|
|
+ (UIFont *)updateFont:(UIFont *)font withFamily:(NSString *)family;
|
|
+ (UIFont *)updateFont:(UIFont *)font withSize:(NSNumber *)size;
|
|
+ (UIFont *)updateFont:(UIFont *)font withWeight:(NSString *)weight;
|
|
+ (UIFont *)updateFont:(UIFont *)font withStyle:(NSString *)style;
|
|
@end
|
|
@interface RCTConvert (RCTFont)
|
|
+ (UIFont *)UIFont:(id)json;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTLayout.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_ENUM(NSInteger, RCTDisplayType) {
|
|
RCTDisplayTypeNone,
|
|
RCTDisplayTypeFlex,
|
|
RCTDisplayTypeInline,
|
|
};
|
|
struct RCTLayoutMetrics {
|
|
CGRect frame;
|
|
CGRect contentFrame;
|
|
UIEdgeInsets borderWidth;
|
|
RCTDisplayType displayType;
|
|
UIUserInterfaceLayoutDirection layoutDirection;
|
|
};
|
|
typedef struct CG_BOXABLE RCTLayoutMetrics RCTLayoutMetrics;
|
|
struct RCTLayoutContext {
|
|
CGPoint absolutePosition;
|
|
__unsafe_unretained NSPointerArray *_Nonnull affectedShadowViews;
|
|
__unsafe_unretained NSHashTable<NSString *> *_Nonnull other;
|
|
};
|
|
typedef struct CG_BOXABLE RCTLayoutContext RCTLayoutContext;
|
|
static inline BOOL RCTLayoutMetricsEqualToLayoutMetrics(RCTLayoutMetrics a, RCTLayoutMetrics b)
|
|
{
|
|
return CGRectEqualToRect(a.frame, b.frame) && CGRectEqualToRect(a.contentFrame, b.contentFrame) &&
|
|
UIEdgeInsetsEqualToEdgeInsets(a.borderWidth, b.borderWidth) && a.displayType == b.displayType &&
|
|
a.layoutDirection == b.layoutDirection;
|
|
}
|
|
RCT_EXTERN RCTLayoutMetrics RCTLayoutMetricsFromYogaNode(YGNodeRef yogaNode);
|
|
RCT_EXTERN float RCTYogaFloatFromCoreGraphicsFloat(CGFloat value);
|
|
RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaFloat(float value);
|
|
RCT_EXTERN CGFloat RCTCoreGraphicsFloatFromYogaValue(YGValue value, CGFloat baseFloatValue);
|
|
RCT_EXTERN YGDirection RCTYogaLayoutDirectionFromUIKitLayoutDirection(UIUserInterfaceLayoutDirection direction);
|
|
RCT_EXTERN UIUserInterfaceLayoutDirection RCTUIKitLayoutDirectionFromYogaLayoutDirection(YGDirection direction);
|
|
RCT_EXTERN YGDisplay RCTYogaDisplayTypeFromReactDisplayType(RCTDisplayType displayType);
|
|
RCT_EXTERN RCTDisplayType RCTReactDisplayTypeFromYogaDisplayType(YGDisplay displayType);
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/RCTModalHostView.h}:
|
|
|
|
@interface RCTModalHostView : UIView <RCTInvalidating, UIAdaptivePresentationControllerDelegate>
|
|
@property (nonatomic, copy) NSString *animationType;
|
|
@property (nonatomic, assign) UIModalPresentationStyle presentationStyle;
|
|
@property (nonatomic, assign, getter=isTransparent) BOOL transparent;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onShow;
|
|
@property (nonatomic, assign) BOOL visible;
|
|
@property (nonatomic, assign) BOOL allowSwipeDismissal;
|
|
@property (nonatomic, assign) BOOL statusBarTranslucent;
|
|
@property (nonatomic, assign) BOOL hardwareAccelerated;
|
|
@property (nonatomic, assign) BOOL animated;
|
|
@property (nonatomic, copy) NSNumber *identifier;
|
|
@property (nonatomic, weak) id<RCTModalHostViewInteractor> delegate;
|
|
@property (nonatomic, copy) NSArray<NSString *> *supportedOrientations;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onOrientationChange;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onDismiss;
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
@protocol RCTModalHostViewInteractor <NSObject>
|
|
- (void)presentModalHostView:(RCTModalHostView *)modalHostView
|
|
withViewController:(RCTModalHostViewController *)viewController
|
|
animated:(BOOL)animated;
|
|
- (void)dismissModalHostView:(RCTModalHostView *)modalHostView
|
|
withViewController:(RCTModalHostViewController *)viewController
|
|
animated:(BOOL)animated;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTModalHostViewController.h}:
|
|
@interface RCTModalHostViewController : UIViewController
|
|
@property (nonatomic, copy) void (^boundsDidChangeBlock)(CGRect newBounds);
|
|
@property (nonatomic, assign) UIInterfaceOrientationMask supportedInterfaceOrientations;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTModalHostViewManager.h}:
|
|
typedef void (^RCTModalViewInteractionBlock)(
|
|
UIViewController *reactViewController,
|
|
UIViewController *viewController,
|
|
BOOL animated,
|
|
dispatch_block_t completionBlock);
|
|
@interface RCTModalHostViewManager : RCTViewManager <RCTInvalidating>
|
|
@property (nonatomic, strong) RCTModalViewInteractionBlock presentationBlock;
|
|
@property (nonatomic, strong) RCTModalViewInteractionBlock dismissalBlock;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTModalManager.h}:
|
|
@interface RCTModalManager : RCTEventEmitter <RCTBridgeModule>
|
|
- (void)modalDismissed:(NSNumber *)modalID;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTPointerEvents.h}:
|
|
typedef NS_ENUM(NSInteger, RCTPointerEvents) {
|
|
RCTPointerEventsUnspecified = 0,
|
|
RCTPointerEventsNone,
|
|
RCTPointerEventsBoxNone,
|
|
RCTPointerEventsBoxOnly,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Views/RCTRootShadowView.h}:
|
|
@interface RCTRootShadowView : RCTShadowView
|
|
@property (nonatomic, assign) CGSize minimumSize;
|
|
@property (nonatomic, assign) CGSize availableSize;
|
|
@property (nonatomic, assign) YGDirection baseDirection;
|
|
- (void)layoutWithAffectedShadowViews:(NSPointerArray *)affectedShadowViews;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTShadowView+Internal.h}:
|
|
|
|
@interface RCTShadowView (Internal)
|
|
@property (nonatomic, weak, readwrite) RCTRootShadowView *rootView;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTShadowView+Layout.h}:
|
|
@interface RCTShadowView (Layout)
|
|
@property (nonatomic, readonly) UIEdgeInsets paddingAsInsets;
|
|
@property (nonatomic, readonly) UIEdgeInsets borderAsInsets;
|
|
@property (nonatomic, readonly) UIEdgeInsets compoundInsets;
|
|
@property (nonatomic, readonly) CGSize availableSize;
|
|
@property (nonatomic, readonly) CGRect contentFrame;
|
|
- (void)dirtyLayout;
|
|
- (void)clearLayout;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTShadowView.h}:
|
|
|
|
typedef void (^RCTApplierBlock)(NSDictionary<NSNumber *, UIView *> *viewRegistry);
|
|
@interface RCTShadowView : NSObject <RCTComponent>
|
|
+ (YGConfigRef)yogaConfig;
|
|
- (NSArray<RCTShadowView *> *)reactSubviews NS_REQUIRES_SUPER;
|
|
- (RCTShadowView *)reactSuperview NS_REQUIRES_SUPER;
|
|
- (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex NS_REQUIRES_SUPER;
|
|
- (void)removeReactSubview:(RCTShadowView *)subview NS_REQUIRES_SUPER;
|
|
@property (nonatomic, weak, readonly) RCTRootShadowView *rootView;
|
|
@property (nonatomic, weak, readonly) RCTShadowView *superview;
|
|
@property (nonatomic, assign, readonly) YGNodeRef yogaNode;
|
|
@property (nonatomic, copy) NSString *viewName;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onLayout;
|
|
@property (nonatomic, assign) RCTLayoutMetrics layoutMetrics;
|
|
- (void)setLocalData:(NSObject *)localData;
|
|
@property (nonatomic, assign, getter=isNewView) BOOL newView;
|
|
@property (nonatomic, assign) YGValue top;
|
|
@property (nonatomic, assign) YGValue left;
|
|
@property (nonatomic, assign) YGValue bottom;
|
|
@property (nonatomic, assign) YGValue right;
|
|
@property (nonatomic, assign) YGValue start;
|
|
@property (nonatomic, assign) YGValue end;
|
|
@property (nonatomic, assign) YGValue width;
|
|
@property (nonatomic, assign) YGValue height;
|
|
@property (nonatomic, assign) YGValue minWidth;
|
|
@property (nonatomic, assign) YGValue maxWidth;
|
|
@property (nonatomic, assign) YGValue minHeight;
|
|
@property (nonatomic, assign) YGValue maxHeight;
|
|
@property (nonatomic, assign) CGSize size;
|
|
@property (nonatomic, assign) float borderWidth;
|
|
@property (nonatomic, assign) float borderTopWidth;
|
|
@property (nonatomic, assign) float borderLeftWidth;
|
|
@property (nonatomic, assign) float borderBottomWidth;
|
|
@property (nonatomic, assign) float borderRightWidth;
|
|
@property (nonatomic, assign) float borderStartWidth;
|
|
@property (nonatomic, assign) float borderEndWidth;
|
|
@property (nonatomic, assign) YGValue margin;
|
|
@property (nonatomic, assign) YGValue marginVertical;
|
|
@property (nonatomic, assign) YGValue marginHorizontal;
|
|
@property (nonatomic, assign) YGValue marginTop;
|
|
@property (nonatomic, assign) YGValue marginLeft;
|
|
@property (nonatomic, assign) YGValue marginBottom;
|
|
@property (nonatomic, assign) YGValue marginRight;
|
|
@property (nonatomic, assign) YGValue marginStart;
|
|
@property (nonatomic, assign) YGValue marginEnd;
|
|
@property (nonatomic, assign) YGValue padding;
|
|
@property (nonatomic, assign) YGValue paddingVertical;
|
|
@property (nonatomic, assign) YGValue paddingHorizontal;
|
|
@property (nonatomic, assign) YGValue paddingTop;
|
|
@property (nonatomic, assign) YGValue paddingLeft;
|
|
@property (nonatomic, assign) YGValue paddingBottom;
|
|
@property (nonatomic, assign) YGValue paddingRight;
|
|
@property (nonatomic, assign) YGValue paddingStart;
|
|
@property (nonatomic, assign) YGValue paddingEnd;
|
|
@property (nonatomic, assign) YGFlexDirection flexDirection;
|
|
@property (nonatomic, assign) YGJustify justifyContent;
|
|
@property (nonatomic, assign) YGAlign alignSelf;
|
|
@property (nonatomic, assign) YGAlign alignItems;
|
|
@property (nonatomic, assign) YGAlign alignContent;
|
|
@property (nonatomic, assign) YGPositionType position;
|
|
@property (nonatomic, assign) YGWrap flexWrap;
|
|
@property (nonatomic, assign) YGDisplay display;
|
|
@property (nonatomic, assign) float flex;
|
|
@property (nonatomic, assign) float flexGrow;
|
|
@property (nonatomic, assign) YGValue rowGap;
|
|
@property (nonatomic, assign) YGValue columnGap;
|
|
@property (nonatomic, assign) YGValue gap;
|
|
@property (nonatomic, assign) float flexShrink;
|
|
@property (nonatomic, assign) YGValue flexBasis;
|
|
@property (nonatomic, assign) float aspectRatio;
|
|
@property (nonatomic, assign) YGDirection direction;
|
|
@property (nonatomic, assign) YGOverflow overflow;
|
|
@property (nonatomic, assign) CGSize intrinsicContentSize;
|
|
- (void)layoutWithMinimumSize:(CGSize)minimumSize
|
|
maximumSize:(CGSize)maximumSize
|
|
layoutDirection:(UIUserInterfaceLayoutDirection)layoutDirection
|
|
layoutContext:(RCTLayoutContext)layoutContext;
|
|
- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics layoutContext:(RCTLayoutContext)layoutContext;
|
|
- (void)layoutSubviewsWithContext:(RCTLayoutContext)layoutContext;
|
|
- (CGSize)sizeThatFitsMinimumSize:(CGSize)minimumSize maximumSize:(CGSize)maximumSize;
|
|
- (BOOL)canHaveSubviews;
|
|
- (BOOL)isYogaLeafNode;
|
|
- (void)didUpdateReactSubviews NS_REQUIRES_SUPER;
|
|
- (void)didSetProps:(NSArray<NSString *> *)changedProps NS_REQUIRES_SUPER;
|
|
- (CGRect)measureLayoutRelativeToAncestor:(RCTShadowView *)ancestor;
|
|
- (BOOL)viewIsDescendantOf:(RCTShadowView *)ancestor;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTSwitch.h}:
|
|
@interface RCTSwitch : UISwitch
|
|
@property (nonatomic, assign) BOOL wasOn;
|
|
@property (nonatomic, copy) RCTBubblingEventBlock onChange;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTSwitchManager.h}:
|
|
@interface RCTSwitchManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTTextDecorationLineType.h}:
|
|
typedef NS_ENUM(NSInteger, RCTTextDecorationLineType) {
|
|
RCTTextDecorationLineTypeNone = 0,
|
|
RCTTextDecorationLineTypeUnderline,
|
|
RCTTextDecorationLineTypeStrikethrough,
|
|
RCTTextDecorationLineTypeUnderlineStrikethrough,
|
|
};
|
|
|
|
/// @src {packages/react-native/React/Views/RCTView.h}:
|
|
extern const UIAccessibilityTraits SwitchAccessibilityTrait;
|
|
@interface RCTView : UIView
|
|
@property (nonatomic, copy) RCTDirectEventBlock onAccessibilityAction;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onAccessibilityTap;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onMagicTap;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onAccessibilityEscape;
|
|
@property (nonatomic, assign) RCTPointerEvents pointerEvents;
|
|
+ (void)autoAdjustInsetsForView:(UIView<RCTAutoInsetsProtocol> *)parentView
|
|
withScrollView:(UIScrollView *)scrollView
|
|
updateOffset:(BOOL)updateOffset;
|
|
@property (nonatomic, assign) UIUserInterfaceLayoutDirection reactLayoutDirection;
|
|
@property (nonatomic, assign) BOOL removeClippedSubviews;
|
|
- (void)updateClippedSubviews;
|
|
@property (nonatomic, assign) CGFloat borderRadius;
|
|
@property (nonatomic, assign) CGFloat borderTopLeftRadius;
|
|
@property (nonatomic, assign) CGFloat borderTopRightRadius;
|
|
@property (nonatomic, assign) CGFloat borderTopStartRadius;
|
|
@property (nonatomic, assign) CGFloat borderTopEndRadius;
|
|
@property (nonatomic, assign) CGFloat borderBottomLeftRadius;
|
|
@property (nonatomic, assign) CGFloat borderBottomRightRadius;
|
|
@property (nonatomic, assign) CGFloat borderBottomStartRadius;
|
|
@property (nonatomic, assign) CGFloat borderBottomEndRadius;
|
|
@property (nonatomic, assign) CGFloat borderEndEndRadius;
|
|
@property (nonatomic, assign) CGFloat borderEndStartRadius;
|
|
@property (nonatomic, assign) CGFloat borderStartEndRadius;
|
|
@property (nonatomic, assign) CGFloat borderStartStartRadius;
|
|
@property (nonatomic, strong) UIColor *borderTopColor;
|
|
@property (nonatomic, strong) UIColor *borderRightColor;
|
|
@property (nonatomic, strong) UIColor *borderBottomColor;
|
|
@property (nonatomic, strong) UIColor *borderLeftColor;
|
|
@property (nonatomic, strong) UIColor *borderStartColor;
|
|
@property (nonatomic, strong) UIColor *borderEndColor;
|
|
@property (nonatomic, strong) UIColor *borderColor;
|
|
@property (nonatomic, strong) UIColor *borderBlockColor;
|
|
@property (nonatomic, strong) UIColor *borderBlockEndColor;
|
|
@property (nonatomic, strong) UIColor *borderBlockStartColor;
|
|
@property (nonatomic, assign) CGFloat borderTopWidth;
|
|
@property (nonatomic, assign) CGFloat borderRightWidth;
|
|
@property (nonatomic, assign) CGFloat borderBottomWidth;
|
|
@property (nonatomic, assign) CGFloat borderLeftWidth;
|
|
@property (nonatomic, assign) CGFloat borderStartWidth;
|
|
@property (nonatomic, assign) CGFloat borderEndWidth;
|
|
@property (nonatomic, assign) CGFloat borderWidth;
|
|
@property (nonatomic, assign) CGFloat borderBlockWidth;
|
|
@property (nonatomic, assign) CGFloat borderBlockEndWidth;
|
|
@property (nonatomic, assign) CGFloat borderBlockStartWidth;
|
|
@property (nonatomic, assign) RCTBorderCurve borderCurve;
|
|
@property (nonatomic, assign) RCTBorderStyle borderStyle;
|
|
@property (nonatomic, assign) UIEdgeInsets hitTestEdgeInsets;
|
|
@property (nonatomic, assign) RCTCursor cursor;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onClick;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onPointerCancel;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onPointerDown;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onPointerMove;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onPointerUp;
|
|
@property (nonatomic, assign) RCTCapturingEventBlock onPointerEnter;
|
|
@property (nonatomic, assign) RCTCapturingEventBlock onPointerLeave;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onPointerOver;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onPointerOut;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onGotPointerCapture;
|
|
@property (nonatomic, assign) RCTBubblingEventBlock onLostPointerCapture;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTViewManager.h}:
|
|
|
|
typedef void (^RCTViewManagerUIBlock)(RCTUIManager *uiManager, NSDictionary<NSNumber *, UIView *> *viewRegistry);
|
|
@interface RCTViewManager : NSObject <RCTBridgeModule>
|
|
@property (nonatomic, weak) RCTBridge *bridge;
|
|
- (UIView *)view;
|
|
- (RCTShadowView *)shadowView;
|
|
- (NSArray<NSString *> *)customBubblingEventTypes __deprecated_msg("Use RCTBubblingEventBlock props instead.");
|
|
CGFloat RCTJSONParseOnlyNumber(id json);
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RCTViewUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN_C_BEGIN
|
|
UIEdgeInsets RCTContentInsets(UIView *view);
|
|
RCT_EXTERN_C_END
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/RCTWrapperViewController.h}:
|
|
|
|
@interface RCTWrapperViewController : UIViewController
|
|
- (instancetype)initWithContentView:(UIView *)contentView NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RefreshControl/RCTRefreshControl.h}:
|
|
@interface RCTRefreshControl : UIRefreshControl <RCTCustomRefreshControlProtocol>
|
|
@property (nonatomic, copy) NSString *title;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
|
|
@property (nonatomic, weak) UIScrollView *scrollView;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RefreshControl/RCTRefreshControlManager.h}:
|
|
@interface RCTRefreshControlManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/RefreshControl/RCTRefreshableProtocol.h}:
|
|
@protocol RCTRefreshableProtocol
|
|
- (void)setRefreshing:(BOOL)refreshing;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/SafeAreaView/RCTSafeAreaShadowView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSafeAreaShadowView : RCTShadowView
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/SafeAreaView/RCTSafeAreaView.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSafeAreaView : RCTView
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/SafeAreaView/RCTSafeAreaViewLocalData.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSafeAreaViewLocalData : NSObject
|
|
- (instancetype)initWithInsets:(UIEdgeInsets)insets;
|
|
@property (atomic, readonly) UIEdgeInsets insets;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/SafeAreaView/RCTSafeAreaViewManager.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSafeAreaViewManager : RCTViewManager
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollContentShadowView.h}:
|
|
@interface RCTScrollContentShadowView : RCTShadowView
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollContentView.h}:
|
|
@interface RCTScrollContentView : RCTView
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollContentViewManager.h}:
|
|
@interface RCTScrollContentViewManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollEvent.h}:
|
|
@interface RCTScrollEvent : NSObject <RCTEvent>
|
|
- (instancetype)initWithEventName:(NSString *)eventName
|
|
reactTag:(NSNumber *)reactTag
|
|
scrollViewContentOffset:(CGPoint)scrollViewContentOffset
|
|
scrollViewContentInset:(UIEdgeInsets)scrollViewContentInset
|
|
scrollViewContentSize:(CGSize)scrollViewContentSize
|
|
scrollViewFrame:(CGRect)scrollViewFrame
|
|
scrollViewZoomScale:(CGFloat)scrollViewZoomScale
|
|
userData:(NSDictionary *)userData
|
|
coalescingKey:(uint16_t)coalescingKey NS_DESIGNATED_INITIALIZER;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollView.h}:
|
|
|
|
@interface RCTScrollView : RCTView <UIScrollViewDelegate, RCTScrollableProtocol, RCTAutoInsetsProtocol>
|
|
- (instancetype)initWithEventDispatcher:(id<RCTEventDispatcherProtocol>)eventDispatcher NS_DESIGNATED_INITIALIZER;
|
|
@property (nonatomic, readonly) UIView *contentView;
|
|
@property (nonatomic, readonly) UIScrollView *scrollView;
|
|
@property (nonatomic, assign) UIEdgeInsets contentInset;
|
|
@property (nonatomic, assign) BOOL automaticallyAdjustContentInsets;
|
|
@property (nonatomic, assign) BOOL automaticallyAdjustKeyboardInsets;
|
|
@property (nonatomic, assign) BOOL DEPRECATED_sendUpdatedChildFrames;
|
|
@property (nonatomic, assign) NSTimeInterval scrollEventThrottle;
|
|
@property (nonatomic, assign) BOOL centerContent;
|
|
@property (nonatomic, copy) NSDictionary *maintainVisibleContentPosition;
|
|
@property (nonatomic, assign) BOOL scrollToOverflowEnabled;
|
|
@property (nonatomic, assign) int snapToInterval;
|
|
@property (nonatomic, assign) BOOL disableIntervalMomentum;
|
|
@property (nonatomic, copy) NSArray<NSNumber *> *snapToOffsets;
|
|
@property (nonatomic, assign) BOOL snapToStart;
|
|
@property (nonatomic, assign) BOOL snapToEnd;
|
|
@property (nonatomic, copy) NSString *snapToAlignment;
|
|
@property (nonatomic, assign) BOOL inverted;
|
|
@property (nonatomic, assign) CGRect firstResponderFocus;
|
|
@property (nonatomic, weak) UIView *firstResponderViewOutsideScrollView;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onScrollBeginDrag;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onScroll;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onScrollToTop;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onScrollEndDrag;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onMomentumScrollBegin;
|
|
@property (nonatomic, copy) RCTDirectEventBlock onMomentumScrollEnd;
|
|
@end
|
|
@interface UIView (RCTScrollView)
|
|
- (void)reactUpdateResponderOffsetForScrollView:(RCTScrollView *)scrollView;
|
|
@end
|
|
@interface RCTScrollView (Internal)
|
|
- (void)updateContentSizeIfNeeded;
|
|
@end
|
|
RCT_EXTERN void RCTSendFakeScrollEvent(id<RCTEventDispatcherProtocol> eventDispatcher, NSNumber *reactTag);
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollViewManager.h}:
|
|
@interface RCTConvert (UIScrollView)
|
|
+ (UIScrollViewKeyboardDismissMode)UIScrollViewKeyboardDismissMode:(id)json;
|
|
@end
|
|
@interface RCTScrollViewManager : RCTViewManager
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/ScrollView/RCTScrollableProtocol.h}:
|
|
@protocol RCTScrollableProtocol
|
|
@property (nonatomic, readonly) CGSize contentSize;
|
|
- (void)scrollToOffset:(CGPoint)offset;
|
|
- (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated;
|
|
- (void)scrollToEnd:(BOOL)animated;
|
|
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated;
|
|
- (void)addScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener;
|
|
- (void)removeScrollListener:(NSObject<UIScrollViewDelegate> *)scrollListener;
|
|
@end
|
|
@protocol RCTCustomRefreshControlProtocol
|
|
@property (nonatomic, copy) RCTDirectEventBlock onRefresh;
|
|
@property (nonatomic, readonly, getter=isRefreshing) BOOL refreshing;
|
|
@optional
|
|
@property (nonatomic, weak) UIScrollView *scrollView;
|
|
@end
|
|
__attribute__((deprecated("Use RCTCustomRefreshControlProtocol instead")))
|
|
@protocol RCTCustomRefreshContolProtocol<RCTCustomRefreshControlProtocol>
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/UIView+Private.h}:
|
|
@interface UIView (Private)
|
|
- (void)react_remountAllSubviews;
|
|
- (void)react_updateClippedSubviewsWithClipRect:(CGRect)clipRect relativeToView:(UIView *)clipView;
|
|
- (UIView *)react_findClipView;
|
|
@end
|
|
|
|
/// @src {packages/react-native/React/Views/UIView+React.h}:
|
|
|
|
typedef struct {
|
|
YGValue x;
|
|
YGValue y;
|
|
CGFloat z;
|
|
} RCTTransformOrigin;
|
|
@interface UIView (React) <RCTComponent>
|
|
- (NSArray<UIView *> *)reactSubviews NS_REQUIRES_SUPER;
|
|
- (UIView *)reactSuperview NS_REQUIRES_SUPER;
|
|
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex NS_REQUIRES_SUPER;
|
|
- (void)removeReactSubview:(UIView *)subview NS_REQUIRES_SUPER;
|
|
@property (nonatomic, copy) NSString *nativeID;
|
|
@property (nonatomic, assign) BOOL shouldAccessibilityIgnoresInvertColors;
|
|
@property (nonatomic, assign) UIUserInterfaceLayoutDirection reactLayoutDirection;
|
|
@property (nonatomic, assign) YGDisplay reactDisplay;
|
|
@property (nonatomic, assign) NSInteger reactZIndex;
|
|
- (NSArray<UIView *> *)reactZIndexSortedSubviews;
|
|
- (void)didUpdateReactSubviews;
|
|
- (void)didSetProps:(NSArray<NSString *> *)changedProps;
|
|
- (void)reactSetFrame:(CGRect)frame;
|
|
- (UIViewController *)reactViewController;
|
|
- (void)reactAddControllerToClosestParent:(UIViewController *)controller;
|
|
- (void)reactFocus;
|
|
- (void)reactFocusIfNeeded;
|
|
- (void)reactBlur;
|
|
@property (nonatomic, readonly) UIEdgeInsets reactBorderInsets;
|
|
@property (nonatomic, readonly) UIEdgeInsets reactPaddingInsets;
|
|
@property (nonatomic, readonly) UIEdgeInsets reactCompoundInsets;
|
|
@property (nonatomic, readonly) CGRect reactContentFrame;
|
|
@property (nonatomic, assign) CATransform3D reactTransform;
|
|
@property (nonatomic, assign) RCTTransformOrigin reactTransformOrigin;
|
|
@property (nonatomic, readonly) UIView *reactAccessibilityElement;
|
|
@property (nonatomic, copy) NSString *accessibilityRole;
|
|
@property (nonatomic, copy) NSString *role;
|
|
@property (nonatomic, copy) NSDictionary<NSString *, id> *accessibilityState;
|
|
@property (nonatomic, copy) NSArray<NSDictionary *> *accessibilityActions;
|
|
@property (nonatomic, copy) NSDictionary *accessibilityValueInternal;
|
|
@property (nonatomic, copy) NSString *accessibilityLanguage;
|
|
@property (nonatomic) UIAccessibilityTraits accessibilityRoleTraits;
|
|
@property (nonatomic) UIAccessibilityTraits roleTraits;
|
|
- (NSString *)react_recursiveDescription;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/fbgloginit/fb/glog_init.h}:
|
|
namespace facebook::gloginit {
|
|
void initialize(const char* tag = "ReactNativeJNI");
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/jni-hack/jni.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/jni-hack/real/jni.h}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/jni-hack/real/jni.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/jni-hack/jni.h}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/jni-lib-merge/jni_lib_merge.h}:
|
|
struct pre_merge_jni_library {
|
|
const char* name;
|
|
int (*onload_func)(JNIEnv*, jclass);
|
|
};
|
|
extern "C" {
|
|
JNIEXPORT jint JNICALL JNI_OnLoad_Weak(JavaVM* vm, void* reserved);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/LayoutContext.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h}
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
void registerNatives(
|
|
JNIEnv* env,
|
|
const char* className,
|
|
const JNINativeMethod methods[],
|
|
size_t numMethods);
|
|
jmethodID getStaticMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jmethodID getMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jfieldID getFieldId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* fieldName,
|
|
const char* fieldSignature);
|
|
void callVoidMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jlong callLongMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jfloat callFloatMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
ScopedLocalRef<jobject>
|
|
callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...);
|
|
ScopedGlobalRef<jobject> newGlobalRef(JNIEnv* env, jobject obj);
|
|
ScopedGlobalRef<jthrowable> newGlobalRef(JNIEnv* env, jthrowable obj);
|
|
} // namespace facebook::yoga::vanillajni
|
|
class PtrJNodeMapVanilla {
|
|
std::map<YGNodeConstRef, jsize> ptrsToIdxs_{};
|
|
jobjectArray javaNodes_{};
|
|
|
|
public:
|
|
PtrJNodeMapVanilla() = default;
|
|
PtrJNodeMapVanilla(jlongArray javaNativePointers, jobjectArray javaNodes)
|
|
: javaNodes_{javaNodes} {
|
|
using namespace facebook::yoga::vanillajni;
|
|
JNIEnv* env = getCurrentEnv();
|
|
jsize nativePointersSize = env->GetArrayLength(javaNativePointers);
|
|
std::vector<jlong> nativePointers(static_cast<size_t>(nativePointersSize));
|
|
env->GetLongArrayRegion(
|
|
javaNativePointers, 0, nativePointersSize, nativePointers.data());
|
|
for (jsize i = 0; i < nativePointersSize; ++i) {
|
|
ptrsToIdxs_[(YGNodeConstRef)nativePointers[static_cast<size_t>(i)]] = i;
|
|
}
|
|
}
|
|
facebook::yoga::vanillajni::ScopedLocalRef<jobject> ref(YGNodeConstRef node) {
|
|
using namespace facebook::yoga::vanillajni;
|
|
JNIEnv* env = getCurrentEnv();
|
|
auto idx = ptrsToIdxs_.find(node);
|
|
if (idx == ptrsToIdxs_.end()) {
|
|
return ScopedLocalRef<jobject>(env);
|
|
} else {
|
|
return make_local_ref(
|
|
env, env->GetObjectArrayElement(javaNodes_, idx->second));
|
|
}
|
|
}
|
|
};
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
class YG_EXPORT LayoutContext {
|
|
public:
|
|
struct Provider {
|
|
explicit Provider(PtrJNodeMapVanilla* data);
|
|
~Provider();
|
|
};
|
|
static PtrJNodeMapVanilla* getNodeMap();
|
|
};
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/corefunctions.h}
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
template <typename T>
|
|
class ScopedGlobalRef {
|
|
static_assert(
|
|
std::is_same<T, jclass>() || std::is_same<T, jobject>() ||
|
|
std::is_same<T, jstring>() || std::is_same<T, jthrowable>() ||
|
|
std::is_same<T, jbyteArray>() || std::is_same<T, jintArray>() ||
|
|
std::is_same<T, jshortArray>() || std::is_same<T, jcharArray>() ||
|
|
std::is_same<T, jlongArray>() || std::is_same<T, jfloatArray>() ||
|
|
std::is_same<T, jdoubleArray>() || std::is_same<T, jobjectArray>() ||
|
|
std::is_same<T, jbooleanArray>(),
|
|
"ScopedGlobalRef instantiated for invalid type");
|
|
|
|
public:
|
|
explicit ScopedGlobalRef(T globalRef) : mGlobalRef(globalRef) {}
|
|
explicit ScopedGlobalRef() : mGlobalRef(NULL) {}
|
|
ScopedGlobalRef(ScopedGlobalRef&& s) noexcept : mGlobalRef(s.release()) {}
|
|
ScopedGlobalRef& operator=(ScopedGlobalRef&& s) noexcept {
|
|
reset(s.release());
|
|
return *this;
|
|
}
|
|
~ScopedGlobalRef() {
|
|
reset();
|
|
}
|
|
void reset(T ptr = NULL) {
|
|
if (ptr != mGlobalRef) {
|
|
if (mGlobalRef != NULL) {
|
|
vanillajni::getCurrentEnv()->DeleteGlobalRef(mGlobalRef);
|
|
}
|
|
mGlobalRef = ptr;
|
|
}
|
|
}
|
|
T release() {
|
|
T globalRef = mGlobalRef;
|
|
mGlobalRef = NULL;
|
|
return globalRef;
|
|
}
|
|
T get() const {
|
|
return mGlobalRef;
|
|
}
|
|
operator bool() const {
|
|
return mGlobalRef != NULL;
|
|
}
|
|
ScopedGlobalRef(const ScopedGlobalRef& ref) = delete;
|
|
ScopedGlobalRef& operator=(const ScopedGlobalRef& other) = delete;
|
|
};
|
|
template <typename T>
|
|
ScopedGlobalRef<T> make_global_ref(T globalRef) {
|
|
return ScopedGlobalRef<T>(globalRef);
|
|
}
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h}:
|
|
namespace facebook::yoga::vanillajni {
|
|
template <typename T>
|
|
class ScopedLocalRef {
|
|
static_assert(
|
|
std::is_same<T, jclass>() || std::is_same<T, jobject>() ||
|
|
std::is_same<T, jstring>() || std::is_same<T, jthrowable>() ||
|
|
std::is_same<T, jbyteArray>() || std::is_same<T, jintArray>() ||
|
|
std::is_same<T, jshortArray>() || std::is_same<T, jcharArray>() ||
|
|
std::is_same<T, jlongArray>() || std::is_same<T, jfloatArray>() ||
|
|
std::is_same<T, jdoubleArray>() || std::is_same<T, jobjectArray>() ||
|
|
std::is_same<T, jbooleanArray>(),
|
|
"ScopedLocalRef instantiated for invalid type");
|
|
|
|
public:
|
|
ScopedLocalRef(JNIEnv* env, T localRef) : mEnv(env), mLocalRef(localRef) {}
|
|
explicit ScopedLocalRef(JNIEnv* env) : mEnv(env), mLocalRef(NULL) {}
|
|
ScopedLocalRef(ScopedLocalRef&& s) noexcept
|
|
: mEnv(s.mEnv), mLocalRef(s.release()) {}
|
|
ScopedLocalRef& operator=(ScopedLocalRef&& s) noexcept {
|
|
reset(s.release());
|
|
mEnv = s.mEnv;
|
|
return *this;
|
|
}
|
|
~ScopedLocalRef() {
|
|
reset();
|
|
}
|
|
void reset(T ptr = NULL) {
|
|
if (ptr != mLocalRef) {
|
|
if (mLocalRef != NULL) {
|
|
mEnv->DeleteLocalRef(mLocalRef);
|
|
}
|
|
mLocalRef = ptr;
|
|
}
|
|
}
|
|
T release() {
|
|
T localRef = mLocalRef;
|
|
mLocalRef = NULL;
|
|
return localRef;
|
|
}
|
|
T get() const {
|
|
return mLocalRef;
|
|
}
|
|
operator bool() const {
|
|
return mLocalRef != NULL;
|
|
}
|
|
ScopedLocalRef(const ScopedLocalRef& ref) = delete;
|
|
ScopedLocalRef& operator=(const ScopedLocalRef& other) = delete;
|
|
};
|
|
template <typename T>
|
|
ScopedLocalRef<T> make_local_ref(JNIEnv* env, T localRef) {
|
|
return ScopedLocalRef<T>(env, localRef);
|
|
}
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNI.h}:
|
|
const short int LAYOUT_EDGE_SET_FLAG_INDEX = 0;
|
|
const short int LAYOUT_WIDTH_INDEX = 1;
|
|
const short int LAYOUT_HEIGHT_INDEX = 2;
|
|
const short int LAYOUT_LEFT_INDEX = 3;
|
|
const short int LAYOUT_TOP_INDEX = 4;
|
|
const short int LAYOUT_DIRECTION_INDEX = 5;
|
|
const short int LAYOUT_MARGIN_START_INDEX = 6;
|
|
const short int LAYOUT_PADDING_START_INDEX = 10;
|
|
const short int LAYOUT_BORDER_START_INDEX = 14;
|
|
namespace {
|
|
const int HAS_NEW_LAYOUT = 16;
|
|
union YGNodeContext {
|
|
int32_t edgesSet = 0;
|
|
void* asVoidPtr;
|
|
};
|
|
class YGNodeEdges {
|
|
int32_t edges_;
|
|
|
|
public:
|
|
enum Edge {
|
|
MARGIN = 1,
|
|
PADDING = 2,
|
|
BORDER = 4,
|
|
};
|
|
explicit YGNodeEdges(YGNodeRef node) {
|
|
auto context = YGNodeContext{};
|
|
context.asVoidPtr = YGNodeGetContext(node);
|
|
edges_ = context.edgesSet;
|
|
}
|
|
void setOn(YGNodeRef node) {
|
|
auto context = YGNodeContext{};
|
|
context.edgesSet = edges_;
|
|
YGNodeSetContext(node, context.asVoidPtr);
|
|
}
|
|
bool has(Edge edge) {
|
|
return (edges_ & edge) == edge;
|
|
}
|
|
YGNodeEdges& add(Edge edge) {
|
|
edges_ |= edge;
|
|
return *this;
|
|
}
|
|
int get() {
|
|
return edges_;
|
|
}
|
|
};
|
|
struct YogaValue {
|
|
static constexpr jint NAN_BYTES = 0x7fc00000;
|
|
static jlong asJavaLong(const YGValue& value) {
|
|
uint32_t valueBytes = 0;
|
|
memcpy(&valueBytes, &value.value, sizeof valueBytes);
|
|
return ((jlong)value.unit) << 32 | valueBytes;
|
|
}
|
|
constexpr static jlong undefinedAsJavaLong() {
|
|
return ((jlong)YGUnitUndefined) << 32 | NAN_BYTES;
|
|
}
|
|
};
|
|
} // namespace
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJNIVanilla.h}:
|
|
namespace YGJNIVanilla {
|
|
void registerNatives(JNIEnv* env);
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YGJTypesVanilla.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h}
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
void registerNatives(
|
|
JNIEnv* env,
|
|
const char* className,
|
|
const JNINativeMethod methods[],
|
|
size_t numMethods);
|
|
jmethodID getStaticMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jmethodID getMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jfieldID getFieldId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* fieldName,
|
|
const char* fieldSignature);
|
|
void callVoidMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jlong callLongMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jfloat callFloatMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
ScopedLocalRef<jobject>
|
|
callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...);
|
|
ScopedGlobalRef<jobject> newGlobalRef(JNIEnv* env, jobject obj);
|
|
ScopedGlobalRef<jthrowable> newGlobalRef(JNIEnv* env, jthrowable obj);
|
|
} // namespace facebook::yoga::vanillajni
|
|
class PtrJNodeMapVanilla {
|
|
std::map<YGNodeConstRef, jsize> ptrsToIdxs_{};
|
|
jobjectArray javaNodes_{};
|
|
|
|
public:
|
|
PtrJNodeMapVanilla() = default;
|
|
PtrJNodeMapVanilla(jlongArray javaNativePointers, jobjectArray javaNodes)
|
|
: javaNodes_{javaNodes} {
|
|
using namespace facebook::yoga::vanillajni;
|
|
JNIEnv* env = getCurrentEnv();
|
|
jsize nativePointersSize = env->GetArrayLength(javaNativePointers);
|
|
std::vector<jlong> nativePointers(static_cast<size_t>(nativePointersSize));
|
|
env->GetLongArrayRegion(
|
|
javaNativePointers, 0, nativePointersSize, nativePointers.data());
|
|
for (jsize i = 0; i < nativePointersSize; ++i) {
|
|
ptrsToIdxs_[(YGNodeConstRef)nativePointers[static_cast<size_t>(i)]] = i;
|
|
}
|
|
}
|
|
facebook::yoga::vanillajni::ScopedLocalRef<jobject> ref(YGNodeConstRef node) {
|
|
using namespace facebook::yoga::vanillajni;
|
|
JNIEnv* env = getCurrentEnv();
|
|
auto idx = ptrsToIdxs_.find(node);
|
|
if (idx == ptrsToIdxs_.end()) {
|
|
return ScopedLocalRef<jobject>(env);
|
|
} else {
|
|
return make_local_ref(
|
|
env, env->GetObjectArrayElement(javaNodes_, idx->second));
|
|
}
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/YogaJniException.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h}
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
void registerNatives(
|
|
JNIEnv* env,
|
|
const char* className,
|
|
const JNINativeMethod methods[],
|
|
size_t numMethods);
|
|
jmethodID getStaticMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jmethodID getMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jfieldID getFieldId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* fieldName,
|
|
const char* fieldSignature);
|
|
void callVoidMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jlong callLongMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jfloat callFloatMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
ScopedLocalRef<jobject>
|
|
callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...);
|
|
ScopedGlobalRef<jobject> newGlobalRef(JNIEnv* env, jobject obj);
|
|
ScopedGlobalRef<jthrowable> newGlobalRef(JNIEnv* env, jthrowable obj);
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
class YogaJniException : public std::exception {
|
|
public:
|
|
YogaJniException();
|
|
~YogaJniException() override;
|
|
explicit YogaJniException(jthrowable throwable);
|
|
YogaJniException(YogaJniException&& rhs) noexcept;
|
|
YogaJniException(const YogaJniException& rhs);
|
|
ScopedLocalRef<jthrowable> getThrowable() const noexcept;
|
|
};
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/common.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedGlobalRef.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/ScopedLocalRef.h}
|
|
|
|
namespace facebook::yoga::vanillajni {
|
|
void registerNatives(
|
|
JNIEnv* env,
|
|
const char* className,
|
|
const JNINativeMethod methods[],
|
|
size_t numMethods);
|
|
jmethodID getStaticMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jmethodID getMethodId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* methodName,
|
|
const char* methodDescriptor);
|
|
jfieldID getFieldId(
|
|
JNIEnv* env,
|
|
jclass clazz,
|
|
const char* fieldName,
|
|
const char* fieldSignature);
|
|
void callVoidMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jlong callLongMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
jfloat callFloatMethod(JNIEnv* env, jobject obj, jmethodID methodId, ...);
|
|
ScopedLocalRef<jobject>
|
|
callStaticObjectMethod(JNIEnv* env, jclass clazz, jmethodID methodId, ...);
|
|
ScopedGlobalRef<jobject> newGlobalRef(JNIEnv* env, jobject obj);
|
|
ScopedGlobalRef<jthrowable> newGlobalRef(JNIEnv* env, jthrowable obj);
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/corefunctions.h}:
|
|
namespace facebook::yoga::vanillajni {
|
|
jint ensureInitialized(JNIEnv** env, JavaVM* vm);
|
|
JNIEnv* getCurrentEnv();
|
|
void logErrorMessageAndDie(const char* message);
|
|
void assertNoPendingJniException(JNIEnv* env);
|
|
void assertNoPendingJniExceptionIf(JNIEnv* env, bool condition);
|
|
} // namespace facebook::yoga::vanillajni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/first-party/yogajni/jni/macros.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnection.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionDelegateImpl.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class JCxxInspectorPackagerConnection
|
|
: public jni::HybridClass<JCxxInspectorPackagerConnection> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/devsupport/CxxInspectorPackagerConnection;";
|
|
static void registerNatives();
|
|
void connect();
|
|
void closeQuietly();
|
|
void sendEventToAllConnections(const std::string& event);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionDelegateImpl.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct JCxxInspectorPackagerConnectionDelegateImpl
|
|
: public jni::JavaClass<JCxxInspectorPackagerConnectionDelegateImpl> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/devsupport/CxxInspectorPackagerConnection$DelegateImpl;";
|
|
std::unique_ptr<InspectorPackagerConnectionDelegate> wrapInUniquePtr();
|
|
std::unique_ptr<IWebSocket> connectWebSocket(
|
|
const std::string& url,
|
|
std::weak_ptr<IWebSocketDelegate> delegate);
|
|
void scheduleCallback(
|
|
std::function<void(void)> callback,
|
|
std::chrono::milliseconds delayMs);
|
|
};
|
|
class JCxxInspectorPackagerConnectionDelegateImpl::RefWrapper
|
|
: public InspectorPackagerConnectionDelegate {
|
|
public:
|
|
explicit RefWrapper(jni::alias_ref<javaobject> jDelegate);
|
|
virtual std::unique_ptr<IWebSocket> connectWebSocket(
|
|
const std::string& url,
|
|
std::weak_ptr<IWebSocketDelegate> delegate) override;
|
|
virtual void scheduleCallback(
|
|
std::function<void(void)> callback,
|
|
std::chrono::milliseconds delayMs) override;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionWebSocket.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class JCxxInspectorPackagerConnectionWebSocket
|
|
: public jni::JavaClass<JCxxInspectorPackagerConnectionWebSocket> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/devsupport/CxxInspectorPackagerConnection$IWebSocket;";
|
|
~JCxxInspectorPackagerConnectionWebSocket();
|
|
std::unique_ptr<jsinspector_modern::IWebSocket> wrapInUniquePtr();
|
|
void send(std::string_view message);
|
|
};
|
|
class JCxxInspectorPackagerConnectionWebSocket::RefWrapper : public IWebSocket {
|
|
public:
|
|
explicit RefWrapper(jni::alias_ref<javaobject> jWebSocket_);
|
|
virtual void send(std::string_view message) override;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JCxxInspectorPackagerConnectionWebSocketDelegate.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class JCxxInspectorPackagerConnectionWebSocketDelegate
|
|
: public jni::HybridClass<
|
|
JCxxInspectorPackagerConnectionWebSocketDelegate> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/devsupport/CxxInspectorPackagerConnection$WebSocketDelegate;";
|
|
void didFailWithError(
|
|
jni::alias_ref<jni::JInteger> posixCode,
|
|
const std::string& error);
|
|
void didReceiveMessage(const std::string& message);
|
|
void didOpen();
|
|
void didClose();
|
|
static void registerNatives();
|
|
JCxxInspectorPackagerConnectionWebSocketDelegate(
|
|
std::weak_ptr<IWebSocketDelegate> cxxDelegate);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/devsupport/JInspectorFlags.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class JInspectorFlags : public jni::JavaClass<JInspectorFlags> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/devsupport/InspectorFlags;";
|
|
static bool getFuseboxEnabled(jni::alias_ref<jclass>);
|
|
static bool getIsProfilingBuild(jni::alias_ref<jclass>);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/AndroidEventBeat.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventBeatManager.h}
|
|
|
|
namespace facebook::react {
|
|
class AndroidEventBeat final : public EventBeat,
|
|
public EventBeatManagerObserver {
|
|
public:
|
|
AndroidEventBeat(
|
|
std::shared_ptr<OwnerBox> ownerBox,
|
|
EventBeatManager* eventBeatManager,
|
|
RuntimeScheduler& runtimeScheduler,
|
|
jni::global_ref<jobject> javaUIManager);
|
|
~AndroidEventBeat() override;
|
|
void tick() const override;
|
|
void request() const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/ComponentFactory.h}:
|
|
namespace facebook::react {
|
|
class ComponentFactory : public jni::HybridClass<ComponentFactory> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/ComponentFactory;";
|
|
static void registerNatives();
|
|
ComponentRegistryFactory buildRegistryFunction;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/CoreComponentsRegistry.h}:
|
|
namespace facebook::react::CoreComponentsRegistry {
|
|
std::shared_ptr<const ComponentDescriptorProviderRegistry>
|
|
sharedProviderRegistry();
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventBeatManager.h}:
|
|
namespace facebook::react {
|
|
class EventBeatManagerObserver {
|
|
public:
|
|
virtual void tick() const = 0;
|
|
virtual ~EventBeatManagerObserver() noexcept = default;
|
|
};
|
|
class EventBeatManager : public jni::HybridClass<EventBeatManager> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/events/EventBeatManager;";
|
|
static void registerNatives();
|
|
void addObserver(const EventBeatManagerObserver& observer) const;
|
|
void removeObserver(const EventBeatManagerObserver& observer) const;
|
|
};
|
|
mutable std::mutex mutex_;
|
|
static void initHybrid(jni::alias_ref<jhybridobject> jobj);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/EventEmitterWrapper.h}:
|
|
namespace facebook::react {
|
|
class EventEmitterWrapper : public jni::HybridClass<EventEmitterWrapper> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/events/EventEmitterWrapper;";
|
|
static void registerNatives();
|
|
EventEmitterWrapper(SharedEventEmitter eventEmitter)
|
|
: eventEmitter(std::move(eventEmitter)) {};
|
|
SharedEventEmitter eventEmitter;
|
|
void dispatchEvent(std::string eventName, NativeMap* params, int category);
|
|
void dispatchEventSynchronously(std::string eventName, NativeMap* params);
|
|
void dispatchUniqueEvent(std::string eventName, NativeMap* params);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricMountingManager.h}:
|
|
namespace facebook::react {
|
|
class FabricMountingManager final {
|
|
public:
|
|
FabricMountingManager(
|
|
jni::global_ref<JFabricUIManager::javaobject>& javaUIManager);
|
|
FabricMountingManager(const FabricMountingManager&) = delete;
|
|
void onSurfaceStart(SurfaceId surfaceId);
|
|
void onSurfaceStop(SurfaceId surfaceId);
|
|
void maybePreallocateShadowNode(const ShadowNode& shadowNode);
|
|
void destroyUnmountedShadowNode(const ShadowNodeFamily& family);
|
|
void drainPreallocateViewsQueue();
|
|
void executeMount(const MountingTransaction& transaction);
|
|
void dispatchCommand(
|
|
const ShadowView& shadowView,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args);
|
|
void sendAccessibilityEvent(
|
|
const ShadowView& shadowView,
|
|
const std::string& eventType);
|
|
void setIsJSResponder(
|
|
const ShadowView& shadowView,
|
|
bool isJSResponder,
|
|
bool blockNativeResponder);
|
|
void onAnimationStarted();
|
|
void onAllAnimationsComplete();
|
|
void synchronouslyUpdateViewOnUIThread(
|
|
Tag viewTag,
|
|
const folly::dynamic& props);
|
|
};
|
|
std::unordered_map<SurfaceId, std::unordered_set<Tag>>
|
|
allocatedViewRegistry_{};
|
|
std::recursive_mutex allocatedViewsMutex_;
|
|
void preallocateShadowView(const ShadowView& shadowView);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/FabricUIManagerBinding.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/FocusOrderingHelper.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/fabric/Binding.h}
|
|
|
|
namespace facebook::react {
|
|
enum class FocusDirection {
|
|
FocusDown = 0,
|
|
FocusUp = 1,
|
|
FocusRight = 2,
|
|
FocusLeft = 3,
|
|
FocusForward = 4,
|
|
FocusBackward = 5,
|
|
};
|
|
class FocusOrderingHelper {
|
|
public:
|
|
static void traverseAndUpdateNextFocusableElement(
|
|
const std::shared_ptr<const ShadowNode>& parentShadowNode,
|
|
const std::shared_ptr<const ShadowNode>& focusedShadowNode,
|
|
const std::shared_ptr<const ShadowNode>& currNode,
|
|
FocusDirection focusDirection,
|
|
const UIManager& uimanager,
|
|
Rect sourceRect,
|
|
std::optional<Rect>& nextRect,
|
|
std::shared_ptr<const ShadowNode>& nextNode);
|
|
static std::shared_ptr<const ShadowNode> findShadowNodeByTagRecursively(
|
|
const std::shared_ptr<const ShadowNode>& parentShadowNode,
|
|
Tag tag);
|
|
static std::optional<FocusDirection> resolveFocusDirection(int direction);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/JFabricUIManager.h}:
|
|
namespace facebook::react {
|
|
class JFabricUIManager : public jni::JavaClass<JFabricUIManager> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/FabricUIManager;";
|
|
FabricUIManagerBinding* getBinding();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/MountItem.h}:
|
|
namespace facebook::react {
|
|
struct JMountItem : public jni::JavaClass<JMountItem> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/mounting/mountitems/MountItem;";
|
|
};
|
|
struct CppMountItem final {
|
|
static CppMountItem CreateMountItem(const ShadowView& shadowView);
|
|
static CppMountItem DeleteMountItem(const ShadowView& shadowView);
|
|
static CppMountItem
|
|
InsertMountItem(Tag parentTag, const ShadowView& shadowView, int index);
|
|
static CppMountItem
|
|
RemoveMountItem(Tag parentTag, const ShadowView& shadowView, int index);
|
|
static CppMountItem UpdatePropsMountItem(
|
|
const ShadowView& oldShadowView,
|
|
const ShadowView& newShadowView);
|
|
static CppMountItem UpdateStateMountItem(const ShadowView& shadowView);
|
|
static CppMountItem UpdateLayoutMountItem(
|
|
const ShadowView& shadowView,
|
|
Tag parentTag);
|
|
static CppMountItem UpdateEventEmitterMountItem(const ShadowView& shadowView);
|
|
static CppMountItem UpdatePaddingMountItem(const ShadowView& shadowView);
|
|
static CppMountItem UpdateOverflowInsetMountItem(
|
|
const ShadowView& shadowView);
|
|
enum Type {
|
|
Undefined = -1,
|
|
Multiple = 1,
|
|
Create = 2,
|
|
Delete = 4,
|
|
Insert = 8,
|
|
Remove = 16,
|
|
UpdateProps = 32,
|
|
UpdateState = 64,
|
|
UpdateLayout = 128,
|
|
UpdateEventEmitter = 256,
|
|
UpdatePadding = 512,
|
|
UpdateOverflowInset = 1024
|
|
};
|
|
Type type = {Create};
|
|
Tag parentTag = -1;
|
|
ShadowView oldChildShadowView = {};
|
|
ShadowView newChildShadowView = {};
|
|
int index = {};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/StateWrapperImpl.h}:
|
|
namespace facebook::react {
|
|
class StateWrapperImpl : public jni::HybridClass<StateWrapperImpl> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/StateWrapperImpl;";
|
|
constexpr static auto StateWrapperImplJavaDescriptor =
|
|
"com/facebook/react/fabric/StateWrapperImpl";
|
|
static void registerNatives();
|
|
jni::local_ref<JReadableMapBuffer::jhybridobject> getStateMapBufferDataImpl();
|
|
jni::local_ref<ReadableNativeMap::jhybridobject> getStateDataImpl();
|
|
jni::local_ref<jobject> getStateDataReferenceImpl();
|
|
void updateStateImpl(NativeMap* map);
|
|
void setState(std::shared_ptr<const State> state);
|
|
std::shared_ptr<const State> getState() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/fabric/SurfaceHandlerBinding.h}:
|
|
namespace facebook::react {
|
|
class SurfaceHandlerBinding : public jni::HybridClass<SurfaceHandlerBinding> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/fabric/SurfaceHandlerBinding;";
|
|
static void registerNatives();
|
|
SurfaceHandlerBinding(SurfaceId surfaceId, const std::string& moduleName);
|
|
void setDisplayMode(jint mode);
|
|
jint getSurfaceId();
|
|
jni::local_ref<jstring> getModuleName();
|
|
jboolean isRunning();
|
|
void setLayoutConstraints(
|
|
jfloat minWidth,
|
|
jfloat maxWidth,
|
|
jfloat minHeight,
|
|
jfloat maxHeight,
|
|
jfloat offsetX,
|
|
jfloat offsetY,
|
|
jboolean doLeftAndRightSwapInRTL,
|
|
jboolean isRTL,
|
|
jfloat pixelDensity,
|
|
jfloat fontScale);
|
|
void setProps(NativeMap* props);
|
|
const SurfaceHandler& getSurfaceHandler();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/featureflags/JReactNativeFeatureFlagsCxxInterop.h}:
|
|
namespace facebook::react {
|
|
class JReactNativeFeatureFlagsCxxInterop
|
|
: public jni::JavaClass<JReactNativeFeatureFlagsCxxInterop> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/internal/featureflags/ReactNativeFeatureFlagsCxxInterop;";
|
|
static bool commonTestFlag(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool cxxNativeAnimatedEnabled(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool cxxNativeAnimatedRemoveJsSync(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool disableMountItemReorderingAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool disableOldAndroidAttachmentMetricsWorkarounds(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool disableTextLayoutManagerCacheAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableAccessibilityOrder(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableAccumulatedUpdatesInRawPropsAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableAndroidTextMeasurementOptimizations(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableBridgelessArchitecture(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableCppPropsIteratorSetter(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableCustomFocusSearchOnClippedElementsAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableDestroyShadowTreeRevisionAsync(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableDoubleMeasurementFixAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableEagerMainQueueModulesOnIOS(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableEagerRootViewAttachment(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableFabricLogs(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableFabricRenderer(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableFixForParentTagDuringReparenting(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableFontScaleChangesUpdatingLayout(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableIOSTextBaselineOffsetPerLine(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableIOSViewClipToPaddingBox(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableImagePrefetchingAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableImmediateUpdateModeForContentOffsetChanges(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableInteropViewManagerClassLookUpOptimizationIOS(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableLayoutAnimationsOnAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableLayoutAnimationsOnIOS(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableMainQueueCoordinatorOnIOS(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableModuleArgumentNSNullConversionIOS(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableNativeCSSParsing(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableNetworkEventReporting(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableNewBackgroundAndBorderDrawables(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enablePreparedTextLayout(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enablePropsUpdateReconciliationAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableResourceTimingAPI(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableViewCulling(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableViewRecycling(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableViewRecyclingForText(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableViewRecyclingForView(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableVirtualViewDebugFeatures(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableVirtualViewRenderState(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool enableVirtualViewWindowFocusDetection(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool fixMappingOfEventPrioritiesBetweenFabricAndReact(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool fuseboxEnabledRelease(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool fuseboxNetworkInspectionEnabled(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool hideOffscreenVirtualViewsOnIOS(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static double preparedTextCacheSize(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool preventShadowTreeCommitExhaustionWithLocking(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool releaseImageDataWhenConsumed(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool skipActivityIdentityAssertionOnHostPause(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool traceTurboModulePromiseRejectionsOnAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool updateRuntimeShadowNodeReferencesOnCommit(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useAlwaysAvailableJSErrorHandling(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useFabricInterop(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useNativeEqualsInNativeReadableArrayAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useNativeTransformHelperAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useNativeViewConfigsInBridgelessMode(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useOptimizedEventBatchingOnAndroid(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useRawPropsJsiValue(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useShadowNodeStateOnClone(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useTurboModuleInterop(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static bool useTurboModules(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static double virtualViewPrerenderRatio(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static void override(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>,
|
|
jni::alias_ref<jobject> provider);
|
|
static void dangerouslyReset(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>);
|
|
static jni::local_ref<jstring> dangerouslyForceOverride(
|
|
facebook::jni::alias_ref<JReactNativeFeatureFlagsCxxInterop>,
|
|
jni::alias_ref<jobject> provider);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/hermes/instrumentation/HermesMemoryDumper.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
namespace jni {
|
|
namespace jni = ::facebook::jni;
|
|
class HermesMemoryDumper : public jni::JavaClass<HermesMemoryDumper> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/hermes/instrumentation/HermesMemoryDumper;";
|
|
bool shouldSaveSnapshot() {
|
|
static auto shouldSaveSnapshotMethod =
|
|
javaClassStatic()->getMethod<jboolean()>("shouldSaveSnapshot");
|
|
return shouldSaveSnapshotMethod(self());
|
|
}
|
|
std::string getInternalStorage() {
|
|
static auto getInternalStorageMethod =
|
|
javaClassStatic()->getMethod<jstring()>("getInternalStorage");
|
|
return getInternalStorageMethod(self())->toStdString();
|
|
}
|
|
std::string getId() {
|
|
static auto getInternalStorageMethod =
|
|
javaClassStatic()->getMethod<jstring()>("getId");
|
|
return getInternalStorageMethod(self())->toStdString();
|
|
}
|
|
void setMetaData(std::string crashId) {
|
|
static auto getIdMethod =
|
|
javaClassStatic()->getMethod<void(std::string)>("setMetaData");
|
|
getIdMethod(self(), crashId);
|
|
}
|
|
};
|
|
} // namespace jni
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/hermes/instrumentation/HermesSamplingProfiler.h}:
|
|
namespace facebook::jsi::jni {
|
|
namespace jni = ::facebook::jni;
|
|
class HermesSamplingProfiler : public jni::JavaClass<HermesSamplingProfiler> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/hermes/instrumentation/HermesSamplingProfiler;";
|
|
static void enable(jni::alias_ref<jclass>);
|
|
static void disable(jni::alias_ref<jclass>);
|
|
static void dumpSampledTraceToFile(
|
|
jni::alias_ref<jclass>,
|
|
std::string filename);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::jsi::jni
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeScheduler.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/JSLoader.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapper.h}
|
|
namespace facebook::react {
|
|
class ModuleHolder : public jni::JavaClass<ModuleHolder> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ModuleHolder;";
|
|
std::string getName() const;
|
|
xplat::module::CxxModule::Provider getProvider(
|
|
const std::string& moduleName) const;
|
|
};
|
|
std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
|
|
std::weak_ptr<Instance> winstance,
|
|
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject>
|
|
javaModules,
|
|
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject>
|
|
cxxModules,
|
|
std::shared_ptr<MessageQueueThread> moduleMessageQueue);
|
|
} // namespace facebook::react
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/ReactInstanceManagerInspectorTarget.h}
|
|
namespace facebook::react {
|
|
struct JInstanceCallback : public jni::JavaClass<JInstanceCallback> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/CatalystInstanceImpl$InstanceCallback;";
|
|
};
|
|
class CatalystInstanceImpl : public jni::HybridClass<CatalystInstanceImpl> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/CatalystInstanceImpl;";
|
|
static jni::local_ref<jhybriddata> initHybrid(jni::alias_ref<jclass>);
|
|
static void registerNatives();
|
|
std::shared_ptr<Instance> getInstance() {
|
|
return instance_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapper.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h}
|
|
|
|
namespace facebook::react {
|
|
class CxxModuleWrapper
|
|
: public jni::HybridClass<CxxModuleWrapper, CxxModuleWrapperBase> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/CxxModuleWrapper;";
|
|
std::string getName() override {
|
|
return module_->getName();
|
|
}
|
|
std::unique_ptr<xplat::module::CxxModule> getModule() override {
|
|
return std::move(module_);
|
|
}
|
|
|
|
protected:
|
|
friend HybridBase;
|
|
explicit CxxModuleWrapper(std::unique_ptr<xplat::module::CxxModule> module)
|
|
: module_(std::move(module)) {}
|
|
std::unique_ptr<xplat::module::CxxModule> module_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h}:
|
|
namespace facebook::react {
|
|
struct JNativeModule : jni::JavaClass<JNativeModule> {
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeModule;";
|
|
};
|
|
class CxxModuleWrapperBase
|
|
: public jni::HybridClass<CxxModuleWrapperBase, JNativeModule> {
|
|
public:
|
|
constexpr static const char* const kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/CxxModuleWrapperBase;";
|
|
static void registerNatives() {
|
|
registerHybrid(
|
|
{makeNativeMethod("getName", CxxModuleWrapperBase::getName)});
|
|
}
|
|
virtual std::string getName() = 0;
|
|
virtual std::unique_ptr<xplat::module::CxxModule> getModule() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxSharedModuleWrapper.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapperBase.h}
|
|
|
|
namespace facebook::react {
|
|
class CxxSharedModuleWrapper : public CxxModuleWrapperBase {
|
|
public:
|
|
std::string getName() override {
|
|
return shared_->getName();
|
|
}
|
|
std::unique_ptr<xplat::module::CxxModule> getModule() override {
|
|
return std::make_unique<xplat::module::SharedProxyCxxModule>(shared_);
|
|
}
|
|
|
|
protected:
|
|
explicit CxxSharedModuleWrapper(
|
|
std::unique_ptr<xplat::module::CxxModule> module)
|
|
: shared_(std::move(module)) {}
|
|
std::shared_ptr<xplat::module::CxxModule> shared_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/InspectorNetworkReporter.h}:
|
|
namespace facebook::react {
|
|
class InspectorNetworkReporter
|
|
: public jni::HybridClass<InspectorNetworkReporter> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/modules/network/InspectorNetworkReporter;";
|
|
static void reportRequestStart(
|
|
jni::alias_ref<jclass>,
|
|
jint requestId,
|
|
jni::alias_ref<jstring> requestUrl,
|
|
jni::alias_ref<jstring> requestMethod,
|
|
jni::alias_ref<jni::JMap<jstring, jstring>> requestHeaders,
|
|
jni::alias_ref<jstring> requestBody,
|
|
jlong encodedDataLength);
|
|
static void reportConnectionTiming(
|
|
jni::alias_ref<jclass>,
|
|
jint requestId,
|
|
jni::alias_ref<jni::JMap<jstring, jstring>> headers);
|
|
static void reportResponseStart(
|
|
jni::alias_ref<jclass>,
|
|
jint requestId,
|
|
jni::alias_ref<jstring> requestUrl,
|
|
jint responseStatus,
|
|
jni::alias_ref<jni::JMap<jstring, jstring>> responseHeaders,
|
|
jlong encodedDataLength);
|
|
static void
|
|
reportDataReceived(jni::alias_ref<jclass>, jint requestId, jint dataLength);
|
|
static void reportResponseEnd(
|
|
jni::alias_ref<jclass>,
|
|
jint requestId,
|
|
jlong encodedDataLength);
|
|
static void maybeStoreResponseBody(
|
|
jni::alias_ref<jclass>,
|
|
jint requestId,
|
|
jni::alias_ref<jstring> body,
|
|
jboolean base64Encoded);
|
|
static void maybeStoreResponseBodyIncremental(
|
|
jni::alias_ref<jclass>,
|
|
jint requestId,
|
|
jni::alias_ref<jstring> data);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/InspectorNetworkRequestListener.h}:
|
|
namespace facebook::react {
|
|
class InspectorNetworkRequestListener
|
|
: public jni::HybridClass<InspectorNetworkRequestListener> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/devsupport/inspector/InspectorNetworkRequestListener;";
|
|
static void registerNatives();
|
|
void onHeaders(
|
|
jint httpStatusCode,
|
|
jni::alias_ref<jni::JMap<jstring, jstring>> headers);
|
|
void onData(jni::alias_ref<jstring> data);
|
|
void onError(jni::alias_ref<jstring> message);
|
|
void onCompletion();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JCallback.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeArray.h}
|
|
|
|
namespace facebook::react {
|
|
struct JCallback : public jni::JavaClass<JCallback> {
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/Callback;";
|
|
};
|
|
class JCxxCallbackImpl : public jni::HybridClass<JCxxCallbackImpl, JCallback> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/CxxCallbackImpl;";
|
|
static void registerNatives() {
|
|
registerHybrid({
|
|
makeNativeMethod("nativeInvoke", JCxxCallbackImpl::invoke),
|
|
});
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JDynamicNative.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeCommon.h}
|
|
namespace facebook::react {
|
|
class NativeArray : public jni::HybridClass<NativeArray> {
|
|
public:
|
|
static auto constexpr* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeArray;";
|
|
jni::local_ref<jstring> toString();
|
|
const folly::dynamic& getArray() const {
|
|
return array_;
|
|
}
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic array_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeArray(Dyn&& array)
|
|
: isConsumed(false), array_(std::forward<Dyn>(array)) {
|
|
assertInternalType();
|
|
}
|
|
void assertInternalType();
|
|
void throwIfConsumed();
|
|
NativeArray(const NativeArray&) = delete;
|
|
NativeArray& operator=(const NativeArray&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeMap;";
|
|
jni::local_ref<jstring> toString();
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic map_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeMap(Dyn&& map)
|
|
: isConsumed(false), map_(std::forward<Dyn>(map)) {}
|
|
void throwIfConsumed();
|
|
NativeMap(const NativeMap&) = delete;
|
|
NativeMap& operator=(const NativeMap&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct ReadableArray : jni::JavaClass<ReadableArray> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableArray;";
|
|
};
|
|
class ReadableNativeArray
|
|
: public jni::HybridClass<ReadableNativeArray, NativeArray> {
|
|
protected:
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit ReadableNativeArray(Dyn&& array)
|
|
: HybridBase(std::forward<Dyn>(array)) {}
|
|
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeArray;";
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
bool equals(jni::alias_ref<ReadableNativeArray::javaobject> other);
|
|
jni::local_ref<jni::JArrayClass<jobject>> importArray();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypeArray();
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
struct ReadableMap : jni::JavaClass<ReadableMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableMap;";
|
|
};
|
|
void addDynamicToJArray(
|
|
jni::local_ref<jni::JArrayClass<jobject>> jarray,
|
|
jint index,
|
|
const folly::dynamic& dyn);
|
|
struct ReadableNativeMap : jni::HybridClass<ReadableNativeMap, NativeMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeMap;";
|
|
jni::local_ref<jni::JArrayClass<jstring>> importKeys();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importValues();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypes();
|
|
std::optional<folly::dynamic> keys_;
|
|
static jni::local_ref<jhybridobject> createWithContents(folly::dynamic&& map);
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
using HybridBase::HybridBase;
|
|
friend HybridBase;
|
|
friend
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
struct JDynamic : public jni::JavaClass<JDynamic> {
|
|
constexpr static auto kJavaDescriptor = "Lcom/facebook/react/bridge/Dynamic;";
|
|
};
|
|
class JDynamicNative : public jni::HybridClass<JDynamicNative, JDynamic> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/DynamicNative;";
|
|
JDynamicNative(folly::dynamic payload) : payload_(std::move(payload)) {}
|
|
static void registerNatives() {
|
|
javaClassStatic()->registerNatives(
|
|
{makeNativeMethod("isNullNative", JDynamicNative::isNullNative),
|
|
makeNativeMethod("getTypeNative", JDynamicNative::getTypeNative),
|
|
makeNativeMethod("asDouble", JDynamicNative::asDouble),
|
|
makeNativeMethod("asBoolean", JDynamicNative::asBoolean),
|
|
makeNativeMethod("asString", JDynamicNative::asString),
|
|
makeNativeMethod("asArray", JDynamicNative::asArray),
|
|
makeNativeMethod("asMap", JDynamicNative::asMap)});
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JExecutor.h}:
|
|
namespace facebook::react {
|
|
struct JExecutor : public jni::JavaClass<JExecutor> {
|
|
constexpr static auto kJavaDescriptor = "Ljava/util/concurrent/Executor;";
|
|
void execute(jni::alias_ref<jni::JRunnable::javaobject> runnable);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JInspector.h}:
|
|
namespace facebook::react {
|
|
class JPage : public jni::JavaClass<JPage> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/Inspector$Page;";
|
|
static jni::local_ref<JPage::javaobject>
|
|
create(int id, const std::string& title, const std::string& vm);
|
|
};
|
|
class JRemoteConnection : public jni::JavaClass<JRemoteConnection> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/Inspector$RemoteConnection;";
|
|
void onMessage(const std::string& message) const;
|
|
void onDisconnect() const;
|
|
};
|
|
class JLocalConnection : public jni::HybridClass<JLocalConnection> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/Inspector$LocalConnection;";
|
|
JLocalConnection(
|
|
std::unique_ptr<jsinspector_modern::ILocalConnection> connection);
|
|
void sendMessage(std::string message);
|
|
void disconnect();
|
|
static void registerNatives();
|
|
};
|
|
class JInspector : public jni::HybridClass<JInspector> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/Inspector;";
|
|
static jni::global_ref<JInspector::javaobject> instance(
|
|
jni::alias_ref<jclass>);
|
|
jni::local_ref<jni::JArrayClass<JPage::javaobject>> getPages();
|
|
jni::local_ref<JLocalConnection::javaobject> connect(
|
|
int pageId,
|
|
jni::alias_ref<JRemoteConnection::javaobject> remote);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JMessageQueueThread.h}:
|
|
namespace facebook::react {
|
|
class JavaMessageQueueThread : public jni::JavaClass<JavaMessageQueueThread> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/queue/MessageQueueThread;";
|
|
};
|
|
class JMessageQueueThread : public MessageQueueThread {
|
|
public:
|
|
JMessageQueueThread(jni::alias_ref<JavaMessageQueueThread::javaobject> jobj);
|
|
void runOnQueue(std::function<void()>&& runnable) override;
|
|
void runOnQueueSync(std::function<void()>&& runnable) override;
|
|
void quitSynchronous() override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactCxxErrorHandler.h}:
|
|
namespace facebook::react {
|
|
class JReactCxxErrorHandler : public jni::JavaClass<JReactCxxErrorHandler> {
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReactCxxErrorHandler;";
|
|
static void handleError(std::string message);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactMarker.h}:
|
|
namespace facebook::react {
|
|
class JReactMarker : public facebook::jni::JavaClass<JReactMarker> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReactMarker;";
|
|
static void registerNatives();
|
|
static void setLogPerfMarkerIfNeeded();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JReactSoftExceptionLogger.h}:
|
|
namespace facebook::react {
|
|
class JReactSoftExceptionLogger
|
|
: public jni::JavaClass<JReactSoftExceptionLogger> {
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReactSoftExceptionLogger;";
|
|
static void logNoThrowSoftExceptionWithMessage(
|
|
std::string tag,
|
|
std::string message);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h}:
|
|
namespace facebook::react {
|
|
class JRuntimeExecutor : public jni::HybridClass<JRuntimeExecutor> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/RuntimeExecutor;";
|
|
RuntimeExecutor get();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JRuntimeScheduler.h}:
|
|
namespace facebook::react {
|
|
class JRuntimeScheduler : public jni::HybridClass<JRuntimeScheduler> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/RuntimeScheduler;";
|
|
std::weak_ptr<RuntimeScheduler> get();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JSLoader.h}:
|
|
namespace facebook::react {
|
|
struct JAssetManager : jni::JavaClass<JAssetManager> {
|
|
static constexpr auto kJavaDescriptor = "Landroid/content/res/AssetManager;";
|
|
};
|
|
AAssetManager* extractAssetManager(
|
|
jni::alias_ref<JAssetManager::javaobject> assetManager);
|
|
std::unique_ptr<const JSBigString> loadScriptFromAssets(
|
|
AAssetManager* assetManager,
|
|
const std::string& assetName);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JSLogging.h}:
|
|
namespace facebook::react {
|
|
void reactAndroidLoggingHook(const std::string& message, unsigned int logLevel);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JWeakRefUtils.h}:
|
|
namespace facebook::react {
|
|
template <typename T>
|
|
inline jni::local_ref<jni::JWeakReference<T>> makeJWeakReference(
|
|
jni::alias_ref<T> ref) {
|
|
return jni::JWeakReference<T>::newInstance(ref);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/MethodInvoker.h}
|
|
namespace facebook::react {
|
|
struct JMethodDescriptor : public jni::JavaClass<JMethodDescriptor> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/JavaModuleWrapper$MethodDescriptor;";
|
|
jni::local_ref<JReflectMethod::javaobject> getMethod() const;
|
|
std::string getSignature() const;
|
|
std::string getName() const;
|
|
std::string getType() const;
|
|
};
|
|
struct JavaModuleWrapper : jni::JavaClass<JavaModuleWrapper> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/JavaModuleWrapper;";
|
|
jni::local_ref<JBaseJavaModule::javaobject> getModule() {
|
|
static auto getModule =
|
|
javaClassStatic()->getMethod<JBaseJavaModule::javaobject()>(
|
|
"getModule");
|
|
return getModule(self());
|
|
}
|
|
std::string getName() const {
|
|
static auto getName = javaClassStatic()->getMethod<jstring()>("getName");
|
|
return getName(self())->toStdString();
|
|
}
|
|
jni::local_ref<jni::JList<JMethodDescriptor::javaobject>::javaobject>
|
|
getMethodDescriptors() {
|
|
static auto getMethods =
|
|
getClass()
|
|
->getMethod<
|
|
jni::JList<JMethodDescriptor::javaobject>::javaobject()>(
|
|
"getMethodDescriptors");
|
|
return getMethods(self());
|
|
}
|
|
};
|
|
class JavaNativeModule : public NativeModule {
|
|
public:
|
|
JavaNativeModule(
|
|
std::weak_ptr<Instance> instance,
|
|
jni::alias_ref<JavaModuleWrapper::javaobject> wrapper,
|
|
std::shared_ptr<MessageQueueThread> messageQueueThread)
|
|
: instance_(std::move(instance)),
|
|
wrapper_(make_global(wrapper)),
|
|
messageQueueThread_(std::move(messageQueueThread)) {}
|
|
std::string getName() override;
|
|
std::string getSyncMethodName(unsigned int reactMethodId) override;
|
|
folly::dynamic getConstants() override;
|
|
std::vector<MethodDescriptor> getMethods() override;
|
|
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId)
|
|
override;
|
|
MethodCallResult callSerializableNativeHook(
|
|
unsigned int reactMethodId,
|
|
folly::dynamic&& params) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JavaScriptExecutorHolder.h}:
|
|
namespace facebook::react {
|
|
class JavaScriptExecutorHolder
|
|
: public jni::HybridClass<JavaScriptExecutorHolder> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/JavaScriptExecutor;";
|
|
std::shared_ptr<JSExecutorFactory> getExecutorFactory() {
|
|
return mExecutorFactory;
|
|
}
|
|
|
|
protected:
|
|
JavaScriptExecutorHolder(std::shared_ptr<JSExecutorFactory> factory)
|
|
: mExecutorFactory(factory) {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/JniJSModulesUnbundle.h}:
|
|
namespace facebook::react {
|
|
class JniJSModulesUnbundle : public JSModulesUnbundle {
|
|
public:
|
|
JniJSModulesUnbundle() = default;
|
|
JniJSModulesUnbundle(
|
|
AAssetManager* assetManager,
|
|
const std::string& moduleDirectory);
|
|
JniJSModulesUnbundle(JniJSModulesUnbundle&& other) = delete;
|
|
JniJSModulesUnbundle& operator=(JSModulesUnbundle&& other) = delete;
|
|
static std::unique_ptr<JniJSModulesUnbundle> fromEntryFile(
|
|
AAssetManager* assetManager,
|
|
const std::string& entryFile);
|
|
static bool isUnbundle(
|
|
AAssetManager* assetManager,
|
|
const std::string& assetName);
|
|
virtual Module getModule(uint32_t moduleId) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/MethodInvoker.h}:
|
|
namespace facebook::react {
|
|
struct JReflectMethod : public jni::JavaClass<JReflectMethod> {
|
|
static constexpr auto kJavaDescriptor = "Ljava/lang/reflect/Method;";
|
|
jmethodID getMethodID() {
|
|
auto id = jni::Environment::current()->FromReflectedMethod(self());
|
|
jni::throwPendingJniExceptionAsCppException();
|
|
return id;
|
|
}
|
|
};
|
|
struct JBaseJavaModule : public jni::JavaClass<JBaseJavaModule> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/BaseJavaModule;";
|
|
};
|
|
class MethodInvoker {
|
|
public:
|
|
MethodInvoker(
|
|
jni::alias_ref<JReflectMethod::javaobject> method,
|
|
std::string methodName,
|
|
std::string signature,
|
|
std::string traceName,
|
|
bool isSync);
|
|
MethodCallResult invoke(
|
|
std::weak_ptr<Instance>& instance,
|
|
jni::alias_ref<JBaseJavaModule::javaobject> module,
|
|
const folly::dynamic& params);
|
|
std::string getMethodName() const;
|
|
bool isSyncHook() const {
|
|
return isSync_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/ModuleRegistryBuilder.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/CxxModuleWrapper.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/JavaModuleWrapper.h}
|
|
namespace facebook::react {
|
|
class ModuleHolder : public jni::JavaClass<ModuleHolder> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ModuleHolder;";
|
|
std::string getName() const;
|
|
xplat::module::CxxModule::Provider getProvider(
|
|
const std::string& moduleName) const;
|
|
};
|
|
std::vector<std::unique_ptr<NativeModule>> buildNativeModuleList(
|
|
std::weak_ptr<Instance> winstance,
|
|
jni::alias_ref<jni::JCollection<JavaModuleWrapper::javaobject>::javaobject>
|
|
javaModules,
|
|
jni::alias_ref<jni::JCollection<ModuleHolder::javaobject>::javaobject>
|
|
cxxModules,
|
|
std::shared_ptr<MessageQueueThread> moduleMessageQueue);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeArray.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeCommon.h}
|
|
|
|
namespace facebook::react {
|
|
class NativeArray : public jni::HybridClass<NativeArray> {
|
|
public:
|
|
static auto constexpr* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeArray;";
|
|
jni::local_ref<jstring> toString();
|
|
const folly::dynamic& getArray() const {
|
|
return array_;
|
|
}
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic array_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeArray(Dyn&& array)
|
|
: isConsumed(false), array_(std::forward<Dyn>(array)) {
|
|
assertInternalType();
|
|
}
|
|
void assertInternalType();
|
|
void throwIfConsumed();
|
|
NativeArray(const NativeArray&) = delete;
|
|
NativeArray& operator=(const NativeArray&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeCommon.h}:
|
|
namespace facebook::react {
|
|
struct ReadableType : public jni::JavaClass<ReadableType> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableType;";
|
|
static jni::local_ref<ReadableType> getType(folly::dynamic::Type type);
|
|
};
|
|
namespace exceptions {
|
|
extern const char* gUnexpectedNativeTypeExceptionClass;
|
|
template <typename T>
|
|
void throwIfObjectAlreadyConsumed(const T& t, const char* msg) {
|
|
if (t->isConsumed) {
|
|
jni::throwNewJavaException(
|
|
"com/facebook/react/bridge/ObjectAlreadyConsumedException", msg);
|
|
}
|
|
}
|
|
} // namespace exceptions
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeMap.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeCommon.h}
|
|
|
|
namespace facebook::react {
|
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeMap;";
|
|
jni::local_ref<jstring> toString();
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic map_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeMap(Dyn&& map)
|
|
: isConsumed(false), map_(std::forward<Dyn>(map)) {}
|
|
void throwIfConsumed();
|
|
NativeMap(const NativeMap&) = delete;
|
|
NativeMap& operator=(const NativeMap&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/ReactInstanceManagerInspectorTarget.h}:
|
|
namespace facebook::react {
|
|
class ReactInstanceManagerInspectorTarget
|
|
: public jni::HybridClass<ReactInstanceManagerInspectorTarget>,
|
|
public jsinspector_modern::HostTargetDelegate {};
|
|
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReactInstanceManagerInspectorTarget;";
|
|
ReactInstanceManagerInspectorTarget(
|
|
const ReactInstanceManagerInspectorTarget&) = delete;
|
|
ReactInstanceManagerInspectorTarget& operator=(
|
|
const ReactInstanceManagerInspectorTarget&) = delete;
|
|
~ReactInstanceManagerInspectorTarget() override;
|
|
static jni::local_ref<jhybriddata> initHybrid(
|
|
jni::alias_ref<jhybridobject> jobj,
|
|
jni::alias_ref<JExecutor::javaobject> javaExecutor,
|
|
jni::alias_ref<
|
|
ReactInstanceManagerInspectorTarget::TargetDelegate::javaobject>
|
|
delegate);
|
|
void sendDebuggerResumeCommand();
|
|
static void registerNatives();
|
|
jsinspector_modern::HostTarget* getInspectorTarget();
|
|
jsinspector_modern::HostTargetMetadata getMetadata() override;
|
|
void onReload(const PageReloadRequest& request) override;
|
|
void onSetPausedInDebuggerMessage(
|
|
const OverlaySetPausedInDebuggerMessageRequest&) override;
|
|
void loadNetworkResource(
|
|
const jsinspector_modern::LoadNetworkResourceRequest& params,
|
|
jsinspector_modern::ScopedExecutor<
|
|
jsinspector_modern::NetworkRequestListener> executor) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/ReadableNativeArray.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeArray.h}
|
|
namespace facebook::react {
|
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeMap;";
|
|
jni::local_ref<jstring> toString();
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic map_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeMap(Dyn&& map)
|
|
: isConsumed(false), map_(std::forward<Dyn>(map)) {}
|
|
void throwIfConsumed();
|
|
NativeMap(const NativeMap&) = delete;
|
|
NativeMap& operator=(const NativeMap&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct ReadableArray : jni::JavaClass<ReadableArray> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableArray;";
|
|
};
|
|
class ReadableNativeArray
|
|
: public jni::HybridClass<ReadableNativeArray, NativeArray> {
|
|
protected:
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit ReadableNativeArray(Dyn&& array)
|
|
: HybridBase(std::forward<Dyn>(array)) {}
|
|
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeArray;";
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
bool equals(jni::alias_ref<ReadableNativeArray::javaobject> other);
|
|
jni::local_ref<jni::JArrayClass<jobject>> importArray();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypeArray();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/ReadableNativeMap.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeCommon.h}
|
|
namespace facebook::react {
|
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeMap;";
|
|
jni::local_ref<jstring> toString();
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic map_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeMap(Dyn&& map)
|
|
: isConsumed(false), map_(std::forward<Dyn>(map)) {}
|
|
void throwIfConsumed();
|
|
NativeMap(const NativeMap&) = delete;
|
|
NativeMap& operator=(const NativeMap&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class NativeArray : public jni::HybridClass<NativeArray> {
|
|
public:
|
|
static auto constexpr* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeArray;";
|
|
jni::local_ref<jstring> toString();
|
|
const folly::dynamic& getArray() const {
|
|
return array_;
|
|
}
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic array_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeArray(Dyn&& array)
|
|
: isConsumed(false), array_(std::forward<Dyn>(array)) {
|
|
assertInternalType();
|
|
}
|
|
void assertInternalType();
|
|
void throwIfConsumed();
|
|
NativeArray(const NativeArray&) = delete;
|
|
NativeArray& operator=(const NativeArray&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
struct ReadableArray : jni::JavaClass<ReadableArray> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableArray;";
|
|
};
|
|
class ReadableNativeArray
|
|
: public jni::HybridClass<ReadableNativeArray, NativeArray> {
|
|
protected:
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit ReadableNativeArray(Dyn&& array)
|
|
: HybridBase(std::forward<Dyn>(array)) {}
|
|
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeArray;";
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
bool equals(jni::alias_ref<ReadableNativeArray::javaobject> other);
|
|
jni::local_ref<jni::JArrayClass<jobject>> importArray();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypeArray();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct ReadableMap : jni::JavaClass<ReadableMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableMap;";
|
|
};
|
|
void addDynamicToJArray(
|
|
jni::local_ref<jni::JArrayClass<jobject>> jarray,
|
|
jint index,
|
|
const folly::dynamic& dyn);
|
|
struct ReadableNativeMap : jni::HybridClass<ReadableNativeMap, NativeMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeMap;";
|
|
jni::local_ref<jni::JArrayClass<jstring>> importKeys();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importValues();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypes();
|
|
std::optional<folly::dynamic> keys_;
|
|
static jni::local_ref<jhybridobject> createWithContents(folly::dynamic&& map);
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
using HybridBase::HybridBase;
|
|
friend HybridBase;
|
|
friend
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/SafeReleaseJniRef.h}:
|
|
namespace facebook::react {
|
|
void ensureThreadDurationJNIEnvAttached();
|
|
template <typename RefT>
|
|
class SafeReleaseJniRef {
|
|
using T = std::remove_reference<decltype(*std::declval<RefT>())>::type;
|
|
|
|
public:
|
|
SafeReleaseJniRef() = default;
|
|
SafeReleaseJniRef(RefT ref) : ref_(std::move(ref)) {}
|
|
SafeReleaseJniRef(const SafeReleaseJniRef& other) = default;
|
|
SafeReleaseJniRef(SafeReleaseJniRef&& other) = default;
|
|
SafeReleaseJniRef& operator=(const SafeReleaseJniRef& other) = default;
|
|
SafeReleaseJniRef& operator=(SafeReleaseJniRef&& other) = default;
|
|
~SafeReleaseJniRef() {
|
|
if (ref_) {
|
|
ensureThreadDurationJNIEnvAttached();
|
|
ref_.reset();
|
|
}
|
|
}
|
|
operator bool() const noexcept {
|
|
return (bool)ref_;
|
|
}
|
|
T& operator*() noexcept {
|
|
return *ref_;
|
|
}
|
|
T* operator->() noexcept {
|
|
return &*ref_;
|
|
}
|
|
const T& operator*() const noexcept {
|
|
return *ref_;
|
|
}
|
|
const T* operator->() const noexcept {
|
|
return &*ref_;
|
|
}
|
|
operator RefT() const {
|
|
return ref_;
|
|
}
|
|
RefT::javaobject get() const {
|
|
return ref_.get();
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/TransformHelper.h}:
|
|
namespace facebook::react {
|
|
class TransformHelper : public jni::JavaClass<TransformHelper> {
|
|
public:
|
|
static auto constexpr* kJavaDescriptor =
|
|
"Lcom/facebook/react/uimanager/TransformHelper;";
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/WritableNativeArray.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeArray.h}
|
|
namespace facebook::react {
|
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeMap;";
|
|
jni::local_ref<jstring> toString();
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic map_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeMap(Dyn&& map)
|
|
: isConsumed(false), map_(std::forward<Dyn>(map)) {}
|
|
void throwIfConsumed();
|
|
NativeMap(const NativeMap&) = delete;
|
|
NativeMap& operator=(const NativeMap&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct ReadableArray : jni::JavaClass<ReadableArray> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableArray;";
|
|
};
|
|
class ReadableNativeArray
|
|
: public jni::HybridClass<ReadableNativeArray, NativeArray> {
|
|
protected:
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit ReadableNativeArray(Dyn&& array)
|
|
: HybridBase(std::forward<Dyn>(array)) {}
|
|
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeArray;";
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
bool equals(jni::alias_ref<ReadableNativeArray::javaobject> other);
|
|
jni::local_ref<jni::JArrayClass<jobject>> importArray();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypeArray();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct WritableArray : jni::JavaClass<WritableArray> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/WritableArray;";
|
|
};
|
|
struct WritableNativeArray
|
|
: public jni::HybridClass<WritableNativeArray, ReadableNativeArray> {
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/WritableNativeArray;";
|
|
WritableNativeArray();
|
|
WritableNativeArray(folly::dynamic&& val);
|
|
static void initHybrid(jni::alias_ref<jhybridobject> jobj);
|
|
void pushNull();
|
|
void pushBoolean(jboolean value);
|
|
void pushDouble(jdouble value);
|
|
void pushInt(jint value);
|
|
void pushLong(jlong value);
|
|
void pushString(jstring value);
|
|
void pushNativeArray(ReadableNativeArray* otherArray);
|
|
void pushNativeMap(ReadableNativeMap* map);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/jni/WritableNativeMap.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/jni/NativeArray.h}
|
|
namespace facebook::react {
|
|
class NativeMap : public jni::HybridClass<NativeMap> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/NativeMap;";
|
|
jni::local_ref<jstring> toString();
|
|
__attribute__((visibility("default"))) folly::dynamic consume();
|
|
bool isConsumed;
|
|
static void registerNatives();
|
|
|
|
protected:
|
|
folly::dynamic map_;
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit NativeMap(Dyn&& map)
|
|
: isConsumed(false), map_(std::forward<Dyn>(map)) {}
|
|
void throwIfConsumed();
|
|
NativeMap(const NativeMap&) = delete;
|
|
NativeMap& operator=(const NativeMap&) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct ReadableArray : jni::JavaClass<ReadableArray> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableArray;";
|
|
};
|
|
class ReadableNativeArray
|
|
: public jni::HybridClass<ReadableNativeArray, NativeArray> {
|
|
protected:
|
|
friend HybridBase;
|
|
template <class Dyn>
|
|
explicit ReadableNativeArray(Dyn&& array)
|
|
: HybridBase(std::forward<Dyn>(array)) {}
|
|
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeArray;";
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
bool equals(jni::alias_ref<ReadableNativeArray::javaobject> other);
|
|
jni::local_ref<jni::JArrayClass<jobject>> importArray();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypeArray();
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
struct ReadableMap : jni::JavaClass<ReadableMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableMap;";
|
|
};
|
|
void addDynamicToJArray(
|
|
jni::local_ref<jni::JArrayClass<jobject>> jarray,
|
|
jint index,
|
|
const folly::dynamic& dyn);
|
|
struct ReadableNativeMap : jni::HybridClass<ReadableNativeMap, NativeMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/ReadableNativeMap;";
|
|
jni::local_ref<jni::JArrayClass<jstring>> importKeys();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importValues();
|
|
jni::local_ref<jni::JArrayClass<jobject>> importTypes();
|
|
std::optional<folly::dynamic> keys_;
|
|
static jni::local_ref<jhybridobject> createWithContents(folly::dynamic&& map);
|
|
static void mapException(std::exception_ptr ex);
|
|
static void registerNatives();
|
|
using HybridBase::HybridBase;
|
|
friend HybridBase;
|
|
friend
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
struct WritableMap : jni::JavaClass<WritableMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/WritableMap;";
|
|
};
|
|
struct WritableNativeMap
|
|
: jni::HybridClass<WritableNativeMap, ReadableNativeMap> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/bridge/WritableNativeMap;";
|
|
WritableNativeMap();
|
|
WritableNativeMap(folly::dynamic&& val);
|
|
static void initHybrid(jni::alias_ref<jhybridobject> jobj);
|
|
void putNull(std::string key);
|
|
void putBoolean(std::string key, bool val);
|
|
void putDouble(std::string key, double val);
|
|
void putInt(std::string key, int val);
|
|
void putLong(std::string key, jlong val);
|
|
void putString(std::string key, jni::alias_ref<jstring> val);
|
|
void putNativeArray(std::string key, ReadableNativeArray* val);
|
|
void putNativeMap(std::string key, ReadableNativeMap* val);
|
|
void mergeNativeMap(ReadableNativeMap* other);
|
|
static void registerNatives();
|
|
friend HybridBase;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/mapbuffer/react/common/mapbuffer/JReadableMapBuffer.h}:
|
|
namespace facebook::react {
|
|
class JReadableMapBuffer : public jni::HybridClass<JReadableMapBuffer> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/common/mapbuffer/ReadableMapBuffer;";
|
|
static jni::local_ref<JReadableMapBuffer::jhybridobject> createWithContents(
|
|
MapBuffer&& map);
|
|
explicit JReadableMapBuffer(MapBuffer&& map);
|
|
std::vector<uint8_t> data() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/mapbuffer/react/common/mapbuffer/JWritableMapBuffer.h}:
|
|
namespace facebook::react {
|
|
class JWritableMapBuffer : public jni::JavaClass<JWritableMapBuffer> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/common/mapbuffer/WritableMapBuffer;";
|
|
MapBuffer getMapBuffer();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultComponentsRegistry.h}:
|
|
namespace facebook::react {
|
|
class DefaultComponentsRegistry
|
|
: public facebook::jni::JavaClass<DefaultComponentsRegistry> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/defaults/DefaultComponentsRegistry;";
|
|
static void registerNatives();
|
|
static std::function<void(
|
|
std::shared_ptr<const ComponentDescriptorProviderRegistry>)>
|
|
registerComponentDescriptorsFromEntryPoint;
|
|
static std::function<void(
|
|
std::shared_ptr<const ComponentDescriptorProviderRegistry>)>
|
|
registerCodegenComponentDescriptorsFromEntryPoint;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/DefaultTurboModuleManagerDelegate.h}:
|
|
namespace facebook::react {
|
|
class DefaultTurboModuleManagerDelegate : public jni::HybridClass<
|
|
DefaultTurboModuleManagerDelegate,
|
|
TurboModuleManagerDelegate> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/defaults/DefaultTurboModuleManagerDelegate;";
|
|
static jni::local_ref<jhybriddata> initHybrid(
|
|
jni::alias_ref<jclass>,
|
|
jni::alias_ref<jni::JList<CxxReactPackage::javaobject>::javaobject>);
|
|
static void registerNatives();
|
|
static std::function<std::shared_ptr<TurboModule>(
|
|
const std::string&,
|
|
const std::shared_ptr<CallInvoker>&)>
|
|
cxxModuleProvider;
|
|
static std::function<std::shared_ptr<TurboModule>(
|
|
const std::string&,
|
|
const JavaTurboModule::InitParams&)>
|
|
javaModuleProvider;
|
|
std::shared_ptr<TurboModule> getTurboModule(
|
|
const std::string& name,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) override;
|
|
std::shared_ptr<TurboModule> getTurboModule(
|
|
const std::string& name,
|
|
const JavaTurboModule::InitParams& params) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/newarchdefaults/rncore.h}:
|
|
namespace facebook::react {
|
|
constexpr auto rncore_ModuleProvider = FBReactNativeSpec_ModuleProvider;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/reactnativeblob/BlobCollector.h}:
|
|
namespace facebook::react {
|
|
class BlobCollector : public jni::HybridClass<BlobCollector>,
|
|
public jsi::HostObject {
|
|
public:
|
|
BlobCollector(jni::global_ref<jobject> blobModule, const std::string& blobId);
|
|
~BlobCollector();
|
|
size_t getBlobLength();
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/modules/blob/BlobCollector;";
|
|
static void nativeInstall(
|
|
jni::alias_ref<jclass>,
|
|
jni::alias_ref<jobject> blobModule,
|
|
jlong jsContextNativePointer);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/reactperflogger/reactperflogger/JNativeModulePerfLogger.h}:
|
|
namespace facebook::react {
|
|
class JNativeModulePerfLogger
|
|
: public jni::HybridClass<JNativeModulePerfLogger> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/reactperflogger/NativeModulePerfLogger;";
|
|
virtual std::unique_ptr<facebook::react::NativeModulePerfLogger> get() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/cxxreactpackage/ReactCommon/CxxReactPackage.h}:
|
|
namespace facebook::react {
|
|
class CxxReactPackage : public jni::HybridClass<CxxReactPackage> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/cxxreactpackage/CxxReactPackage;";
|
|
virtual std::shared_ptr<TurboModule> getModule(
|
|
const std::string& name,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/hermes/jni/JHermesInstance.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSRuntimeFactory.h}
|
|
|
|
namespace facebook::react {
|
|
class JHermesInstance
|
|
: public jni::HybridClass<JHermesInstance, JJSRuntimeFactory> {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/hermes/HermesInstance;";
|
|
static jni::local_ref<jhybriddata> initHybrid(
|
|
jni::alias_ref<jclass>,
|
|
bool allocInOldGenBeforeTTI);
|
|
static void registerNatives();
|
|
JHermesInstance(bool allocInOldGenBeforeTTI)
|
|
: allocInOldGenBeforeTTI_(allocInOldGenBeforeTTI) {};
|
|
std::unique_ptr<JSRuntime> createJSRuntime(
|
|
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept;
|
|
~JHermesInstance() {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JBindingsInstaller.h}:
|
|
namespace facebook::react {
|
|
class JBindingsInstaller : public jni::HybridClass<JBindingsInstaller>,
|
|
public BindingsInstaller {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/BindingsInstaller;";
|
|
~JBindingsInstaller() {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSRuntimeFactory.h}:
|
|
namespace facebook::react {
|
|
class JJSRuntimeFactory : public jni::HybridClass<JJSRuntimeFactory>,
|
|
public JSRuntimeFactory {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/JSRuntimeFactory;";
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.h}:
|
|
namespace facebook::react {
|
|
class JJSTimerExecutor : public jni::HybridClass<JJSTimerExecutor> {
|
|
public:
|
|
JJSTimerExecutor() = default;
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/JSTimerExecutor;";
|
|
static void registerNatives();
|
|
void setTimerManager(std::weak_ptr<TimerManager> timerManager);
|
|
void callTimers(WritableNativeArray* timerIDs);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJavaTimerManager.h}:
|
|
namespace facebook::react {
|
|
struct JJavaTimerManager : jni::JavaClass<JJavaTimerManager> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/modules/core/JavaTimerManager;";
|
|
void createTimer(uint32_t timerID, double duration, bool repeat);
|
|
void deleteTimer(uint32_t timerID);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactExceptionManager.h}:
|
|
namespace facebook::react {
|
|
class JReactExceptionManager
|
|
: public facebook::jni::JavaClass<JReactExceptionManager> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/interfaces/exceptionmanager/ReactJsExceptionHandler;";
|
|
void reportJsException(
|
|
jsi::Runtime& runtime,
|
|
const JsErrorHandler::ProcessedError& error);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h}:
|
|
namespace facebook::react {
|
|
struct JTaskInterface : public jni::JavaClass<JTaskInterface> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/interfaces/TaskInterface;";
|
|
};
|
|
struct JReactHostImpl : public jni::JavaClass<JReactHostImpl> {
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/ReactHostImpl;";
|
|
jni::local_ref<JTaskInterface::javaobject> reload(const std::string& reason) {
|
|
static auto method =
|
|
javaClassStatic()->getMethod<JTaskInterface::javaobject(std::string)>(
|
|
"reload");
|
|
return method(self(), reason);
|
|
}
|
|
void setPausedInDebuggerMessage(std::optional<std::string> message) {
|
|
static auto method =
|
|
javaClassStatic()->getMethod<void(jni::local_ref<jni::JString>)>(
|
|
"setPausedInDebuggerMessage");
|
|
method(self(), message ? jni::make_jstring(*message) : nullptr);
|
|
}
|
|
jni::local_ref<jni::JMap<jstring, jstring>> getHostMetadata() const {
|
|
static auto method =
|
|
javaClassStatic()
|
|
->getMethod<jni::local_ref<jni::JMap<jstring, jstring>>()>(
|
|
"getHostMetadata");
|
|
return method(self());
|
|
}
|
|
void loadNetworkResource(
|
|
const std::string& url,
|
|
jni::local_ref<InspectorNetworkRequestListener::javaobject> listener)
|
|
const {
|
|
auto method =
|
|
javaClassStatic()
|
|
->getMethod<void(
|
|
jni::local_ref<jni::JString>,
|
|
jni::local_ref<InspectorNetworkRequestListener::javaobject>)>(
|
|
"loadNetworkResource");
|
|
return method(self(), jni::make_jstring(url), listener);
|
|
}
|
|
};
|
|
class JReactHostInspectorTarget
|
|
: public jni::HybridClass<JReactHostInspectorTarget>,
|
|
public jsinspector_modern::HostTargetDelegate {
|
|
public:
|
|
static constexpr auto kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/ReactHostInspectorTarget;";
|
|
~JReactHostInspectorTarget() override;
|
|
static jni::local_ref<JReactHostInspectorTarget::jhybriddata> initHybrid(
|
|
jni::alias_ref<JReactHostInspectorTarget::jhybridobject> jThis,
|
|
jni::alias_ref<JReactHostImpl> reactHost,
|
|
jni::alias_ref<JExecutor::javaobject> javaExecutor);
|
|
static void registerNatives();
|
|
void sendDebuggerResumeCommand();
|
|
jsinspector_modern::HostTarget* getInspectorTarget();
|
|
jsinspector_modern::HostTargetMetadata getMetadata() override;
|
|
void onReload(const PageReloadRequest& request) override;
|
|
void onSetPausedInDebuggerMessage(
|
|
const OverlaySetPausedInDebuggerMessageRequest&) override;
|
|
void loadNetworkResource(
|
|
const jsinspector_modern::LoadNetworkResourceRequest& params,
|
|
jsinspector_modern::ScopedExecutor<
|
|
jsinspector_modern::NetworkRequestListener> executor) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactInstance.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JBindingsInstaller.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSRuntimeFactory.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJSTimerExecutor.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJavaTimerManager.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactExceptionManager.h}
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JReactHostInspectorTarget.h}
|
|
|
|
namespace facebook::react {
|
|
class JReactInstance : public jni::HybridClass<JReactInstance> {
|
|
public:
|
|
constexpr static auto kJavaDescriptor =
|
|
"Lcom/facebook/react/runtime/ReactInstance;";
|
|
static jni::local_ref<jhybriddata> initHybrid(
|
|
jni::alias_ref<jhybridobject>,
|
|
jni::alias_ref<JJSRuntimeFactory::javaobject> jsRuntimeFactory,
|
|
jni::alias_ref<JavaMessageQueueThread::javaobject> jsMessageQueueThread,
|
|
jni::alias_ref<JavaMessageQueueThread::javaobject>
|
|
nativeMessageQueueThread,
|
|
jni::alias_ref<JJavaTimerManager::javaobject> javaTimerManager,
|
|
jni::alias_ref<JJSTimerExecutor::javaobject> jsTimerExecutor,
|
|
jni::alias_ref<JReactExceptionManager::javaobject> jReactExceptionManager,
|
|
jni::alias_ref<JBindingsInstaller::javaobject> jBindingsInstaller,
|
|
bool isProfiling,
|
|
jni::alias_ref<JReactHostInspectorTarget::javaobject>
|
|
jReactHostInspectorTarget);
|
|
static jni::global_ref<JJSTimerExecutor::javaobject> createJSTimerExecutor(
|
|
jni::alias_ref<jhybridobject>);
|
|
static void registerNatives();
|
|
void loadJSBundleFromAssets(
|
|
jni::alias_ref<JAssetManager::javaobject> assetManager,
|
|
const std::string& assetURL);
|
|
void loadJSBundleFromFile(
|
|
const std::string& fileName,
|
|
const std::string& sourceURL);
|
|
void callFunctionOnModule(
|
|
const std::string& moduleName,
|
|
const std::string& methodName,
|
|
NativeArray* args);
|
|
jni::alias_ref<JRuntimeExecutor::javaobject>
|
|
getUnbufferedRuntimeExecutor() noexcept;
|
|
jni::alias_ref<JRuntimeExecutor::javaobject>
|
|
getBufferedRuntimeExecutor() noexcept;
|
|
jni::alias_ref<JRuntimeScheduler::javaobject> getRuntimeScheduler() noexcept;
|
|
void registerSegment(int segmentId, const std::string& segmentPath) noexcept;
|
|
void handleMemoryPressureJs(jint level);
|
|
void unregisterFromInspector();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JavaTimerRegistry.h}:
|
|
/// @dep {packages/react-native/ReactAndroid/src/main/jni/react/runtime/jni/JJavaTimerManager.h}
|
|
|
|
namespace facebook::react {
|
|
class JavaTimerRegistry : public PlatformTimerRegistry {
|
|
public:
|
|
JavaTimerRegistry(
|
|
jni::global_ref<JJavaTimerManager::javaobject> javaTimerManager);
|
|
void createTimer(uint32_t timerID, double delayMS) override;
|
|
void createRecurringTimer(uint32_t timerID, double delayMS) override;
|
|
void deleteTimer(uint32_t timerID) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/BindingsInstallerHolder.h}:
|
|
namespace facebook::react {
|
|
class BindingsInstallerHolder
|
|
: public jni::HybridClass<BindingsInstallerHolder> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/turbomodule/core/interfaces/BindingsInstallerHolder;";
|
|
using BindingsInstallFunc = std::function<void(
|
|
jsi::Runtime& runtime,
|
|
const std::shared_ptr<CallInvoker>& callInvoker)>;
|
|
void installBindings(
|
|
jsi::Runtime& runtime,
|
|
const std::shared_ptr<CallInvoker>& callInvoker);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/CallInvokerHolder.h}:
|
|
namespace facebook::react {
|
|
class CallInvokerHolder : public jni::HybridClass<CallInvokerHolder> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/turbomodule/core/CallInvokerHolderImpl;";
|
|
std::shared_ptr<CallInvoker> getCallInvoker() {
|
|
return callInvoker_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/NativeMethodCallInvokerHolder.h}:
|
|
namespace facebook::react {
|
|
class NativeMethodCallInvokerHolder
|
|
: public jni::HybridClass<NativeMethodCallInvokerHolder> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/turbomodule/core/NativeMethodCallInvokerHolderImpl;";
|
|
std::shared_ptr<NativeMethodCallInvoker> getNativeMethodCallInvoker() {
|
|
return nativeMethodCallInvoker_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManager.h}:
|
|
namespace facebook::react {
|
|
class TurboModuleManager : public jni::HybridClass<TurboModuleManager> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/internal/turbomodule/core/TurboModuleManager;";
|
|
static jni::local_ref<jhybriddata> initHybrid(
|
|
jni::alias_ref<jhybridobject>,
|
|
jni::alias_ref<JRuntimeExecutor::javaobject> runtimeExecutor,
|
|
jni::alias_ref<CallInvokerHolder::javaobject> jsCallInvokerHolder,
|
|
jni::alias_ref<NativeMethodCallInvokerHolder::javaobject>
|
|
nativeMethodCallInvokerHolder,
|
|
jni::alias_ref<TurboModuleManagerDelegate::javaobject> delegate);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/turbomodule/ReactCommon/TurboModuleManagerDelegate.h}:
|
|
namespace facebook::react {
|
|
class TurboModuleManagerDelegate
|
|
: public jni::HybridClass<TurboModuleManagerDelegate> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/internal/turbomodule/core/TurboModuleManagerDelegate;";
|
|
virtual std::shared_ptr<TurboModule> getTurboModule(
|
|
const std::string& name,
|
|
const JavaTurboModule::InitParams& params) = 0;
|
|
virtual std::shared_ptr<TurboModule> getTurboModule(
|
|
const std::string& name,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/uimanager/ComponentNameResolverBinding.h}:
|
|
namespace facebook::react {
|
|
class ComponentNameResolverBinding
|
|
: public facebook::jni::JavaClass<ComponentNameResolverBinding> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/uimanager/ComponentNameResolverBinding;";
|
|
static void install(
|
|
jni::alias_ref<jclass>,
|
|
jni::alias_ref<JRuntimeExecutor::javaobject> runtimeExecutor,
|
|
jni::alias_ref<jobject> componentNameResolver);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/react/uimanager/UIConstantsProviderBinding.h}:
|
|
namespace facebook::react {
|
|
class DefaultEventTypesProvider
|
|
: public jni::JavaClass<DefaultEventTypesProvider> {
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/uimanager/UIConstantsProviderBinding$DefaultEventTypesProvider;";
|
|
folly::dynamic getDefaultEventTypes() const {
|
|
static auto method =
|
|
javaClassStatic()
|
|
->getMethod<jni::alias_ref<NativeMap::jhybridobject>()>(
|
|
"getDefaultEventTypes");
|
|
return method(self())->cthis()->consume();
|
|
}
|
|
};
|
|
class ConstantsForViewManagerProvider
|
|
: public jni::JavaClass<ConstantsForViewManagerProvider> {
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/uimanager/UIConstantsProviderBinding$ConstantsForViewManagerProvider;";
|
|
folly::dynamic getConstantsForViewManager(
|
|
const std::string& viewManagerName) const {
|
|
static auto method =
|
|
javaClassStatic()
|
|
->getMethod<jni::alias_ref<NativeMap::jhybridobject>(
|
|
const std::string&)>("getConstantsForViewManager");
|
|
auto result = method(self(), viewManagerName);
|
|
if (result == nullptr) {
|
|
return nullptr;
|
|
}
|
|
return result->cthis()->consume();
|
|
}
|
|
};
|
|
class ConstantsProvider : public jni::JavaClass<ConstantsProvider> {
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/react/uimanager/UIConstantsProviderBinding$ConstantsProvider;";
|
|
folly::dynamic getConstants() const {
|
|
static auto method =
|
|
javaClassStatic()
|
|
->getMethod<jni::alias_ref<NativeMap::jhybridobject>()>(
|
|
"getConstants");
|
|
return method(self())->cthis()->consume();
|
|
}
|
|
};
|
|
class UIConstantsProviderBinding
|
|
: public jni::JavaClass<UIConstantsProviderBinding> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/uimanager/UIConstantsProviderBinding;";
|
|
static void install(
|
|
jni::alias_ref<jclass>,
|
|
jni::alias_ref<JRuntimeExecutor::javaobject> runtimeExecutor,
|
|
jni::alias_ref<DefaultEventTypesProvider::javaobject>
|
|
defaultExportableEventTypesProvider,
|
|
jni::alias_ref<ConstantsForViewManagerProvider::javaobject>
|
|
constantsForViewManagerProvider,
|
|
jni::alias_ref<ConstantsProvider::javaobject> constantsProvider);
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactAndroid/src/main/jni/third-party/glog/config.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactApple/Libraries/RCTFoundation/RCTDeprecation/Exported/RCTDeprecation.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/callinvoker/ReactCommon/CallInvoker.h}:
|
|
/// @dep {packages/react-native/ReactCommon/callinvoker/ReactCommon/SchedulerPriority.h}
|
|
namespace facebook::jsi {
|
|
}
|
|
namespace facebook::react {
|
|
using CallFunc = std::function<void(jsi::Runtime&)>;
|
|
class CallInvoker {
|
|
public:
|
|
virtual void invokeAsync(CallFunc&& func) noexcept = 0;
|
|
virtual void invokeAsync(SchedulerPriority, CallFunc&& func) noexcept {
|
|
invokeAsync(std::move(func));
|
|
}
|
|
virtual void invokeSync(CallFunc&& func) = 0;
|
|
virtual void invokeAsync(std::function<void()>&& func) noexcept {
|
|
invokeAsync([func](jsi::Runtime&) { func(); });
|
|
}
|
|
virtual void invokeSync(std::function<void()>&& func) {
|
|
invokeSync([func](jsi::Runtime&) { func(); });
|
|
}
|
|
virtual ~CallInvoker() = default;
|
|
};
|
|
using NativeMethodCallFunc = std::function<void()>;
|
|
class NativeMethodCallInvoker {
|
|
public:
|
|
virtual void invokeAsync(
|
|
const std::string& methodName,
|
|
NativeMethodCallFunc&& func) noexcept = 0;
|
|
virtual void invokeSync(
|
|
const std::string& methodName,
|
|
NativeMethodCallFunc&& func) = 0;
|
|
virtual ~NativeMethodCallInvoker() = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/callinvoker/ReactCommon/SchedulerPriority.h}:
|
|
namespace facebook::react {
|
|
enum class SchedulerPriority : int {
|
|
ImmediatePriority = 1,
|
|
UserBlockingPriority = 2,
|
|
NormalPriority = 3,
|
|
LowPriority = 4,
|
|
IdlePriority = 5,
|
|
};
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/callinvoker/ReactCommon/tests/TestCallInvoker.h}:
|
|
namespace facebook::react {
|
|
class TestCallInvoker : public CallInvoker {
|
|
public:
|
|
explicit TestCallInvoker(std::shared_ptr<facebook::jsi::Runtime> runtime)
|
|
: runtime_(runtime) {}
|
|
void invokeAsync(CallFunc&& func) noexcept override {
|
|
queue_.push_back(std::move(func));
|
|
}
|
|
void invokeSync(CallFunc&& func) override {
|
|
func(*runtime_);
|
|
}
|
|
void flushQueue() {
|
|
while (!queue_.empty()) {
|
|
queue_.front()(*runtime_);
|
|
queue_.pop_front();
|
|
runtime_->drainMicrotasks();
|
|
}
|
|
}
|
|
};
|
|
std::shared_ptr<facebook::jsi::Runtime> runtime_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/CxxModule.h}:
|
|
namespace facebook::react {
|
|
}
|
|
namespace facebook::xplat::module {
|
|
class CxxModule {
|
|
class AsyncTagType {};
|
|
class SyncTagType {};
|
|
|
|
public:
|
|
using Provider = std::function<std::unique_ptr<CxxModule>()>;
|
|
using Callback = std::function<void(std::vector<folly::dynamic>)>;
|
|
constexpr static AsyncTagType AsyncTag = AsyncTagType();
|
|
constexpr static SyncTagType SyncTag = SyncTagType();
|
|
struct Method {
|
|
std::string name;
|
|
size_t callbacks;
|
|
bool isPromise;
|
|
std::function<void(folly::dynamic, Callback, Callback)> func;
|
|
std::function<folly::dynamic(folly::dynamic)> syncFunc;
|
|
const char* getType() {
|
|
assert(func || syncFunc);
|
|
return func ? (isPromise ? "promise" : "async") : "sync";
|
|
}
|
|
Method(std::string aname, std::function<void()>&& afunc)
|
|
: name(std::move(aname)),
|
|
callbacks(0),
|
|
isPromise(false),
|
|
func(std::bind(std::move(afunc))) {}
|
|
Method(std::string aname, std::function<void(folly::dynamic)>&& afunc)
|
|
: name(std::move(aname)),
|
|
callbacks(0),
|
|
isPromise(false),
|
|
func(std::bind(std::move(afunc), std::placeholders::_1)) {}
|
|
Method(
|
|
std::string aname,
|
|
std::function<void(folly::dynamic, Callback)>&& afunc)
|
|
: name(std::move(aname)),
|
|
callbacks(1),
|
|
isPromise(false),
|
|
func(std::bind(
|
|
std::move(afunc),
|
|
std::placeholders::_1,
|
|
std::placeholders::_2)) {}
|
|
Method(
|
|
std::string aname,
|
|
std::function<void(folly::dynamic, Callback, Callback)>&& afunc)
|
|
: name(std::move(aname)),
|
|
callbacks(2),
|
|
isPromise(true),
|
|
func(std::move(afunc)) {}
|
|
Method(
|
|
std::string aname,
|
|
std::function<void(folly::dynamic, Callback, Callback)>&& afunc,
|
|
AsyncTagType)
|
|
: name(std::move(aname)),
|
|
callbacks(2),
|
|
isPromise(false),
|
|
func(std::move(afunc)) {}
|
|
template <typename T>
|
|
Method(std::string aname, T* t, void (T::*method)())
|
|
: name(std::move(aname)),
|
|
callbacks(0),
|
|
isPromise(false),
|
|
func(std::bind(method, t)) {}
|
|
template <typename T>
|
|
Method(std::string aname, T* t, void (T::*method)(folly::dynamic))
|
|
: name(std::move(aname)),
|
|
callbacks(0),
|
|
isPromise(false),
|
|
func(std::bind(method, t, std::placeholders::_1)) {}
|
|
template <typename T>
|
|
Method(std::string aname, T* t, void (T::*method)(folly::dynamic, Callback))
|
|
: name(std::move(aname)),
|
|
callbacks(1),
|
|
isPromise(false),
|
|
func(std::bind(
|
|
method,
|
|
t,
|
|
std::placeholders::_1,
|
|
std::placeholders::_2)) {}
|
|
template <typename T>
|
|
Method(
|
|
std::string aname,
|
|
T* t,
|
|
void (T::*method)(folly::dynamic, Callback, Callback))
|
|
: name(std::move(aname)),
|
|
callbacks(2),
|
|
isPromise(true),
|
|
func(std::bind(
|
|
method,
|
|
t,
|
|
std::placeholders::_1,
|
|
std::placeholders::_2,
|
|
std::placeholders::_3)) {}
|
|
template <typename T>
|
|
Method(
|
|
std::string aname,
|
|
T* t,
|
|
void (T::*method)(folly::dynamic, Callback, Callback),
|
|
AsyncTagType)
|
|
: name(std::move(aname)),
|
|
callbacks(2),
|
|
isPromise(false),
|
|
func(std::bind(
|
|
method,
|
|
t,
|
|
std::placeholders::_1,
|
|
std::placeholders::_2,
|
|
std::placeholders::_3)) {}
|
|
Method(
|
|
std::string aname,
|
|
std::function<folly::dynamic()>&& afunc,
|
|
SyncTagType)
|
|
: name(std::move(aname)),
|
|
callbacks(0),
|
|
isPromise(false),
|
|
syncFunc([afunc = std::move(afunc)](const folly::dynamic&) {
|
|
return afunc();
|
|
}) {}
|
|
Method(
|
|
std::string aname,
|
|
std::function<folly::dynamic(folly::dynamic)>&& afunc,
|
|
SyncTagType)
|
|
: name(std::move(aname)),
|
|
callbacks(0),
|
|
isPromise(false),
|
|
syncFunc(std::move(afunc)) {}
|
|
};
|
|
virtual ~CxxModule() = default;
|
|
virtual std::string getName() = 0;
|
|
virtual auto getConstants() -> std::map<std::string, folly::dynamic> {
|
|
return {};
|
|
};
|
|
virtual auto getMethods() -> std::vector<Method> = 0;
|
|
void setInstance(std::weak_ptr<react::Instance> instance) {
|
|
instance_ = instance;
|
|
}
|
|
std::weak_ptr<react::Instance> getInstance() {
|
|
return instance_;
|
|
}
|
|
};
|
|
} // namespace facebook::xplat::module
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/CxxNativeModule.h}:
|
|
namespace facebook::react {
|
|
typedef void (*WarnOnUsageLogger)(std::string message);
|
|
std::function<void(folly::dynamic)> makeCallback(
|
|
std::weak_ptr<Instance> instance,
|
|
const folly::dynamic& callbackId);
|
|
class __attribute__((visibility("default"))) CxxNativeModule
|
|
: public NativeModule {
|
|
public:
|
|
CxxNativeModule(
|
|
std::weak_ptr<Instance> instance,
|
|
std::string name,
|
|
xplat::module::CxxModule::Provider provider,
|
|
std::shared_ptr<MessageQueueThread> messageQueueThread)
|
|
: instance_(instance),
|
|
name_(std::move(name)),
|
|
provider_(provider),
|
|
messageQueueThread_(messageQueueThread) {}
|
|
std::string getName() override;
|
|
std::string getSyncMethodName(unsigned int methodId) override;
|
|
std::vector<MethodDescriptor> getMethods() override;
|
|
folly::dynamic getConstants() override;
|
|
void invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId)
|
|
override;
|
|
MethodCallResult callSerializableNativeHook(
|
|
unsigned int hookId,
|
|
folly::dynamic&& args) override;
|
|
static void setShouldWarnOnUse(bool value);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/ErrorUtils.h}:
|
|
namespace facebook::react {
|
|
inline static void
|
|
handleJSError(jsi::Runtime& runtime, const jsi::JSError& error, bool isFatal) {
|
|
auto errorUtils = runtime.global().getProperty(runtime, "ErrorUtils");
|
|
if (errorUtils.isUndefined() || !errorUtils.isObject() ||
|
|
!errorUtils.getObject(runtime).hasProperty(runtime, "reportFatalError") ||
|
|
!errorUtils.getObject(runtime).hasProperty(runtime, "reportError")) {
|
|
throw jsi::JSError(
|
|
runtime,
|
|
"ErrorUtils is not set up properly. Something probably went wrong trying to load the JS bundle. Trying to report error " +
|
|
error.getMessage(),
|
|
error.getStack());
|
|
}
|
|
if (isFatal) {
|
|
auto func = errorUtils.asObject(runtime).getPropertyAsFunction(
|
|
runtime, "reportFatalError");
|
|
func.call(runtime, error.value());
|
|
} else {
|
|
auto func = errorUtils.asObject(runtime).getPropertyAsFunction(
|
|
runtime, "reportError");
|
|
func.call(runtime, error.value());
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/Instance.h}:
|
|
namespace folly {
|
|
}
|
|
namespace facebook::react {
|
|
struct InstanceCallback {
|
|
virtual ~InstanceCallback() = default;
|
|
virtual void onBatchComplete() {}
|
|
virtual void incrementPendingJSCalls() {}
|
|
virtual void decrementPendingJSCalls() {}
|
|
};
|
|
class __attribute__((visibility("default"))) Instance
|
|
: private jsinspector_modern::InstanceTargetDelegate {
|
|
public:
|
|
~Instance() override;
|
|
void initializeBridge(
|
|
std::unique_ptr<InstanceCallback> callback,
|
|
std::shared_ptr<JSExecutorFactory> jsef,
|
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
std::shared_ptr<ModuleRegistry> moduleRegistry,
|
|
jsinspector_modern::HostTarget* inspectorTarget = nullptr);
|
|
void initializeRuntime();
|
|
void setSourceURL(std::string sourceURL);
|
|
void loadScriptFromString(
|
|
std::unique_ptr<const JSBigString> string,
|
|
std::string sourceURL,
|
|
bool loadSynchronously);
|
|
void loadRAMBundleFromString(
|
|
std::unique_ptr<const JSBigString> script,
|
|
const std::string& sourceURL);
|
|
void loadRAMBundleFromFile(
|
|
const std::string& sourcePath,
|
|
const std::string& sourceURL,
|
|
bool loadSynchronously);
|
|
void loadRAMBundle(
|
|
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
std::unique_ptr<const JSBigString> startupScript,
|
|
std::string startupScriptSourceURL,
|
|
bool loadSynchronously);
|
|
bool supportsProfiling();
|
|
void setGlobalVariable(
|
|
std::string propName,
|
|
std::unique_ptr<const JSBigString> jsonValue);
|
|
void* getJavaScriptContext();
|
|
bool isInspectable();
|
|
bool isBatchActive();
|
|
void callJSFunction(
|
|
std::string&& module,
|
|
std::string&& method,
|
|
folly::dynamic&& params);
|
|
void callJSCallback(uint64_t callbackId, folly::dynamic&& params);
|
|
void registerBundle(uint32_t bundleId, const std::string& bundlePath);
|
|
const ModuleRegistry& getModuleRegistry() const;
|
|
ModuleRegistry& getModuleRegistry();
|
|
void handleMemoryPressure(int pressureLevel);
|
|
std::shared_ptr<CallInvoker> getJSCallInvoker();
|
|
std::shared_ptr<NativeMethodCallInvoker> getDecoratedNativeMethodCallInvoker(
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeInvoker);
|
|
RuntimeExecutor getRuntimeExecutor();
|
|
void unregisterFromInspector();
|
|
public:
|
|
void setNativeToJsBridgeAndFlushCalls(
|
|
std::weak_ptr<NativeToJsBridge> nativeToJsBridge);
|
|
void invokeAsync(CallFunc&& work) noexcept override;
|
|
void invokeSync(CallFunc&& work) override;
|
|
};
|
|
std::shared_ptr<JSCallInvoker> jsCallInvoker_ =
|
|
std::make_shared<JSCallInvoker>();
|
|
jsinspector_modern::HostTarget* parentInspectorTarget_{nullptr};
|
|
jsinspector_modern::InstanceTarget* inspectorTarget_{nullptr};
|
|
jsinspector_modern::RuntimeTarget* runtimeInspectorTarget_{nullptr};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JSBigString.h}:
|
|
namespace facebook::react {
|
|
class JSBigString {
|
|
public:
|
|
JSBigString() = default;
|
|
JSBigString(const JSBigString&) = delete;
|
|
JSBigString& operator=(const JSBigString&) = delete;
|
|
virtual ~JSBigString() = default;
|
|
virtual bool isAscii() const = 0;
|
|
virtual const char* c_str() const = 0;
|
|
virtual size_t size() const = 0;
|
|
};
|
|
class JSBigStdString : public JSBigString {
|
|
public:
|
|
JSBigStdString(std::string str, bool isAscii = false)
|
|
: m_isAscii(isAscii), m_str(std::move(str)) {}
|
|
bool isAscii() const override {
|
|
return m_isAscii;
|
|
}
|
|
const char* c_str() const override {
|
|
return m_str.c_str();
|
|
}
|
|
size_t size() const override {
|
|
return m_str.size();
|
|
}
|
|
};
|
|
class __attribute__((visibility("default"))) JSBigBufferString
|
|
: public JSBigString {
|
|
public:
|
|
JSBigBufferString(size_t size) : m_data(new char[size + 1]), m_size(size) {
|
|
m_data[m_size] = '\0';
|
|
}
|
|
~JSBigBufferString() override {
|
|
delete[] m_data;
|
|
}
|
|
bool isAscii() const override {
|
|
return true;
|
|
}
|
|
const char* c_str() const override {
|
|
return m_data;
|
|
}
|
|
size_t size() const override {
|
|
return m_size;
|
|
}
|
|
char* data() {
|
|
return m_data;
|
|
}
|
|
};
|
|
class __attribute__((visibility("default"))) JSBigFileString
|
|
: public JSBigString {
|
|
public:
|
|
JSBigFileString(int fd, size_t size, off_t offset = 0);
|
|
~JSBigFileString() override;
|
|
bool isAscii() const override {
|
|
return true;
|
|
}
|
|
const char* c_str() const override;
|
|
size_t size() const override;
|
|
int fd() const;
|
|
static std::unique_ptr<const JSBigFileString> fromPath(
|
|
const std::string& sourceURL);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JSBundleType.h}:
|
|
namespace facebook::react {
|
|
enum struct ScriptTag {
|
|
String = 0,
|
|
RAMBundle,
|
|
};
|
|
FOLLY_PACK_PUSH
|
|
struct FOLLY_PACK_ATTR Magic32 {
|
|
uint32_t value;
|
|
uint32_t reserved_;
|
|
};
|
|
struct FOLLY_PACK_ATTR BundleHeader {
|
|
BundleHeader() {
|
|
std::memset(this, 0, sizeof(BundleHeader));
|
|
}
|
|
union {
|
|
Magic32 magic32;
|
|
uint64_t magic64;
|
|
};
|
|
uint32_t version;
|
|
};
|
|
FOLLY_PACK_POP
|
|
__attribute__((visibility("default"))) ScriptTag
|
|
parseTypeFromHeader(const BundleHeader& header);
|
|
__attribute__((visibility("default"))) const char* stringForScriptTag(
|
|
const ScriptTag& tag);
|
|
__attribute__((visibility("default"))) bool isHermesBytecodeBundle(
|
|
const BundleHeader& header);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JSExecutor.h}:
|
|
namespace facebook::react {
|
|
class ExecutorDelegate {
|
|
public:
|
|
virtual ~ExecutorDelegate() = default;
|
|
virtual std::shared_ptr<ModuleRegistry> getModuleRegistry() = 0;
|
|
virtual void callNativeModules(
|
|
JSExecutor& executor,
|
|
folly::dynamic&& calls,
|
|
bool isEndOfBatch) = 0;
|
|
virtual MethodCallResult callSerializableNativeHook(
|
|
JSExecutor& executor,
|
|
unsigned int moduleId,
|
|
unsigned int methodId,
|
|
folly::dynamic&& args) = 0;
|
|
};
|
|
class JSExecutorFactory {
|
|
public:
|
|
virtual std::unique_ptr<JSExecutor> createJSExecutor(
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
std::shared_ptr<MessageQueueThread> jsQueue) = 0;
|
|
virtual ~JSExecutorFactory() = default;
|
|
};
|
|
class __attribute__((visibility("default"))) JSExecutor {
|
|
public:
|
|
virtual void initializeRuntime() = 0;
|
|
virtual void loadBundle(
|
|
std::unique_ptr<const JSBigString> script,
|
|
std::string sourceURL) = 0;
|
|
virtual void setBundleRegistry(
|
|
std::unique_ptr<RAMBundleRegistry> bundleRegistry) = 0;
|
|
virtual void registerBundle(
|
|
uint32_t bundleId,
|
|
const std::string& bundlePath) = 0;
|
|
virtual void callFunction(
|
|
const std::string& moduleId,
|
|
const std::string& methodId,
|
|
const folly::dynamic& arguments) = 0;
|
|
virtual void invokeCallback(
|
|
const double callbackId,
|
|
const folly::dynamic& arguments) = 0;
|
|
virtual void setGlobalVariable(
|
|
std::string propName,
|
|
std::unique_ptr<const JSBigString> jsonValue) = 0;
|
|
virtual void* getJavaScriptContext() {
|
|
return nullptr;
|
|
}
|
|
virtual bool isInspectable() {
|
|
return false;
|
|
}
|
|
virtual std::string getDescription() = 0;
|
|
virtual void handleMemoryPressure([[maybe_unused]] int pressureLevel) {}
|
|
virtual void destroy() {}
|
|
virtual ~JSExecutor() = default;
|
|
virtual void flush() {}
|
|
static std::string getSyntheticBundlePath(
|
|
uint32_t bundleId,
|
|
const std::string& bundlePath);
|
|
virtual jsinspector_modern::RuntimeTargetDelegate& getRuntimeTargetDelegate();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JSIndexedRAMBundle.h}:
|
|
namespace facebook::react {
|
|
class __attribute__((visibility("default"))) JSIndexedRAMBundle
|
|
: public JSModulesUnbundle {
|
|
public:
|
|
static std::function<std::unique_ptr<JSModulesUnbundle>(std::string)>
|
|
buildFactory();
|
|
JSIndexedRAMBundle(const char* sourceURL);
|
|
JSIndexedRAMBundle(std::unique_ptr<const JSBigString> script);
|
|
std::unique_ptr<const JSBigString> getStartupCode();
|
|
Module getModule(uint32_t moduleId) const override;
|
|
};
|
|
static_assert(
|
|
sizeof(ModuleData) == 8,
|
|
"ModuleData must not have any padding and use sizes matching input files");
|
|
struct ModuleTable {
|
|
size_t numEntries;
|
|
std::unique_ptr<ModuleData[]> data;
|
|
ModuleTable() : numEntries(0) {};
|
|
ModuleTable(size_t entries)
|
|
: numEntries(entries),
|
|
data(std::unique_ptr<ModuleData[]>(new ModuleData[numEntries])) {};
|
|
size_t byteLength() const {
|
|
return numEntries * sizeof(ModuleData);
|
|
}
|
|
};
|
|
void init();
|
|
std::string getModuleCode(const uint32_t id) const;
|
|
void readBundle(char* buffer, const std::streamsize bytes) const;
|
|
void readBundle(
|
|
char* buffer,
|
|
const std::streamsize bytes,
|
|
const std::istream::pos_type position) const;
|
|
mutable std::unique_ptr<std::istream> m_bundle;
|
|
ModuleTable m_table;
|
|
size_t m_baseOffset;
|
|
std::unique_ptr<JSBigBufferString> m_startupCode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JSModulesUnbundle.h}:
|
|
namespace facebook::react {
|
|
class JSModulesUnbundle {
|
|
public:
|
|
class ModuleNotFound : public std::out_of_range {
|
|
public:
|
|
using std::out_of_range::out_of_range;
|
|
explicit ModuleNotFound(uint32_t moduleId)
|
|
: std::out_of_range::out_of_range(
|
|
"Module not found: " + std::to_string(moduleId)) {}
|
|
};
|
|
struct Module {
|
|
std::string name;
|
|
std::string code;
|
|
};
|
|
JSModulesUnbundle() {}
|
|
virtual ~JSModulesUnbundle() = default;
|
|
virtual Module getModule(uint32_t moduleId) const = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JsArgumentHelpers-inl.h}:
|
|
namespace facebook {
|
|
namespace xplat {
|
|
namespace detail {
|
|
inline std::string toStringHelper() {
|
|
return "";
|
|
}
|
|
template <typename T, typename... Rest>
|
|
inline std::string toStringHelper(const T& value, const Rest&... rest) {
|
|
return std::to_string(value) + toStringHelper(rest...);
|
|
}
|
|
template <typename... Rest>
|
|
inline std::string toStringHelper(const char* value, const Rest&... rest) {
|
|
return std::string(value) + toStringHelper(rest...);
|
|
}
|
|
template <typename R, typename M, typename... T>
|
|
R jsArg1(const folly::dynamic& arg, M asFoo, const T&... desc) {
|
|
try {
|
|
return (arg.*asFoo)();
|
|
} catch (const folly::TypeError& ex) {
|
|
throw JsArgumentException(
|
|
"Error converting JavaScript arg " + toStringHelper(desc...) +
|
|
" to C++: " + ex.what());
|
|
} catch (const std::range_error& ex) {
|
|
throw JsArgumentException(
|
|
"Could not convert argument " + toStringHelper(desc...) +
|
|
" to required type: " + ex.what());
|
|
}
|
|
}
|
|
} // namespace detail
|
|
template <typename R, typename... T>
|
|
R jsArg(
|
|
const folly::dynamic& arg,
|
|
R (folly::dynamic::*asFoo)() const,
|
|
const T&... desc) {
|
|
return detail::jsArg1<R>(arg, asFoo, desc...);
|
|
}
|
|
template <typename R, typename... T>
|
|
R jsArg(
|
|
const folly::dynamic& arg,
|
|
R (folly::dynamic::*asFoo)() const&,
|
|
const T&... desc) {
|
|
return detail::jsArg1<R>(arg, asFoo, desc...);
|
|
}
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsDynamic(T&& args, size_t n) {
|
|
try {
|
|
return args[n];
|
|
} catch (const std::out_of_range& ex) {
|
|
throw JsArgumentException(
|
|
"JavaScript provided " + std::to_string(args.size()) +
|
|
" arguments for C++ method which references at least " +
|
|
std::to_string(n + 1) + " arguments: " + ex.what());
|
|
}
|
|
}
|
|
template <typename R>
|
|
R jsArgN(
|
|
const folly::dynamic& args,
|
|
size_t n,
|
|
R (folly::dynamic::*asFoo)() const) {
|
|
return jsArg(jsArgAsDynamic(args, n), asFoo, n);
|
|
}
|
|
template <typename R>
|
|
R jsArgN(
|
|
const folly::dynamic& args,
|
|
size_t n,
|
|
R (folly::dynamic::*asFoo)() const&) {
|
|
return jsArg(jsArgAsDynamic(args, n), asFoo, n);
|
|
}
|
|
namespace detail {
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsType(
|
|
T&& args,
|
|
size_t n,
|
|
const char* required,
|
|
bool (folly::dynamic::*isFoo)() const) {
|
|
T& ret = jsArgAsDynamic(args, n);
|
|
if ((ret.*isFoo)()) {
|
|
return ret;
|
|
}
|
|
throw JsArgumentException(
|
|
"Argument " + std::to_string(n + 1) + " of type " + ret.typeName() +
|
|
" is not required type " + required);
|
|
}
|
|
} // namespace detail
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsArray(T&& args, size_t n) {
|
|
return detail::jsArgAsType(args, n, "Array", &folly::dynamic::isArray);
|
|
}
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsObject(T&& args, size_t n) {
|
|
return detail::jsArgAsType(args, n, "Object", &folly::dynamic::isObject);
|
|
}
|
|
} // namespace xplat
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/JsArgumentHelpers.h}:
|
|
namespace facebook::xplat {
|
|
class JsArgumentException : public std::logic_error {
|
|
public:
|
|
JsArgumentException(const std::string& msg) : std::logic_error(msg) {}
|
|
};
|
|
template <typename R, typename... T>
|
|
R jsArg(
|
|
const folly::dynamic& arg,
|
|
R (folly::dynamic::*asFoo)() const,
|
|
const T&... desc);
|
|
template <typename R, typename... T>
|
|
R jsArg(
|
|
const folly::dynamic& arg,
|
|
R (folly::dynamic::*asFoo)() const&,
|
|
const T&... desc);
|
|
template <typename R>
|
|
R jsArgN(
|
|
const folly::dynamic& args,
|
|
size_t n,
|
|
R (folly::dynamic::*asFoo)() const);
|
|
template <typename R>
|
|
R jsArgN(
|
|
const folly::dynamic& args,
|
|
size_t n,
|
|
R (folly::dynamic::*asFoo)() const&);
|
|
namespace detail {
|
|
template <typename T>
|
|
struct is_dynamic {
|
|
using type = typename std::
|
|
enable_if<std::is_assignable<folly::dynamic, T>::value, T>::type;
|
|
};
|
|
} // namespace detail
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsDynamic(T&& args, size_t n);
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsArray(T&& args, size_t n);
|
|
template <typename T>
|
|
typename detail::is_dynamic<T>::type& jsArgAsObject(T&& args, size_t n);
|
|
inline bool jsArgAsBool(const folly::dynamic& args, size_t n) {
|
|
return jsArgN(args, n, &folly::dynamic::asBool);
|
|
}
|
|
inline int64_t jsArgAsInt(const folly::dynamic& args, size_t n) {
|
|
return jsArgN(args, n, &folly::dynamic::asInt);
|
|
}
|
|
inline double jsArgAsDouble(const folly::dynamic& args, size_t n) {
|
|
return jsArgN(args, n, &folly::dynamic::asDouble);
|
|
}
|
|
inline std::string jsArgAsString(const folly::dynamic& args, size_t n) {
|
|
return jsArgN(args, n, &folly::dynamic::asString);
|
|
}
|
|
} // namespace facebook::xplat
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/MessageQueueThread.h}:
|
|
namespace facebook::react {
|
|
class MessageQueueThread {
|
|
public:
|
|
virtual ~MessageQueueThread() = default;
|
|
virtual void runOnQueue(std::function<void()>&&) = 0;
|
|
virtual void runOnQueueSync(std::function<void()>&&) = 0;
|
|
virtual void quitSynchronous() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/MethodCall.h}:
|
|
namespace facebook::react {
|
|
struct MethodCall {
|
|
int moduleId;
|
|
int methodId;
|
|
folly::dynamic arguments;
|
|
int callId;
|
|
MethodCall(int mod, int meth, folly::dynamic&& args, int cid)
|
|
: moduleId(mod),
|
|
methodId(meth),
|
|
arguments(std::move(args)),
|
|
callId(cid) {}
|
|
};
|
|
std::vector<MethodCall> parseMethodCalls(folly::dynamic&& calls);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/ModuleRegistry.h}:
|
|
namespace facebook::react {
|
|
struct ModuleConfig {
|
|
size_t index;
|
|
folly::dynamic config;
|
|
};
|
|
class __attribute__((visibility("default"))) ModuleRegistry {
|
|
public:
|
|
using ModuleNotFoundCallback = std::function<bool(const std::string& name)>;
|
|
ModuleRegistry(
|
|
std::vector<std::unique_ptr<NativeModule>> modules,
|
|
ModuleNotFoundCallback callback = nullptr);
|
|
void registerModules(std::vector<std::unique_ptr<NativeModule>> modules);
|
|
std::vector<std::string> moduleNames();
|
|
std::optional<ModuleConfig> getConfig(const std::string& name);
|
|
void callNativeMethod(
|
|
unsigned int moduleId,
|
|
unsigned int methodId,
|
|
folly::dynamic&& params,
|
|
int callId);
|
|
MethodCallResult callSerializableNativeHook(
|
|
unsigned int moduleId,
|
|
unsigned int methodId,
|
|
folly::dynamic&& args);
|
|
std::string getModuleName(unsigned int moduleId);
|
|
std::string getModuleSyncMethodName(
|
|
unsigned int moduleId,
|
|
unsigned int methodName);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/MoveWrapper.h}:
|
|
namespace facebook::react {
|
|
template <class T>
|
|
class MoveWrapper {
|
|
public:
|
|
MoveWrapper() = default;
|
|
explicit MoveWrapper(T&& t) : value(std::move(t)) {}
|
|
MoveWrapper(const MoveWrapper& other) : value(std::move(other.value)) {}
|
|
MoveWrapper(MoveWrapper&& other) noexcept : value(std::move(other.value)) {}
|
|
const T& operator*() const {
|
|
return value;
|
|
}
|
|
T& operator*() {
|
|
return value;
|
|
}
|
|
const T* operator->() const {
|
|
return &value;
|
|
}
|
|
T* operator->() {
|
|
return &value;
|
|
}
|
|
T&& move() {
|
|
return std::move(value);
|
|
}
|
|
MoveWrapper& operator=(const MoveWrapper&) = delete;
|
|
MoveWrapper& operator=(MoveWrapper&&) = delete;
|
|
};
|
|
template <class T, class T0 = typename std::remove_reference<T>::type>
|
|
MoveWrapper<T0> makeMoveWrapper(T&& t) {
|
|
return MoveWrapper<T0>(std::forward<T0>(t));
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/NativeModule.h}:
|
|
namespace facebook::react {
|
|
struct MethodDescriptor {
|
|
std::string name;
|
|
std::string type;
|
|
MethodDescriptor(std::string n, std::string t)
|
|
: name(std::move(n)), type(std::move(t)) {}
|
|
};
|
|
using MethodCallResult = std::optional<folly::dynamic>;
|
|
class NativeModule {
|
|
public:
|
|
virtual ~NativeModule() = default;
|
|
virtual std::string getName() = 0;
|
|
virtual std::string getSyncMethodName(unsigned int methodId) = 0;
|
|
virtual std::vector<MethodDescriptor> getMethods() = 0;
|
|
virtual folly::dynamic getConstants() = 0;
|
|
virtual void
|
|
invoke(unsigned int reactMethodId, folly::dynamic&& params, int callId) = 0;
|
|
virtual MethodCallResult callSerializableNativeHook(
|
|
unsigned int reactMethodId,
|
|
folly::dynamic&& args) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/NativeToJsBridge.h}:
|
|
namespace folly {
|
|
}
|
|
namespace facebook::react {
|
|
class NativeToJsBridge {
|
|
public:
|
|
friend
|
|
NativeToJsBridge(
|
|
JSExecutorFactory* jsExecutorFactory,
|
|
std::shared_ptr<ModuleRegistry> registry,
|
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
std::shared_ptr<InstanceCallback> callback);
|
|
virtual ~NativeToJsBridge();
|
|
void callFunction(
|
|
std::string&& module,
|
|
std::string&& method,
|
|
folly::dynamic&& args);
|
|
void invokeCallback(double callbackId, folly::dynamic&& args);
|
|
void initializeRuntime();
|
|
void loadBundle(
|
|
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
std::unique_ptr<const JSBigString> startupCode,
|
|
std::string sourceURL);
|
|
void loadBundleSync(
|
|
std::unique_ptr<RAMBundleRegistry> bundleRegistry,
|
|
std::unique_ptr<const JSBigString> startupCode,
|
|
std::string sourceURL);
|
|
void registerBundle(uint32_t bundleId, const std::string& bundlePath);
|
|
void setGlobalVariable(
|
|
std::string propName,
|
|
std::unique_ptr<const JSBigString> jsonValue);
|
|
void* getJavaScriptContext();
|
|
bool isInspectable();
|
|
bool isBatchActive();
|
|
void handleMemoryPressure(int pressureLevel);
|
|
void destroy();
|
|
void runOnExecutorQueue(std::function<void(JSExecutor*)>&& task) noexcept;
|
|
std::shared_ptr<NativeMethodCallInvoker> getDecoratedNativeMethodCallInvoker(
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeInvoker) const;
|
|
jsinspector_modern::RuntimeTargetDelegate& getInspectorTargetDelegate();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/RAMBundleRegistry.h}:
|
|
namespace facebook::react {
|
|
class __attribute__((visibility("default"))) RAMBundleRegistry {
|
|
public:
|
|
constexpr static uint32_t MAIN_BUNDLE_ID = 0;
|
|
static std::unique_ptr<RAMBundleRegistry> singleBundleRegistry(
|
|
std::unique_ptr<JSModulesUnbundle> mainBundle);
|
|
static std::unique_ptr<RAMBundleRegistry> multipleBundlesRegistry(
|
|
std::unique_ptr<JSModulesUnbundle> mainBundle,
|
|
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory);
|
|
explicit RAMBundleRegistry(
|
|
std::unique_ptr<JSModulesUnbundle> mainBundle,
|
|
std::function<std::unique_ptr<JSModulesUnbundle>(std::string)> factory =
|
|
nullptr);
|
|
RAMBundleRegistry(RAMBundleRegistry&&) = default;
|
|
RAMBundleRegistry& operator=(RAMBundleRegistry&&) = default;
|
|
void registerBundle(uint32_t bundleId, std::string bundlePath);
|
|
JSModulesUnbundle::Module getModule(uint32_t bundleId, uint32_t moduleId);
|
|
virtual ~RAMBundleRegistry() = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/ReactMarker.h}:
|
|
namespace facebook::react::ReactMarker {
|
|
enum ReactMarkerId {
|
|
APP_STARTUP_START,
|
|
APP_STARTUP_STOP,
|
|
INIT_REACT_RUNTIME_START,
|
|
INIT_REACT_RUNTIME_STOP,
|
|
NATIVE_REQUIRE_START,
|
|
NATIVE_REQUIRE_STOP,
|
|
RUN_JS_BUNDLE_START,
|
|
RUN_JS_BUNDLE_STOP,
|
|
CREATE_REACT_CONTEXT_STOP,
|
|
JS_BUNDLE_STRING_CONVERT_START,
|
|
JS_BUNDLE_STRING_CONVERT_STOP,
|
|
NATIVE_MODULE_SETUP_START,
|
|
NATIVE_MODULE_SETUP_STOP,
|
|
REGISTER_JS_SEGMENT_START,
|
|
REGISTER_JS_SEGMENT_STOP,
|
|
REACT_INSTANCE_INIT_START,
|
|
REACT_INSTANCE_INIT_STOP
|
|
};
|
|
typedef void (*LogTaggedMarker)(const ReactMarkerId, const char* tag);
|
|
typedef void (*LogTaggedMarkerBridgeless)(const ReactMarkerId, const char* tag);
|
|
extern __attribute__((
|
|
visibility("default"))) std::shared_mutex logTaggedMarkerImplMutex;
|
|
extern
|
|
__attribute__((visibility("default"))) LogTaggedMarker logTaggedMarkerImpl;
|
|
extern __attribute__((
|
|
visibility("default"))) LogTaggedMarker logTaggedMarkerBridgelessImpl;
|
|
extern __attribute__((visibility("default"))) void logMarker(
|
|
const ReactMarkerId markerId);
|
|
extern __attribute__((visibility("default"))) void logTaggedMarker(
|
|
const ReactMarkerId markerId,
|
|
const char* tag);
|
|
extern __attribute__((visibility("default"))) void logMarkerBridgeless(
|
|
const ReactMarkerId markerId);
|
|
extern __attribute__((visibility("default"))) void logTaggedMarkerBridgeless(
|
|
const ReactMarkerId markerId,
|
|
const char* tag);
|
|
struct ReactMarkerEvent {
|
|
const ReactMarkerId markerId;
|
|
const char* tag;
|
|
double time;
|
|
};
|
|
class __attribute__((visibility("default"))) StartupLogger {
|
|
public:
|
|
static StartupLogger& getInstance();
|
|
void logStartupEvent(const ReactMarkerId markerName, double markerTime);
|
|
void reset();
|
|
double getAppStartupStartTime();
|
|
double getInitReactRuntimeStartTime();
|
|
double getInitReactRuntimeEndTime();
|
|
double getRunJSBundleStartTime();
|
|
double getRunJSBundleEndTime();
|
|
double getAppStartupEndTime();
|
|
};
|
|
extern __attribute__((visibility("default"))) void logMarkerDone(
|
|
const ReactMarkerId markerId,
|
|
double markerTime);
|
|
} // namespace facebook::react::ReactMarker
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/ReactNativeVersion.h}:
|
|
namespace facebook::react {
|
|
constexpr struct {
|
|
int32_t Major = 1000;
|
|
int32_t Minor = 0;
|
|
int32_t Patch = 0;
|
|
std::string_view Prerelease = "";
|
|
} ReactNativeVersion;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/RecoverableError.h}:
|
|
namespace facebook::react {
|
|
struct RecoverableError : public std::exception {
|
|
explicit RecoverableError(const std::string& what_)
|
|
: m_what{"facebook::react::Recoverable: " + what_} {}
|
|
virtual const char* what() const noexcept override {
|
|
return m_what.c_str();
|
|
}
|
|
template <typename E>
|
|
inline static void runRethrowingAsRecoverable(std::function<void()> act) {
|
|
try {
|
|
act();
|
|
} catch (const E& err) {
|
|
throw RecoverableError(err.what());
|
|
}
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/SharedProxyCxxModule.h}:
|
|
namespace facebook::xplat::module {
|
|
class SharedProxyCxxModule : public CxxModule {
|
|
public:
|
|
explicit SharedProxyCxxModule(std::shared_ptr<CxxModule> shared)
|
|
: shared_(shared) {}
|
|
std::string getName() override {
|
|
return shared_->getName();
|
|
}
|
|
auto getConstants() -> std::map<std::string, folly::dynamic> override {
|
|
return shared_->getConstants();
|
|
}
|
|
auto getMethods() -> std::vector<Method> override {
|
|
return shared_->getMethods();
|
|
}
|
|
};
|
|
} // namespace facebook::xplat::module
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/SystraceSection.h}:
|
|
/// @dep {packages/react-native/ReactCommon/cxxreact/TraceSection.h}
|
|
namespace facebook::react {
|
|
struct [[deprecated("Use TraceSection")]] SystraceSection
|
|
: public TraceSectionUnwrapped {
|
|
template <typename... ConvertsToStringPiece>
|
|
explicit SystraceSection(const char* name, ConvertsToStringPiece&&... args)
|
|
: TraceSectionUnwrapped(name, args...) {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/cxxreact/TraceSection.h}:
|
|
namespace facebook::react {
|
|
struct DummyTraceSection {
|
|
public:
|
|
template <typename... ConvertsToStringPiece>
|
|
explicit DummyTraceSection(
|
|
const __unused char* name,
|
|
__unused ConvertsToStringPiece&&... args) {}
|
|
};
|
|
using TraceSectionUnwrapped = DummyTraceSection;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/devtoolsruntimesettings/DevToolsRuntimeSettings.h}:
|
|
namespace facebook::react {
|
|
using NativePartialReloadAndProfileConfig =
|
|
NativeReactDevToolsRuntimeSettingsModulePartialReloadAndProfileConfig<
|
|
std::optional<bool>,
|
|
std::optional<bool>>;
|
|
template <>
|
|
struct Bridging<NativePartialReloadAndProfileConfig>
|
|
: NativeReactDevToolsRuntimeSettingsModulePartialReloadAndProfileConfigBridging<
|
|
NativePartialReloadAndProfileConfig> {};
|
|
using NativeReloadAndProfileConfig =
|
|
NativeReactDevToolsRuntimeSettingsModuleReloadAndProfileConfig<bool, bool>;
|
|
template <>
|
|
struct Bridging<NativeReloadAndProfileConfig>
|
|
: NativeReactDevToolsRuntimeSettingsModuleReloadAndProfileConfigBridging<
|
|
NativeReloadAndProfileConfig> {};
|
|
class DevToolsRuntimeSettings {
|
|
public:
|
|
static DevToolsRuntimeSettings& getInstance() {
|
|
static DevToolsRuntimeSettings instance;
|
|
return instance;
|
|
}
|
|
public:
|
|
~DevToolsRuntimeSettings() = default;
|
|
DevToolsRuntimeSettings(const DevToolsRuntimeSettings&) = delete;
|
|
DevToolsRuntimeSettings(DevToolsRuntimeSettings&&) = delete;
|
|
void operator=(const DevToolsRuntimeSettings&) = delete;
|
|
void operator=(DevToolsRuntimeSettings&&) = delete;
|
|
void setReloadAndProfileConfig(NativePartialReloadAndProfileConfig config);
|
|
NativeReloadAndProfileConfig getReloadAndProfileConfig() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/hermes/executor/HermesExecutorFactory.h}:
|
|
namespace facebook::react {
|
|
class HermesExecutorFactory : public JSExecutorFactory {
|
|
public:
|
|
explicit HermesExecutorFactory(
|
|
JSIExecutor::RuntimeInstaller runtimeInstaller,
|
|
const JSIScopedTimeoutInvoker& timeoutInvoker =
|
|
JSIExecutor::defaultTimeoutInvoker,
|
|
::hermes::vm::RuntimeConfig runtimeConfig = defaultRuntimeConfig())
|
|
: runtimeInstaller_(runtimeInstaller),
|
|
timeoutInvoker_(timeoutInvoker),
|
|
runtimeConfig_(std::move(runtimeConfig)) {
|
|
assert(timeoutInvoker_ && "Should not have empty timeoutInvoker");
|
|
}
|
|
void setEnableDebugger(bool enableDebugger);
|
|
void setDebuggerName(const std::string& debuggerName);
|
|
std::unique_ptr<JSExecutor> createJSExecutor(
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
std::shared_ptr<MessageQueueThread> jsQueue) override;
|
|
};
|
|
class HermesExecutor : public JSIExecutor {
|
|
public:
|
|
HermesExecutor(
|
|
std::shared_ptr<jsi::Runtime> runtime,
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
std::shared_ptr<MessageQueueThread> jsQueue,
|
|
const JSIScopedTimeoutInvoker& timeoutInvoker,
|
|
RuntimeInstaller runtimeInstaller,
|
|
hermes::HermesRuntime& hermesRuntime);
|
|
jsinspector_modern::RuntimeTargetDelegate& getRuntimeTargetDelegate()
|
|
override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/hermes/inspector-modern/chrome/ConnectionDemux.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeAgentDelegate.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeSamplingProfileSerializer.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
class RawHermesRuntimeProfile : public RawRuntimeProfile {
|
|
public:
|
|
explicit RawHermesRuntimeProfile(
|
|
hermes::sampling_profiler::Profile hermesProfile)
|
|
: hermesProfile_{std::move(hermesProfile)} {}
|
|
};
|
|
class HermesRuntimeSamplingProfileSerializer {
|
|
public:
|
|
static tracing::RuntimeSamplingProfile serializeToTracingSamplingProfile(
|
|
hermes::sampling_profiler::Profile hermesProfile);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/hermes/inspector-modern/chrome/HermesRuntimeTargetDelegate.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class HermesRuntimeTargetDelegate : public RuntimeTargetDelegate {
|
|
public:
|
|
explicit HermesRuntimeTargetDelegate(
|
|
std::shared_ptr<hermes::HermesRuntime> hermesRuntime);
|
|
~HermesRuntimeTargetDelegate() override;
|
|
std::unique_ptr<jsinspector_modern::RuntimeAgentDelegate> createAgentDelegate(
|
|
jsinspector_modern::FrontendChannel frontendChannel,
|
|
jsinspector_modern::SessionState& sessionState,
|
|
std::unique_ptr<jsinspector_modern::RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const jsinspector_modern::ExecutionContextDescription&
|
|
executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) override;
|
|
void addConsoleMessage(jsi::Runtime& runtime, ConsoleMessage message)
|
|
override;
|
|
bool supportsConsole() const override;
|
|
std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip) override;
|
|
void enableSamplingProfiler() override;
|
|
void disableSamplingProfiler() override;
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile() override;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/hermes/inspector-modern/chrome/Registration.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsc/JSCRuntime.h}:
|
|
namespace facebook::jsc {
|
|
std::unique_ptr<jsi::Runtime> makeJSCRuntime();
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.h}:
|
|
namespace facebook::react {
|
|
class JsErrorHandler {
|
|
public:
|
|
struct ProcessedError {
|
|
struct StackFrame {
|
|
std::optional<std::string> file;
|
|
std::string methodName;
|
|
std::optional<int> lineNumber;
|
|
std::optional<int> column;
|
|
friend std::ostream& operator<<(
|
|
std::ostream& os,
|
|
const StackFrame& frame);
|
|
};
|
|
std::string message;
|
|
std::optional<std::string> originalMessage;
|
|
std::optional<std::string> name;
|
|
std::optional<std::string> componentStack;
|
|
std::vector<StackFrame> stack;
|
|
int id;
|
|
bool isFatal;
|
|
jsi::Object extraData;
|
|
friend std::ostream& operator<<(
|
|
std::ostream& os,
|
|
const ProcessedError& error);
|
|
};
|
|
using OnJsError =
|
|
std::function<void(jsi::Runtime& runtime, const ProcessedError& error)>;
|
|
explicit JsErrorHandler(OnJsError onJsError);
|
|
~JsErrorHandler();
|
|
void handleError(
|
|
jsi::Runtime& runtime,
|
|
jsi::JSError& error,
|
|
bool isFatal,
|
|
bool logToConsole = true);
|
|
bool hasHandledFatalError();
|
|
void registerErrorListener(
|
|
const std::function<void(jsi::Runtime&, jsi::Value)>& listener);
|
|
void setRuntimeReady();
|
|
bool isRuntimeReady();
|
|
void notifyOfFatalError();
|
|
bool inErrorHandler();
|
|
};
|
|
bool _isRuntimeReady{};
|
|
std::shared_ptr<bool> _inErrorHandler;
|
|
std::vector<std::function<void(jsi::Runtime&, jsi::Value)>> _errorListeners;
|
|
void handleErrorWithCppPipeline(
|
|
jsi::Runtime& runtime,
|
|
jsi::JSError& error,
|
|
bool isFatal,
|
|
bool logToConsole);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/jserrorhandler/StackTraceParser.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jserrorhandler/JsErrorHandler.h}
|
|
|
|
namespace facebook::react {
|
|
class StackTraceParser {
|
|
public:
|
|
static std::vector<JsErrorHandler::ProcessedError::StackFrame> parse(
|
|
bool isHermes,
|
|
const std::string& stackString);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/JSIDynamic.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
facebook::jsi::Value valueFromDynamic(
|
|
facebook::jsi::Runtime& runtime,
|
|
const folly::dynamic& dyn);
|
|
folly::dynamic dynamicFromValue(
|
|
facebook::jsi::Runtime& runtime,
|
|
const facebook::jsi::Value& value,
|
|
const std::function<bool(const std::string&)>& filterObjectKeys = nullptr);
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/decorator.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
class DecoratedHostFunction {
|
|
public:
|
|
DecoratedHostFunction(Runtime& drt, HostFunctionType plainHF)
|
|
: drt_(drt), plainHF_(std::move(plainHF)) {}
|
|
Runtime& decoratedRuntime() {
|
|
return drt_;
|
|
}
|
|
Value
|
|
operator()(Runtime&, const Value& thisVal, const Value* args, size_t count) {
|
|
return plainHF_(decoratedRuntime(), thisVal, args, count);
|
|
}
|
|
};
|
|
class DecoratedHostObject : public HostObject {
|
|
public:
|
|
DecoratedHostObject(Runtime& drt, std::shared_ptr<HostObject> plainHO)
|
|
: drt_(drt), plainHO_(plainHO) {}
|
|
Runtime& decoratedRuntime() {
|
|
return drt_;
|
|
}
|
|
Value get(Runtime&, const PropNameID& name) override {
|
|
return plainHO_->get(decoratedRuntime(), name);
|
|
}
|
|
void set(Runtime&, const PropNameID& name, const Value& value) override {
|
|
plainHO_->set(decoratedRuntime(), name, value);
|
|
}
|
|
std::vector<PropNameID> getPropertyNames(Runtime&) override {
|
|
return plainHO_->getPropertyNames(decoratedRuntime());
|
|
}
|
|
};
|
|
template <typename Plain = Runtime, typename Base = Runtime>
|
|
class RuntimeDecorator : public Base, private jsi::Instrumentation {
|
|
public:
|
|
Plain& plain() {
|
|
static_assert(
|
|
std::is_base_of<Runtime, Plain>::value,
|
|
"RuntimeDecorator's Plain type must derive from jsi::Runtime");
|
|
static_assert(
|
|
std::is_base_of<Runtime, Base>::value,
|
|
"RuntimeDecorator's Base type must derive from jsi::Runtime");
|
|
return plain_;
|
|
}
|
|
const Plain& plain() const {
|
|
return plain_;
|
|
}
|
|
ICast* castInterface(const UUID& interfaceUUID) override {
|
|
return plain().castInterface(interfaceUUID);
|
|
}
|
|
Value evaluateJavaScript(
|
|
const std::shared_ptr<const Buffer>& buffer,
|
|
const std::string& sourceURL) override {
|
|
return plain().evaluateJavaScript(buffer, sourceURL);
|
|
}
|
|
std::shared_ptr<const PreparedJavaScript> prepareJavaScript(
|
|
const std::shared_ptr<const Buffer>& buffer,
|
|
std::string sourceURL) override {
|
|
return plain().prepareJavaScript(buffer, std::move(sourceURL));
|
|
}
|
|
Value evaluatePreparedJavaScript(
|
|
const std::shared_ptr<const PreparedJavaScript>& js) override {
|
|
return plain().evaluatePreparedJavaScript(js);
|
|
}
|
|
void queueMicrotask(const jsi::Function& callback) override {
|
|
return plain().queueMicrotask(callback);
|
|
}
|
|
bool drainMicrotasks(int maxMicrotasksHint) override {
|
|
return plain().drainMicrotasks(maxMicrotasksHint);
|
|
}
|
|
Object global() override {
|
|
return plain().global();
|
|
}
|
|
std::string description() override {
|
|
return plain().description();
|
|
};
|
|
bool isInspectable() override {
|
|
return plain().isInspectable();
|
|
};
|
|
Instrumentation& instrumentation() override {
|
|
return *this;
|
|
}
|
|
|
|
protected:
|
|
RuntimeDecorator(Plain& plain) : plain_(plain) {}
|
|
Runtime::PointerValue* cloneSymbol(const Runtime::PointerValue* pv) override {
|
|
return plain_.cloneSymbol(pv);
|
|
};
|
|
Runtime::PointerValue* cloneBigInt(const Runtime::PointerValue* pv) override {
|
|
return plain_.cloneBigInt(pv);
|
|
};
|
|
Runtime::PointerValue* cloneString(const Runtime::PointerValue* pv) override {
|
|
return plain_.cloneString(pv);
|
|
};
|
|
Runtime::PointerValue* cloneObject(const Runtime::PointerValue* pv) override {
|
|
return plain_.cloneObject(pv);
|
|
};
|
|
Runtime::PointerValue* clonePropNameID(
|
|
const Runtime::PointerValue* pv) override {
|
|
return plain_.clonePropNameID(pv);
|
|
};
|
|
PropNameID createPropNameIDFromAscii(const char* str, size_t length)
|
|
override {
|
|
return plain_.createPropNameIDFromAscii(str, length);
|
|
};
|
|
PropNameID createPropNameIDFromUtf8(const uint8_t* utf8, size_t length)
|
|
override {
|
|
return plain_.createPropNameIDFromUtf8(utf8, length);
|
|
};
|
|
PropNameID createPropNameIDFromString(const String& str) override {
|
|
return plain_.createPropNameIDFromString(str);
|
|
};
|
|
PropNameID createPropNameIDFromUtf16(const char16_t* utf16, size_t length)
|
|
override {
|
|
return plain_.createPropNameIDFromUtf16(utf16, length);
|
|
}
|
|
PropNameID createPropNameIDFromSymbol(const Symbol& sym) override {
|
|
return plain_.createPropNameIDFromSymbol(sym);
|
|
};
|
|
std::string utf8(const PropNameID& id) override {
|
|
return plain_.utf8(id);
|
|
};
|
|
bool compare(const PropNameID& a, const PropNameID& b) override {
|
|
return plain_.compare(a, b);
|
|
};
|
|
std::string symbolToString(const Symbol& sym) override {
|
|
return plain_.symbolToString(sym);
|
|
}
|
|
BigInt createBigIntFromInt64(int64_t value) override {
|
|
return plain_.createBigIntFromInt64(value);
|
|
}
|
|
BigInt createBigIntFromUint64(uint64_t value) override {
|
|
return plain_.createBigIntFromUint64(value);
|
|
}
|
|
bool bigintIsInt64(const BigInt& b) override {
|
|
return plain_.bigintIsInt64(b);
|
|
}
|
|
bool bigintIsUint64(const BigInt& b) override {
|
|
return plain_.bigintIsUint64(b);
|
|
}
|
|
uint64_t truncate(const BigInt& b) override {
|
|
return plain_.truncate(b);
|
|
}
|
|
String bigintToString(const BigInt& bigint, int radix) override {
|
|
return plain_.bigintToString(bigint, radix);
|
|
}
|
|
String createStringFromAscii(const char* str, size_t length) override {
|
|
return plain_.createStringFromAscii(str, length);
|
|
};
|
|
String createStringFromUtf8(const uint8_t* utf8, size_t length) override {
|
|
return plain_.createStringFromUtf8(utf8, length);
|
|
};
|
|
String createStringFromUtf16(const char16_t* utf16, size_t length) override {
|
|
return plain_.createStringFromUtf16(utf16, length);
|
|
}
|
|
std::string utf8(const String& s) override {
|
|
return plain_.utf8(s);
|
|
}
|
|
std::u16string utf16(const String& str) override {
|
|
return plain_.utf16(str);
|
|
}
|
|
std::u16string utf16(const PropNameID& sym) override {
|
|
return plain_.utf16(sym);
|
|
}
|
|
void getStringData(
|
|
const jsi::String& str,
|
|
void* ctx,
|
|
void (
|
|
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
|
|
plain_.getStringData(str, ctx, cb);
|
|
}
|
|
void getPropNameIdData(
|
|
const jsi::PropNameID& sym,
|
|
void* ctx,
|
|
void (
|
|
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
|
|
plain_.getPropNameIdData(sym, ctx, cb);
|
|
}
|
|
Object createObjectWithPrototype(const Value& prototype) override {
|
|
return plain_.createObjectWithPrototype(prototype);
|
|
}
|
|
Object createObject() override {
|
|
return plain_.createObject();
|
|
};
|
|
Object createObject(std::shared_ptr<HostObject> ho) override {
|
|
return plain_.createObject(
|
|
std::make_shared<DecoratedHostObject>(*this, std::move(ho)));
|
|
};
|
|
std::shared_ptr<HostObject> getHostObject(const jsi::Object& o) override {
|
|
std::shared_ptr<HostObject> dho = plain_.getHostObject(o);
|
|
return static_cast<DecoratedHostObject&>(*dho).plainHO_;
|
|
};
|
|
HostFunctionType& getHostFunction(const jsi::Function& f) override {
|
|
HostFunctionType& dhf = plain_.getHostFunction(f);
|
|
return dhf.target<DecoratedHostFunction>()->plainHF_;
|
|
};
|
|
bool hasNativeState(const Object& o) override {
|
|
return plain_.hasNativeState(o);
|
|
}
|
|
std::shared_ptr<NativeState> getNativeState(const Object& o) override {
|
|
return plain_.getNativeState(o);
|
|
}
|
|
void setNativeState(const Object& o, std::shared_ptr<NativeState> state)
|
|
override {
|
|
plain_.setNativeState(o, state);
|
|
}
|
|
void setExternalMemoryPressure(const Object& obj, size_t amt) override {
|
|
plain_.setExternalMemoryPressure(obj, amt);
|
|
}
|
|
void setPrototypeOf(const Object& object, const Value& prototype) override {
|
|
plain_.setPrototypeOf(object, prototype);
|
|
}
|
|
Value getPrototypeOf(const Object& object) override {
|
|
return plain_.getPrototypeOf(object);
|
|
}
|
|
Value getProperty(const Object& o, const PropNameID& name) override {
|
|
return plain_.getProperty(o, name);
|
|
};
|
|
Value getProperty(const Object& o, const String& name) override {
|
|
return plain_.getProperty(o, name);
|
|
};
|
|
bool hasProperty(const Object& o, const PropNameID& name) override {
|
|
return plain_.hasProperty(o, name);
|
|
};
|
|
bool hasProperty(const Object& o, const String& name) override {
|
|
return plain_.hasProperty(o, name);
|
|
};
|
|
void setPropertyValue(
|
|
const Object& o,
|
|
const PropNameID& name,
|
|
const Value& value) override {
|
|
plain_.setPropertyValue(o, name, value);
|
|
};
|
|
void setPropertyValue(const Object& o, const String& name, const Value& value)
|
|
override {
|
|
plain_.setPropertyValue(o, name, value);
|
|
};
|
|
bool isArray(const Object& o) const override {
|
|
return plain_.isArray(o);
|
|
};
|
|
bool isArrayBuffer(const Object& o) const override {
|
|
return plain_.isArrayBuffer(o);
|
|
};
|
|
bool isFunction(const Object& o) const override {
|
|
return plain_.isFunction(o);
|
|
};
|
|
bool isHostObject(const jsi::Object& o) const override {
|
|
return plain_.isHostObject(o);
|
|
};
|
|
bool isHostFunction(const jsi::Function& f) const override {
|
|
return plain_.isHostFunction(f);
|
|
};
|
|
Array getPropertyNames(const Object& o) override {
|
|
return plain_.getPropertyNames(o);
|
|
};
|
|
WeakObject createWeakObject(const Object& o) override {
|
|
return plain_.createWeakObject(o);
|
|
};
|
|
Value lockWeakObject(const WeakObject& wo) override {
|
|
return plain_.lockWeakObject(wo);
|
|
};
|
|
Array createArray(size_t length) override {
|
|
return plain_.createArray(length);
|
|
};
|
|
ArrayBuffer createArrayBuffer(
|
|
std::shared_ptr<MutableBuffer> buffer) override {
|
|
return plain_.createArrayBuffer(std::move(buffer));
|
|
};
|
|
size_t size(const Array& a) override {
|
|
return plain_.size(a);
|
|
};
|
|
size_t size(const ArrayBuffer& ab) override {
|
|
return plain_.size(ab);
|
|
};
|
|
uint8_t* data(const ArrayBuffer& ab) override {
|
|
return plain_.data(ab);
|
|
};
|
|
Value getValueAtIndex(const Array& a, size_t i) override {
|
|
return plain_.getValueAtIndex(a, i);
|
|
};
|
|
void setValueAtIndexImpl(const Array& a, size_t i, const Value& value)
|
|
override {
|
|
plain_.setValueAtIndexImpl(a, i, value);
|
|
};
|
|
Function createFunctionFromHostFunction(
|
|
const PropNameID& name,
|
|
unsigned int paramCount,
|
|
HostFunctionType func) override {
|
|
return plain_.createFunctionFromHostFunction(
|
|
name, paramCount, DecoratedHostFunction(*this, std::move(func)));
|
|
};
|
|
Value call(
|
|
const Function& f,
|
|
const Value& jsThis,
|
|
const Value* args,
|
|
size_t count) override {
|
|
return plain_.call(f, jsThis, args, count);
|
|
};
|
|
Value callAsConstructor(const Function& f, const Value* args, size_t count)
|
|
override {
|
|
return plain_.callAsConstructor(f, args, count);
|
|
};
|
|
void setRuntimeDataImpl(
|
|
const UUID& uuid,
|
|
const void* data,
|
|
void (*deleter)(const void* data)) override {
|
|
return plain_.setRuntimeDataImpl(uuid, data, deleter);
|
|
}
|
|
const void* getRuntimeDataImpl(const UUID& uuid) override {
|
|
return plain_.getRuntimeDataImpl(uuid);
|
|
}
|
|
Runtime::ScopeState* pushScope() override {
|
|
return plain_.pushScope();
|
|
}
|
|
void popScope(Runtime::ScopeState* ss) override {
|
|
plain_.popScope(ss);
|
|
}
|
|
bool strictEquals(const Symbol& a, const Symbol& b) const override {
|
|
return plain_.strictEquals(a, b);
|
|
};
|
|
bool strictEquals(const BigInt& a, const BigInt& b) const override {
|
|
return plain_.strictEquals(a, b);
|
|
};
|
|
bool strictEquals(const String& a, const String& b) const override {
|
|
return plain_.strictEquals(a, b);
|
|
};
|
|
bool strictEquals(const Object& a, const Object& b) const override {
|
|
return plain_.strictEquals(a, b);
|
|
};
|
|
bool instanceOf(const Object& o, const Function& f) override {
|
|
return plain_.instanceOf(o, f);
|
|
};
|
|
std::string getRecordedGCStats() override {
|
|
return plain().instrumentation().getRecordedGCStats();
|
|
}
|
|
std::unordered_map<std::string, int64_t> getHeapInfo(
|
|
bool includeExpensive) override {
|
|
return plain().instrumentation().getHeapInfo(includeExpensive);
|
|
}
|
|
void collectGarbage(std::string cause) override {
|
|
plain().instrumentation().collectGarbage(std::move(cause));
|
|
}
|
|
void startTrackingHeapObjectStackTraces(
|
|
std::function<void(
|
|
uint64_t,
|
|
std::chrono::microseconds,
|
|
std::vector<HeapStatsUpdate>)> callback) override {
|
|
plain().instrumentation().startTrackingHeapObjectStackTraces(
|
|
std::move(callback));
|
|
}
|
|
void stopTrackingHeapObjectStackTraces() override {
|
|
plain().instrumentation().stopTrackingHeapObjectStackTraces();
|
|
}
|
|
void startHeapSampling(size_t samplingInterval) override {
|
|
plain().instrumentation().startHeapSampling(samplingInterval);
|
|
}
|
|
void stopHeapSampling(std::ostream& os) override {
|
|
plain().instrumentation().stopHeapSampling(os);
|
|
}
|
|
void createSnapshotToFile(
|
|
const std::string& path,
|
|
const HeapSnapshotOptions& options) override {
|
|
plain().instrumentation().createSnapshotToFile(path, options);
|
|
}
|
|
void createSnapshotToStream(
|
|
std::ostream& os,
|
|
const HeapSnapshotOptions& options) override {
|
|
plain().instrumentation().createSnapshotToStream(os, options);
|
|
}
|
|
std::string flushAndDisableBridgeTrafficTrace() override {
|
|
return const_cast<Plain&>(plain())
|
|
.instrumentation()
|
|
.flushAndDisableBridgeTrafficTrace();
|
|
}
|
|
void writeBasicBlockProfileTraceToFile(
|
|
const std::string& fileName) const override {
|
|
const_cast<Plain&>(plain())
|
|
.instrumentation()
|
|
.writeBasicBlockProfileTraceToFile(fileName);
|
|
}
|
|
void dumpProfilerSymbolsToFile(const std::string& fileName) const override {
|
|
const_cast<Plain&>(plain()).instrumentation().dumpProfilerSymbolsToFile(
|
|
fileName);
|
|
}
|
|
};
|
|
namespace detail {
|
|
template <typename T, typename U = void>
|
|
struct BeforeCaller {
|
|
static void before(T&) {}
|
|
};
|
|
template <typename T, typename U = void>
|
|
struct AfterCaller {
|
|
static void after(T&) {}
|
|
};
|
|
template <typename T>
|
|
struct BeforeCaller<T, decltype((void)&T::before)> {
|
|
static void before(T& t) {
|
|
t.before();
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct AfterCaller<T, decltype((void)&T::after)> {
|
|
static void after(T& t) {
|
|
t.after();
|
|
}
|
|
};
|
|
template <typename... T>
|
|
struct BeforeCaller<std::tuple<T...>> {
|
|
static void before(std::tuple<T...>& tuple) {
|
|
all_before<0, T...>(tuple);
|
|
}
|
|
};
|
|
template <typename... T>
|
|
struct AfterCaller<std::tuple<T...>> {
|
|
static void after(std::tuple<T...>& tuple) {
|
|
all_after<0, T...>(tuple);
|
|
}
|
|
};
|
|
} // namespace detail
|
|
template <typename With, typename Plain = Runtime, typename Base = Runtime>
|
|
class WithRuntimeDecorator : public RuntimeDecorator<Plain, Base> {
|
|
public:
|
|
using RD = RuntimeDecorator<Plain, Base>;
|
|
WithRuntimeDecorator(Plain& plain, With& with) : RD(plain), with_(with) {}
|
|
ICast* castInterface(const UUID& interfaceUUID) override {
|
|
Around around{with_};
|
|
return RD::castInterface(interfaceUUID);
|
|
}
|
|
Value evaluateJavaScript(
|
|
const std::shared_ptr<const Buffer>& buffer,
|
|
const std::string& sourceURL) override {
|
|
Around around{with_};
|
|
return RD::evaluateJavaScript(buffer, sourceURL);
|
|
}
|
|
std::shared_ptr<const PreparedJavaScript> prepareJavaScript(
|
|
const std::shared_ptr<const Buffer>& buffer,
|
|
std::string sourceURL) override {
|
|
Around around{with_};
|
|
return RD::prepareJavaScript(buffer, std::move(sourceURL));
|
|
}
|
|
Value evaluatePreparedJavaScript(
|
|
const std::shared_ptr<const PreparedJavaScript>& js) override {
|
|
Around around{with_};
|
|
return RD::evaluatePreparedJavaScript(js);
|
|
}
|
|
void queueMicrotask(const Function& callback) override {
|
|
Around around{with_};
|
|
RD::queueMicrotask(callback);
|
|
}
|
|
bool drainMicrotasks(int maxMicrotasksHint) override {
|
|
Around around{with_};
|
|
return RD::drainMicrotasks(maxMicrotasksHint);
|
|
}
|
|
Object global() override {
|
|
Around around{with_};
|
|
return RD::global();
|
|
}
|
|
std::string description() override {
|
|
Around around{with_};
|
|
return RD::description();
|
|
};
|
|
bool isInspectable() override {
|
|
Around around{with_};
|
|
return RD::isInspectable();
|
|
};
|
|
jsi::Instrumentation& instrumentation() override {
|
|
Around around{with_};
|
|
return RD::instrumentation();
|
|
}
|
|
|
|
protected:
|
|
Runtime::PointerValue* cloneSymbol(const Runtime::PointerValue* pv) override {
|
|
Around around{with_};
|
|
return RD::cloneSymbol(pv);
|
|
};
|
|
Runtime::PointerValue* cloneBigInt(const Runtime::PointerValue* pv) override {
|
|
Around around{with_};
|
|
return RD::cloneBigInt(pv);
|
|
};
|
|
Runtime::PointerValue* cloneString(const Runtime::PointerValue* pv) override {
|
|
Around around{with_};
|
|
return RD::cloneString(pv);
|
|
};
|
|
Runtime::PointerValue* cloneObject(const Runtime::PointerValue* pv) override {
|
|
Around around{with_};
|
|
return RD::cloneObject(pv);
|
|
};
|
|
Runtime::PointerValue* clonePropNameID(
|
|
const Runtime::PointerValue* pv) override {
|
|
Around around{with_};
|
|
return RD::clonePropNameID(pv);
|
|
};
|
|
PropNameID createPropNameIDFromAscii(const char* str, size_t length)
|
|
override {
|
|
Around around{with_};
|
|
return RD::createPropNameIDFromAscii(str, length);
|
|
};
|
|
PropNameID createPropNameIDFromUtf8(const uint8_t* utf8, size_t length)
|
|
override {
|
|
Around around{with_};
|
|
return RD::createPropNameIDFromUtf8(utf8, length);
|
|
};
|
|
PropNameID createPropNameIDFromUtf16(const char16_t* utf16, size_t length)
|
|
override {
|
|
Around around{with_};
|
|
return RD::createPropNameIDFromUtf16(utf16, length);
|
|
}
|
|
PropNameID createPropNameIDFromString(const String& str) override {
|
|
Around around{with_};
|
|
return RD::createPropNameIDFromString(str);
|
|
};
|
|
PropNameID createPropNameIDFromSymbol(const Symbol& sym) override {
|
|
Around around{with_};
|
|
return RD::createPropNameIDFromSymbol(sym);
|
|
};
|
|
std::string utf8(const PropNameID& id) override {
|
|
Around around{with_};
|
|
return RD::utf8(id);
|
|
};
|
|
bool compare(const PropNameID& a, const PropNameID& b) override {
|
|
Around around{with_};
|
|
return RD::compare(a, b);
|
|
};
|
|
std::string symbolToString(const Symbol& sym) override {
|
|
Around around{with_};
|
|
return RD::symbolToString(sym);
|
|
};
|
|
BigInt createBigIntFromInt64(int64_t i) override {
|
|
Around around{with_};
|
|
return RD::createBigIntFromInt64(i);
|
|
};
|
|
BigInt createBigIntFromUint64(uint64_t i) override {
|
|
Around around{with_};
|
|
return RD::createBigIntFromUint64(i);
|
|
};
|
|
bool bigintIsInt64(const BigInt& bi) override {
|
|
Around around{with_};
|
|
return RD::bigintIsInt64(bi);
|
|
};
|
|
bool bigintIsUint64(const BigInt& bi) override {
|
|
Around around{with_};
|
|
return RD::bigintIsUint64(bi);
|
|
};
|
|
uint64_t truncate(const BigInt& bi) override {
|
|
Around around{with_};
|
|
return RD::truncate(bi);
|
|
};
|
|
String bigintToString(const BigInt& bi, int i) override {
|
|
Around around{with_};
|
|
return RD::bigintToString(bi, i);
|
|
};
|
|
String createStringFromAscii(const char* str, size_t length) override {
|
|
Around around{with_};
|
|
return RD::createStringFromAscii(str, length);
|
|
};
|
|
String createStringFromUtf8(const uint8_t* utf8, size_t length) override {
|
|
Around around{with_};
|
|
return RD::createStringFromUtf8(utf8, length);
|
|
};
|
|
String createStringFromUtf16(const char16_t* utf16, size_t length) override {
|
|
Around around{with_};
|
|
return RD::createStringFromUtf16(utf16, length);
|
|
}
|
|
std::string utf8(const String& s) override {
|
|
Around around{with_};
|
|
return RD::utf8(s);
|
|
}
|
|
std::u16string utf16(const String& str) override {
|
|
Around around{with_};
|
|
return RD::utf16(str);
|
|
}
|
|
std::u16string utf16(const PropNameID& sym) override {
|
|
Around around{with_};
|
|
return RD::utf16(sym);
|
|
}
|
|
void getStringData(
|
|
const jsi::String& str,
|
|
void* ctx,
|
|
void (
|
|
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
|
|
Around around{with_};
|
|
RD::getStringData(str, ctx, cb);
|
|
}
|
|
void getPropNameIdData(
|
|
const jsi::PropNameID& sym,
|
|
void* ctx,
|
|
void (
|
|
*cb)(void* ctx, bool ascii, const void* data, size_t num)) override {
|
|
Around around{with_};
|
|
RD::getPropNameIdData(sym, ctx, cb);
|
|
}
|
|
Value createValueFromJsonUtf8(const uint8_t* json, size_t length) override {
|
|
Around around{with_};
|
|
return RD::createValueFromJsonUtf8(json, length);
|
|
};
|
|
Object createObjectWithPrototype(const Value& prototype) override {
|
|
Around around{with_};
|
|
return RD::createObjectWithPrototype(prototype);
|
|
}
|
|
Object createObject() override {
|
|
Around around{with_};
|
|
return RD::createObject();
|
|
};
|
|
Object createObject(std::shared_ptr<HostObject> ho) override {
|
|
Around around{with_};
|
|
return RD::createObject(std::move(ho));
|
|
};
|
|
std::shared_ptr<HostObject> getHostObject(const jsi::Object& o) override {
|
|
Around around{with_};
|
|
return RD::getHostObject(o);
|
|
};
|
|
HostFunctionType& getHostFunction(const jsi::Function& f) override {
|
|
Around around{with_};
|
|
return RD::getHostFunction(f);
|
|
};
|
|
bool hasNativeState(const Object& o) override {
|
|
Around around{with_};
|
|
return RD::hasNativeState(o);
|
|
};
|
|
std::shared_ptr<NativeState> getNativeState(const Object& o) override {
|
|
Around around{with_};
|
|
return RD::getNativeState(o);
|
|
};
|
|
void setNativeState(const Object& o, std::shared_ptr<NativeState> state)
|
|
override {
|
|
Around around{with_};
|
|
RD::setNativeState(o, state);
|
|
};
|
|
void setPrototypeOf(const Object& object, const Value& prototype) override {
|
|
Around around{with_};
|
|
RD::setPrototypeOf(object, prototype);
|
|
}
|
|
Value getPrototypeOf(const Object& object) override {
|
|
Around around{with_};
|
|
return RD::getPrototypeOf(object);
|
|
}
|
|
Value getProperty(const Object& o, const PropNameID& name) override {
|
|
Around around{with_};
|
|
return RD::getProperty(o, name);
|
|
};
|
|
Value getProperty(const Object& o, const String& name) override {
|
|
Around around{with_};
|
|
return RD::getProperty(o, name);
|
|
};
|
|
bool hasProperty(const Object& o, const PropNameID& name) override {
|
|
Around around{with_};
|
|
return RD::hasProperty(o, name);
|
|
};
|
|
bool hasProperty(const Object& o, const String& name) override {
|
|
Around around{with_};
|
|
return RD::hasProperty(o, name);
|
|
};
|
|
void setPropertyValue(
|
|
const Object& o,
|
|
const PropNameID& name,
|
|
const Value& value) override {
|
|
Around around{with_};
|
|
RD::setPropertyValue(o, name, value);
|
|
};
|
|
void setPropertyValue(const Object& o, const String& name, const Value& value)
|
|
override {
|
|
Around around{with_};
|
|
RD::setPropertyValue(o, name, value);
|
|
};
|
|
bool isArray(const Object& o) const override {
|
|
Around around{with_};
|
|
return RD::isArray(o);
|
|
};
|
|
bool isArrayBuffer(const Object& o) const override {
|
|
Around around{with_};
|
|
return RD::isArrayBuffer(o);
|
|
};
|
|
bool isFunction(const Object& o) const override {
|
|
Around around{with_};
|
|
return RD::isFunction(o);
|
|
};
|
|
bool isHostObject(const jsi::Object& o) const override {
|
|
Around around{with_};
|
|
return RD::isHostObject(o);
|
|
};
|
|
bool isHostFunction(const jsi::Function& f) const override {
|
|
Around around{with_};
|
|
return RD::isHostFunction(f);
|
|
};
|
|
Array getPropertyNames(const Object& o) override {
|
|
Around around{with_};
|
|
return RD::getPropertyNames(o);
|
|
};
|
|
WeakObject createWeakObject(const Object& o) override {
|
|
Around around{with_};
|
|
return RD::createWeakObject(o);
|
|
};
|
|
Value lockWeakObject(const WeakObject& wo) override {
|
|
Around around{with_};
|
|
return RD::lockWeakObject(wo);
|
|
};
|
|
Array createArray(size_t length) override {
|
|
Around around{with_};
|
|
return RD::createArray(length);
|
|
};
|
|
ArrayBuffer createArrayBuffer(
|
|
std::shared_ptr<MutableBuffer> buffer) override {
|
|
return RD::createArrayBuffer(std::move(buffer));
|
|
};
|
|
size_t size(const Array& a) override {
|
|
Around around{with_};
|
|
return RD::size(a);
|
|
};
|
|
size_t size(const ArrayBuffer& ab) override {
|
|
Around around{with_};
|
|
return RD::size(ab);
|
|
};
|
|
uint8_t* data(const ArrayBuffer& ab) override {
|
|
Around around{with_};
|
|
return RD::data(ab);
|
|
};
|
|
Value getValueAtIndex(const Array& a, size_t i) override {
|
|
Around around{with_};
|
|
return RD::getValueAtIndex(a, i);
|
|
};
|
|
void setValueAtIndexImpl(const Array& a, size_t i, const Value& value)
|
|
override {
|
|
Around around{with_};
|
|
RD::setValueAtIndexImpl(a, i, value);
|
|
};
|
|
Function createFunctionFromHostFunction(
|
|
const PropNameID& name,
|
|
unsigned int paramCount,
|
|
HostFunctionType func) override {
|
|
Around around{with_};
|
|
return RD::createFunctionFromHostFunction(
|
|
name, paramCount, std::move(func));
|
|
};
|
|
Value call(
|
|
const Function& f,
|
|
const Value& jsThis,
|
|
const Value* args,
|
|
size_t count) override {
|
|
Around around{with_};
|
|
return RD::call(f, jsThis, args, count);
|
|
};
|
|
Value callAsConstructor(const Function& f, const Value* args, size_t count)
|
|
override {
|
|
Around around{with_};
|
|
return RD::callAsConstructor(f, args, count);
|
|
};
|
|
Runtime::ScopeState* pushScope() override {
|
|
Around around{with_};
|
|
return RD::pushScope();
|
|
}
|
|
void popScope(Runtime::ScopeState* ss) override {
|
|
Around around{with_};
|
|
RD::popScope(ss);
|
|
}
|
|
bool strictEquals(const Symbol& a, const Symbol& b) const override {
|
|
Around around{with_};
|
|
return RD::strictEquals(a, b);
|
|
};
|
|
bool strictEquals(const BigInt& a, const BigInt& b) const override {
|
|
Around around{with_};
|
|
return RD::strictEquals(a, b);
|
|
};
|
|
bool strictEquals(const String& a, const String& b) const override {
|
|
Around around{with_};
|
|
return RD::strictEquals(a, b);
|
|
};
|
|
bool strictEquals(const Object& a, const Object& b) const override {
|
|
Around around{with_};
|
|
return RD::strictEquals(a, b);
|
|
};
|
|
bool instanceOf(const Object& o, const Function& f) override {
|
|
Around around{with_};
|
|
return RD::instanceOf(o, f);
|
|
};
|
|
void setExternalMemoryPressure(const jsi::Object& obj, size_t amount)
|
|
override {
|
|
Around around{with_};
|
|
RD::setExternalMemoryPressure(obj, amount);
|
|
};
|
|
void setRuntimeDataImpl(
|
|
const UUID& uuid,
|
|
const void* data,
|
|
void (*deleter)(const void* data)) override {
|
|
Around around{with_};
|
|
RD::setRuntimeDataImpl(uuid, data, deleter);
|
|
}
|
|
const void* getRuntimeDataImpl(const UUID& uuid) override {
|
|
Around around{with_};
|
|
return RD::getRuntimeDataImpl(uuid);
|
|
}
|
|
};
|
|
With& with_;
|
|
};
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/instrumentation.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
class JSI_EXPORT Instrumentation {
|
|
public:
|
|
struct HeapSnapshotOptions {
|
|
bool captureNumericValue{false};
|
|
};
|
|
virtual ~Instrumentation() = default;
|
|
virtual std::string getRecordedGCStats() = 0;
|
|
virtual std::unordered_map<std::string, int64_t> getHeapInfo(
|
|
bool includeExpensive) = 0;
|
|
virtual void collectGarbage(std::string cause) = 0;
|
|
using HeapStatsUpdate = std::tuple<uint64_t, uint64_t, uint64_t>;
|
|
virtual void startTrackingHeapObjectStackTraces(
|
|
std::function<void(
|
|
uint64_t lastSeenObjectID,
|
|
std::chrono::microseconds timestamp,
|
|
std::vector<HeapStatsUpdate> stats)> fragmentCallback) = 0;
|
|
virtual void stopTrackingHeapObjectStackTraces() = 0;
|
|
virtual void startHeapSampling(size_t samplingInterval) = 0;
|
|
virtual void stopHeapSampling(std::ostream& os) = 0;
|
|
virtual void createSnapshotToFile(
|
|
const std::string& path,
|
|
const HeapSnapshotOptions& options = {false}) = 0;
|
|
virtual void createSnapshotToStream(
|
|
std::ostream& os,
|
|
const HeapSnapshotOptions& options = {false}) = 0;
|
|
virtual std::string flushAndDisableBridgeTrafficTrace() = 0;
|
|
virtual void writeBasicBlockProfileTraceToFile(
|
|
const std::string& fileName) const = 0;
|
|
virtual void dumpProfilerSymbolsToFile(const std::string& fileName) const = 0;
|
|
};
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/jsi-inl.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
namespace detail {
|
|
inline Value toValue(Runtime&, std::nullptr_t) {
|
|
return Value::null();
|
|
}
|
|
inline Value toValue(Runtime&, bool b) {
|
|
return Value(b);
|
|
}
|
|
inline Value toValue(Runtime&, double d) {
|
|
return Value(d);
|
|
}
|
|
inline Value toValue(Runtime&, float f) {
|
|
return Value(static_cast<double>(f));
|
|
}
|
|
inline Value toValue(Runtime&, int i) {
|
|
return Value(i);
|
|
}
|
|
inline Value toValue(Runtime& runtime, const char* str) {
|
|
return String::createFromAscii(runtime, str);
|
|
}
|
|
inline Value toValue(Runtime& runtime, const std::string& str) {
|
|
return String::createFromUtf8(runtime, str);
|
|
}
|
|
template <typename T>
|
|
inline Value toValue(Runtime& runtime, const T& other) {
|
|
static_assert(
|
|
std::is_base_of<Pointer, T>::value,
|
|
"This type cannot be converted to Value");
|
|
return Value(runtime, other);
|
|
}
|
|
inline Value toValue(Runtime& runtime, const Value& value) {
|
|
return Value(runtime, value);
|
|
}
|
|
inline Value&& toValue(Runtime&, Value&& value) {
|
|
return std::move(value);
|
|
}
|
|
inline PropNameID toPropNameID(Runtime& runtime, const char* name) {
|
|
return PropNameID::forAscii(runtime, name);
|
|
}
|
|
inline PropNameID toPropNameID(Runtime& runtime, const std::string& name) {
|
|
return PropNameID::forUtf8(runtime, name);
|
|
}
|
|
inline PropNameID&& toPropNameID(Runtime&, PropNameID&& name) {
|
|
return std::move(name);
|
|
}
|
|
template <typename E, typename... Args>
|
|
[[noreturn]] inline void throwOrDie(Args&&... args) {
|
|
std::rethrow_exception(
|
|
std::make_exception_ptr(E{std::forward<Args>(args)...}));
|
|
}
|
|
} // namespace detail
|
|
template <typename T>
|
|
inline T Runtime::make(Runtime::PointerValue* pv) {
|
|
return T(pv);
|
|
}
|
|
inline Runtime::PointerValue* Runtime::getPointerValue(jsi::Pointer& pointer) {
|
|
return pointer.ptr_;
|
|
}
|
|
inline const Runtime::PointerValue* Runtime::getPointerValue(
|
|
const jsi::Pointer& pointer) {
|
|
return pointer.ptr_;
|
|
}
|
|
inline const Runtime::PointerValue* Runtime::getPointerValue(
|
|
const jsi::Value& value) {
|
|
return value.data_.pointer.ptr_;
|
|
}
|
|
inline void Runtime::setRuntimeData(
|
|
const UUID& uuid,
|
|
const std::shared_ptr<void>& data) {
|
|
auto* dataPtr = new std::shared_ptr<void>(data);
|
|
setRuntimeDataImpl(uuid, dataPtr, [](const void* data) {
|
|
delete (const std::shared_ptr<void>*)data;
|
|
});
|
|
}
|
|
inline std::shared_ptr<void> Runtime::getRuntimeData(const UUID& uuid) {
|
|
auto* data = (const std::shared_ptr<void>*)getRuntimeDataImpl(uuid);
|
|
return data ? *data : nullptr;
|
|
}
|
|
Value Object::getPrototype(Runtime& runtime) const {
|
|
return runtime.getPrototypeOf(*this);
|
|
}
|
|
inline Value Object::getProperty(Runtime& runtime, const char* name) const {
|
|
return getProperty(runtime, String::createFromAscii(runtime, name));
|
|
}
|
|
inline Value Object::getProperty(Runtime& runtime, const String& name) const {
|
|
return runtime.getProperty(*this, name);
|
|
}
|
|
inline Value Object::getProperty(Runtime& runtime, const PropNameID& name)
|
|
const {
|
|
return runtime.getProperty(*this, name);
|
|
}
|
|
inline bool Object::hasProperty(Runtime& runtime, const char* name) const {
|
|
return hasProperty(runtime, String::createFromAscii(runtime, name));
|
|
}
|
|
inline bool Object::hasProperty(Runtime& runtime, const String& name) const {
|
|
return runtime.hasProperty(*this, name);
|
|
}
|
|
inline bool Object::hasProperty(Runtime& runtime, const PropNameID& name)
|
|
const {
|
|
return runtime.hasProperty(*this, name);
|
|
}
|
|
template <typename T>
|
|
void Object::setProperty(Runtime& runtime, const char* name, T&& value) const {
|
|
setProperty(
|
|
runtime, String::createFromAscii(runtime, name), std::forward<T>(value));
|
|
}
|
|
template <typename T>
|
|
void Object::setProperty(Runtime& runtime, const String& name, T&& value)
|
|
const {
|
|
setPropertyValue(
|
|
runtime, name, detail::toValue(runtime, std::forward<T>(value)));
|
|
}
|
|
template <typename T>
|
|
void Object::setProperty(Runtime& runtime, const PropNameID& name, T&& value)
|
|
const {
|
|
setPropertyValue(
|
|
runtime, name, detail::toValue(runtime, std::forward<T>(value)));
|
|
}
|
|
inline Array Object::getArray(Runtime& runtime) const& {
|
|
assert(runtime.isArray(*this));
|
|
(void)runtime;
|
|
return Array(runtime.cloneObject(ptr_));
|
|
}
|
|
inline Array Object::getArray(Runtime& runtime) && {
|
|
assert(runtime.isArray(*this));
|
|
(void)runtime;
|
|
Runtime::PointerValue* value = ptr_;
|
|
ptr_ = nullptr;
|
|
return Array(value);
|
|
}
|
|
inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) const& {
|
|
assert(runtime.isArrayBuffer(*this));
|
|
(void)runtime;
|
|
return ArrayBuffer(runtime.cloneObject(ptr_));
|
|
}
|
|
inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && {
|
|
assert(runtime.isArrayBuffer(*this));
|
|
(void)runtime;
|
|
Runtime::PointerValue* value = ptr_;
|
|
ptr_ = nullptr;
|
|
return ArrayBuffer(value);
|
|
}
|
|
inline Function Object::getFunction(Runtime& runtime) const& {
|
|
assert(runtime.isFunction(*this));
|
|
return Function(runtime.cloneObject(ptr_));
|
|
}
|
|
inline Function Object::getFunction(Runtime& runtime) && {
|
|
assert(runtime.isFunction(*this));
|
|
(void)runtime;
|
|
Runtime::PointerValue* value = ptr_;
|
|
ptr_ = nullptr;
|
|
return Function(value);
|
|
}
|
|
template <typename T>
|
|
inline bool Object::isHostObject(Runtime& runtime) const {
|
|
return runtime.isHostObject(*this) &&
|
|
std::dynamic_pointer_cast<T>(runtime.getHostObject(*this));
|
|
}
|
|
template <>
|
|
inline bool Object::isHostObject<HostObject>(Runtime& runtime) const {
|
|
return runtime.isHostObject(*this);
|
|
}
|
|
template <typename T>
|
|
inline std::shared_ptr<T> Object::getHostObject(Runtime& runtime) const {
|
|
assert(isHostObject<T>(runtime));
|
|
return std::static_pointer_cast<T>(runtime.getHostObject(*this));
|
|
}
|
|
template <typename T>
|
|
inline std::shared_ptr<T> Object::asHostObject(Runtime& runtime) const {
|
|
if (!isHostObject<T>(runtime)) {
|
|
detail::throwOrDie<JSINativeException>(
|
|
"Object is not a HostObject of desired type");
|
|
}
|
|
return std::static_pointer_cast<T>(runtime.getHostObject(*this));
|
|
}
|
|
template <>
|
|
inline std::shared_ptr<HostObject> Object::getHostObject<HostObject>(
|
|
Runtime& runtime) const {
|
|
assert(runtime.isHostObject(*this));
|
|
return runtime.getHostObject(*this);
|
|
}
|
|
template <typename T>
|
|
inline bool Object::hasNativeState(Runtime& runtime) const {
|
|
return runtime.hasNativeState(*this) &&
|
|
std::dynamic_pointer_cast<T>(runtime.getNativeState(*this));
|
|
}
|
|
template <>
|
|
inline bool Object::hasNativeState<NativeState>(Runtime& runtime) const {
|
|
return runtime.hasNativeState(*this);
|
|
}
|
|
template <typename T>
|
|
inline std::shared_ptr<T> Object::getNativeState(Runtime& runtime) const {
|
|
assert(hasNativeState<T>(runtime));
|
|
return std::static_pointer_cast<T>(runtime.getNativeState(*this));
|
|
}
|
|
inline void Object::setNativeState(
|
|
Runtime& runtime,
|
|
std::shared_ptr<NativeState> state) const {
|
|
runtime.setNativeState(*this, state);
|
|
}
|
|
inline void Object::setExternalMemoryPressure(Runtime& runtime, size_t amt)
|
|
const {
|
|
runtime.setExternalMemoryPressure(*this, amt);
|
|
}
|
|
inline Array Object::getPropertyNames(Runtime& runtime) const {
|
|
return runtime.getPropertyNames(*this);
|
|
}
|
|
inline Value WeakObject::lock(Runtime& runtime) const {
|
|
return runtime.lockWeakObject(*this);
|
|
}
|
|
template <typename T>
|
|
void Array::setValueAtIndex(Runtime& runtime, size_t i, T&& value) const {
|
|
setValueAtIndexImpl(
|
|
runtime, i, detail::toValue(runtime, std::forward<T>(value)));
|
|
}
|
|
inline Value Array::getValueAtIndex(Runtime& runtime, size_t i) const {
|
|
return runtime.getValueAtIndex(*this, i);
|
|
}
|
|
inline Function Function::createFromHostFunction(
|
|
Runtime& runtime,
|
|
const jsi::PropNameID& name,
|
|
unsigned int paramCount,
|
|
jsi::HostFunctionType func) {
|
|
return runtime.createFunctionFromHostFunction(
|
|
name, paramCount, std::move(func));
|
|
}
|
|
inline Value Function::call(Runtime& runtime, const Value* args, size_t count)
|
|
const {
|
|
return runtime.call(*this, Value::undefined(), args, count);
|
|
}
|
|
inline Value Function::call(Runtime& runtime, std::initializer_list<Value> args)
|
|
const {
|
|
return call(runtime, args.begin(), args.size());
|
|
}
|
|
template <typename... Args>
|
|
inline Value Function::call(Runtime& runtime, Args&&... args) const {
|
|
return call(runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
|
|
}
|
|
inline Value Function::callWithThis(
|
|
Runtime& runtime,
|
|
const Object& jsThis,
|
|
const Value* args,
|
|
size_t count) const {
|
|
return runtime.call(*this, Value(runtime, jsThis), args, count);
|
|
}
|
|
inline Value Function::callWithThis(
|
|
Runtime& runtime,
|
|
const Object& jsThis,
|
|
std::initializer_list<Value> args) const {
|
|
return callWithThis(runtime, jsThis, args.begin(), args.size());
|
|
}
|
|
template <typename... Args>
|
|
inline Value Function::callWithThis(
|
|
Runtime& runtime,
|
|
const Object& jsThis,
|
|
Args&&... args) const {
|
|
return callWithThis(
|
|
runtime, jsThis, {detail::toValue(runtime, std::forward<Args>(args))...});
|
|
}
|
|
template <typename... Args>
|
|
inline Array Array::createWithElements(Runtime& runtime, Args&&... args) {
|
|
return createWithElements(
|
|
runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
|
|
}
|
|
template <typename... Args>
|
|
inline std::vector<PropNameID> PropNameID::names(
|
|
Runtime& runtime,
|
|
Args&&... args) {
|
|
return names({detail::toPropNameID(runtime, std::forward<Args>(args))...});
|
|
}
|
|
template <size_t N>
|
|
inline std::vector<PropNameID> PropNameID::names(
|
|
PropNameID (&&propertyNames)[N]) {
|
|
std::vector<PropNameID> result;
|
|
result.reserve(N);
|
|
for (auto& name : propertyNames) {
|
|
result.push_back(std::move(name));
|
|
}
|
|
return result;
|
|
}
|
|
inline Value Function::callAsConstructor(
|
|
Runtime& runtime,
|
|
const Value* args,
|
|
size_t count) const {
|
|
return runtime.callAsConstructor(*this, args, count);
|
|
}
|
|
inline Value Function::callAsConstructor(
|
|
Runtime& runtime,
|
|
std::initializer_list<Value> args) const {
|
|
return callAsConstructor(runtime, args.begin(), args.size());
|
|
}
|
|
template <typename... Args>
|
|
inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args)
|
|
const {
|
|
return callAsConstructor(
|
|
runtime, {detail::toValue(runtime, std::forward<Args>(args))...});
|
|
}
|
|
String BigInt::toString(Runtime& runtime, int radix) const {
|
|
return runtime.bigintToString(*this, radix);
|
|
}
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/jsi.h}:
|
|
|
|
namespace facebook {
|
|
namespace jsi {
|
|
class __attribute__((visibility("default"))) UUID {
|
|
public:
|
|
constexpr UUID(
|
|
uint32_t timeLow,
|
|
uint16_t timeMid,
|
|
uint16_t timeHighAndVersion,
|
|
uint16_t variantAndClockSeq,
|
|
uint64_t node)
|
|
: high(
|
|
((uint64_t)(timeLow) << 32) | ((uint64_t)(timeMid) << 16) |
|
|
((uint64_t)(timeHighAndVersion))),
|
|
low(((uint64_t)(variantAndClockSeq) << 48) | node) {}
|
|
constexpr UUID() : high(0), low(0) {}
|
|
constexpr UUID(const UUID&) = default;
|
|
constexpr UUID& operator=(const UUID&) = default;
|
|
constexpr bool operator==(const UUID& other) const {
|
|
return high == other.high && low == other.low;
|
|
}
|
|
constexpr bool operator!=(const UUID& other) const {
|
|
return !(*this == other);
|
|
}
|
|
constexpr bool operator<(const UUID& other) const {
|
|
return (high < other.high) || (high == other.high && low < other.low);
|
|
}
|
|
struct Hash {
|
|
std::size_t operator()(const UUID& uuid) const noexcept {
|
|
return std::hash<uint64_t>{}(uuid.high) ^
|
|
(std::hash<uint64_t>{}(uuid.low) << 1);
|
|
}
|
|
};
|
|
std::string toString() const {
|
|
std::string buffer(36, ' ');
|
|
std::snprintf(
|
|
buffer.data(),
|
|
buffer.size() + 1,
|
|
"%08x-%04x-%04x-%04x-%012llx",
|
|
getTimeLow(),
|
|
getTimeMid(),
|
|
getTimeHighAndVersion(),
|
|
getVariantAndClockSeq(),
|
|
(unsigned long long)getNode());
|
|
return buffer;
|
|
}
|
|
constexpr uint32_t getTimeLow() const {
|
|
return (uint32_t)(high >> 32);
|
|
}
|
|
constexpr uint16_t getTimeMid() const {
|
|
return (uint16_t)(high >> 16);
|
|
}
|
|
constexpr uint16_t getTimeHighAndVersion() const {
|
|
return (uint16_t)high;
|
|
}
|
|
constexpr uint16_t getVariantAndClockSeq() const {
|
|
return (uint16_t)(low >> 48);
|
|
}
|
|
constexpr uint64_t getNode() const {
|
|
return low & 0xFFFFFFFFFFFF;
|
|
}
|
|
};
|
|
struct __attribute__((visibility("default"))) ICast {
|
|
virtual ICast* castInterface(const UUID& interfaceUUID) = 0;
|
|
|
|
protected:
|
|
~ICast() = default;
|
|
};
|
|
class __attribute__((visibility("default"))) Buffer {
|
|
public:
|
|
virtual ~Buffer();
|
|
virtual size_t size() const = 0;
|
|
virtual const uint8_t* data() const = 0;
|
|
};
|
|
class __attribute__((visibility("default"))) StringBuffer : public Buffer {
|
|
public:
|
|
StringBuffer(std::string s) : s_(std::move(s)) {}
|
|
size_t size() const override {
|
|
return s_.size();
|
|
}
|
|
const uint8_t* data() const override {
|
|
return reinterpret_cast<const uint8_t*>(s_.data());
|
|
}
|
|
};
|
|
class __attribute__((visibility("default"))) MutableBuffer {
|
|
public:
|
|
virtual ~MutableBuffer();
|
|
virtual size_t size() const = 0;
|
|
virtual uint8_t* data() = 0;
|
|
};
|
|
class __attribute__((visibility("default"))) PreparedJavaScript {
|
|
protected:
|
|
PreparedJavaScript() = default;
|
|
|
|
public:
|
|
virtual ~PreparedJavaScript() = 0;
|
|
};
|
|
using HostFunctionType = std::function<
|
|
Value(Runtime& rt, const Value& thisVal, const Value* args, size_t count)>;
|
|
class __attribute__((visibility("default"))) HostObject {
|
|
public:
|
|
virtual ~HostObject();
|
|
virtual Value get(Runtime&, const PropNameID& name);
|
|
virtual void set(Runtime&, const PropNameID& name, const Value& value);
|
|
virtual std::vector<PropNameID> getPropertyNames(Runtime& rt);
|
|
};
|
|
class __attribute__((visibility("default"))) NativeState {
|
|
public:
|
|
virtual ~NativeState();
|
|
};
|
|
class __attribute__((visibility("default"))) Runtime : public ICast {
|
|
public:
|
|
virtual ~Runtime();
|
|
ICast* castInterface(const UUID& interfaceUUID) override;
|
|
virtual Value evaluateJavaScript(
|
|
const std::shared_ptr<const Buffer>& buffer,
|
|
const std::string& sourceURL) = 0;
|
|
virtual std::shared_ptr<const PreparedJavaScript> prepareJavaScript(
|
|
const std::shared_ptr<const Buffer>& buffer,
|
|
std::string sourceURL) = 0;
|
|
virtual Value evaluatePreparedJavaScript(
|
|
const std::shared_ptr<const PreparedJavaScript>& js) = 0;
|
|
virtual void queueMicrotask(const jsi::Function& callback) = 0;
|
|
virtual bool drainMicrotasks(int maxMicrotasksHint = -1) = 0;
|
|
virtual Object global() = 0;
|
|
virtual std::string description() = 0;
|
|
virtual bool isInspectable() = 0;
|
|
virtual Instrumentation& instrumentation();
|
|
void setRuntimeData(const UUID& uuid, const std::shared_ptr<void>& data);
|
|
std::shared_ptr<void> getRuntimeData(const UUID& uuid);
|
|
|
|
protected:
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
friend
|
|
virtual void setRuntimeDataImpl(
|
|
const UUID& uuid,
|
|
const void* data,
|
|
void (*deleter)(const void* data));
|
|
virtual const void* getRuntimeDataImpl(const UUID& uuid);
|
|
struct PointerValue {
|
|
virtual void invalidate() noexcept = 0;
|
|
|
|
protected:
|
|
virtual ~PointerValue() = default;
|
|
};
|
|
virtual PointerValue* cloneSymbol(const Runtime::PointerValue* pv) = 0;
|
|
virtual PointerValue* cloneBigInt(const Runtime::PointerValue* pv) = 0;
|
|
virtual PointerValue* cloneString(const Runtime::PointerValue* pv) = 0;
|
|
virtual PointerValue* cloneObject(const Runtime::PointerValue* pv) = 0;
|
|
virtual PointerValue* clonePropNameID(const Runtime::PointerValue* pv) = 0;
|
|
virtual PropNameID createPropNameIDFromAscii(
|
|
const char* str,
|
|
size_t length) = 0;
|
|
virtual PropNameID createPropNameIDFromUtf8(
|
|
const uint8_t* utf8,
|
|
size_t length) = 0;
|
|
virtual PropNameID createPropNameIDFromUtf16(
|
|
const char16_t* utf16,
|
|
size_t length);
|
|
virtual PropNameID createPropNameIDFromString(const String& str) = 0;
|
|
virtual PropNameID createPropNameIDFromSymbol(const Symbol& sym) = 0;
|
|
virtual std::string utf8(const PropNameID&) = 0;
|
|
virtual bool compare(const PropNameID&, const PropNameID&) = 0;
|
|
virtual std::string symbolToString(const Symbol&) = 0;
|
|
virtual BigInt createBigIntFromInt64(int64_t) = 0;
|
|
virtual BigInt createBigIntFromUint64(uint64_t) = 0;
|
|
virtual bool bigintIsInt64(const BigInt&) = 0;
|
|
virtual bool bigintIsUint64(const BigInt&) = 0;
|
|
virtual uint64_t truncate(const BigInt&) = 0;
|
|
virtual String bigintToString(const BigInt&, int) = 0;
|
|
virtual String createStringFromAscii(const char* str, size_t length) = 0;
|
|
virtual String createStringFromUtf8(const uint8_t* utf8, size_t length) = 0;
|
|
virtual String createStringFromUtf16(const char16_t* utf16, size_t length);
|
|
virtual std::string utf8(const String&) = 0;
|
|
virtual Value createValueFromJsonUtf8(const uint8_t* json, size_t length);
|
|
virtual Object createObject() = 0;
|
|
virtual Object createObject(std::shared_ptr<HostObject> ho) = 0;
|
|
virtual std::shared_ptr<HostObject> getHostObject(const jsi::Object&) = 0;
|
|
virtual HostFunctionType& getHostFunction(const jsi::Function&) = 0;
|
|
virtual Object createObjectWithPrototype(const Value& prototype);
|
|
virtual bool hasNativeState(const jsi::Object&) = 0;
|
|
virtual std::shared_ptr<NativeState> getNativeState(const jsi::Object&) = 0;
|
|
virtual void setNativeState(
|
|
const jsi::Object&,
|
|
std::shared_ptr<NativeState> state) = 0;
|
|
virtual void setPrototypeOf(const Object& object, const Value& prototype);
|
|
virtual Value getPrototypeOf(const Object& object);
|
|
virtual Value getProperty(const Object&, const PropNameID& name) = 0;
|
|
virtual Value getProperty(const Object&, const String& name) = 0;
|
|
virtual bool hasProperty(const Object&, const PropNameID& name) = 0;
|
|
virtual bool hasProperty(const Object&, const String& name) = 0;
|
|
virtual void setPropertyValue(
|
|
const Object&,
|
|
const PropNameID& name,
|
|
const Value& value) = 0;
|
|
virtual void
|
|
setPropertyValue(const Object&, const String& name, const Value& value) = 0;
|
|
virtual bool isArray(const Object&) const = 0;
|
|
virtual bool isArrayBuffer(const Object&) const = 0;
|
|
virtual bool isFunction(const Object&) const = 0;
|
|
virtual bool isHostObject(const jsi::Object&) const = 0;
|
|
virtual bool isHostFunction(const jsi::Function&) const = 0;
|
|
virtual Array getPropertyNames(const Object&) = 0;
|
|
virtual WeakObject createWeakObject(const Object&) = 0;
|
|
virtual Value lockWeakObject(const WeakObject&) = 0;
|
|
virtual Array createArray(size_t length) = 0;
|
|
virtual ArrayBuffer createArrayBuffer(
|
|
std::shared_ptr<MutableBuffer> buffer) = 0;
|
|
virtual size_t size(const Array&) = 0;
|
|
virtual size_t size(const ArrayBuffer&) = 0;
|
|
virtual uint8_t* data(const ArrayBuffer&) = 0;
|
|
virtual Value getValueAtIndex(const Array&, size_t i) = 0;
|
|
virtual void
|
|
setValueAtIndexImpl(const Array&, size_t i, const Value& value) = 0;
|
|
virtual Function createFunctionFromHostFunction(
|
|
const PropNameID& name,
|
|
unsigned int paramCount,
|
|
HostFunctionType func) = 0;
|
|
virtual Value call(
|
|
const Function&,
|
|
const Value& jsThis,
|
|
const Value* args,
|
|
size_t count) = 0;
|
|
virtual Value
|
|
callAsConstructor(const Function&, const Value* args, size_t count) = 0;
|
|
virtual ScopeState* pushScope();
|
|
virtual void popScope(ScopeState*);
|
|
virtual bool strictEquals(const Symbol& a, const Symbol& b) const = 0;
|
|
virtual bool strictEquals(const BigInt& a, const BigInt& b) const = 0;
|
|
virtual bool strictEquals(const String& a, const String& b) const = 0;
|
|
virtual bool strictEquals(const Object& a, const Object& b) const = 0;
|
|
virtual bool instanceOf(const Object& o, const Function& f) = 0;
|
|
virtual void setExternalMemoryPressure(
|
|
const jsi::Object& obj,
|
|
size_t amount) = 0;
|
|
virtual std::u16string utf16(const String& str);
|
|
virtual std::u16string utf16(const PropNameID& sym);
|
|
virtual void getStringData(
|
|
const jsi::String& str,
|
|
void* ctx,
|
|
void (*cb)(void* ctx, bool ascii, const void* data, size_t num));
|
|
virtual void getPropNameIdData(
|
|
const jsi::PropNameID& sym,
|
|
void* ctx,
|
|
void (*cb)(void* ctx, bool ascii, const void* data, size_t num));
|
|
template <typename T>
|
|
static T make(PointerValue* pv);
|
|
static PointerValue* getPointerValue(Pointer& pointer);
|
|
static const PointerValue* getPointerValue(const Pointer& pointer);
|
|
static const PointerValue* getPointerValue(const Value& value);
|
|
friend
|
|
template <typename Plain, typename Base>
|
|
friend
|
|
class __attribute__((visibility("default"))) Pointer {
|
|
protected:
|
|
explicit Pointer(Pointer&& other) noexcept : ptr_(other.ptr_) {
|
|
other.ptr_ = nullptr;
|
|
}
|
|
~Pointer() {
|
|
if (ptr_) {
|
|
ptr_->invalidate();
|
|
}
|
|
}
|
|
Pointer& operator=(Pointer&& other) noexcept;
|
|
friend
|
|
friend
|
|
explicit Pointer(Runtime::PointerValue* ptr) : ptr_(ptr) {}
|
|
typename Runtime::PointerValue* ptr_;
|
|
};
|
|
class __attribute__((visibility("default"))) PropNameID : public Pointer {
|
|
public:
|
|
using Pointer::Pointer;
|
|
PropNameID(Runtime& runtime, const PropNameID& other)
|
|
: Pointer(runtime.clonePropNameID(other.ptr_)) {}
|
|
PropNameID(PropNameID&& other) = default;
|
|
PropNameID& operator=(PropNameID&& other) = default;
|
|
static PropNameID forAscii(Runtime& runtime, const char* str, size_t length) {
|
|
return runtime.createPropNameIDFromAscii(str, length);
|
|
}
|
|
static PropNameID forAscii(Runtime& runtime, const char* str) {
|
|
return forAscii(runtime, str, strlen(str));
|
|
}
|
|
static PropNameID forAscii(Runtime& runtime, const std::string& str) {
|
|
return forAscii(runtime, str.c_str(), str.size());
|
|
}
|
|
static PropNameID
|
|
forUtf8(Runtime& runtime, const uint8_t* utf8, size_t length) {
|
|
return runtime.createPropNameIDFromUtf8(utf8, length);
|
|
}
|
|
static PropNameID forUtf8(Runtime& runtime, const std::string& utf8) {
|
|
return runtime.createPropNameIDFromUtf8(
|
|
reinterpret_cast<const uint8_t*>(utf8.data()), utf8.size());
|
|
}
|
|
static PropNameID
|
|
forUtf16(Runtime& runtime, const char16_t* utf16, size_t length) {
|
|
return runtime.createPropNameIDFromUtf16(utf16, length);
|
|
}
|
|
static PropNameID forUtf16(Runtime& runtime, const std::u16string& str) {
|
|
return runtime.createPropNameIDFromUtf16(str.data(), str.size());
|
|
}
|
|
static PropNameID forString(Runtime& runtime, const jsi::String& str) {
|
|
return runtime.createPropNameIDFromString(str);
|
|
}
|
|
static PropNameID forSymbol(Runtime& runtime, const jsi::Symbol& sym) {
|
|
return runtime.createPropNameIDFromSymbol(sym);
|
|
}
|
|
template <typename... Args>
|
|
static std::vector<PropNameID> names(Runtime& runtime, Args&&... args);
|
|
template <size_t N>
|
|
static std::vector<PropNameID> names(PropNameID (&&propertyNames)[N]);
|
|
std::string utf8(Runtime& runtime) const {
|
|
return runtime.utf8(*this);
|
|
}
|
|
std::u16string utf16(Runtime& runtime) const {
|
|
return runtime.utf16(*this);
|
|
}
|
|
template <typename CB>
|
|
void getPropNameIdData(Runtime& runtime, CB& cb) const {
|
|
runtime.getPropNameIdData(
|
|
*this, &cb, [](void* ctx, bool ascii, const void* data, size_t num) {
|
|
(*((CB*)ctx))(ascii, data, num);
|
|
});
|
|
}
|
|
static bool compare(
|
|
Runtime& runtime,
|
|
const jsi::PropNameID& a,
|
|
const jsi::PropNameID& b) {
|
|
return runtime.compare(a, b);
|
|
}
|
|
friend
|
|
friend
|
|
class __attribute__((visibility("default"))) Symbol : public Pointer {
|
|
public:
|
|
using Pointer::Pointer;
|
|
Symbol(Symbol&& other) = default;
|
|
Symbol& operator=(Symbol&& other) = default;
|
|
static bool strictEquals(Runtime& runtime, const Symbol& a, const Symbol& b) {
|
|
return runtime.strictEquals(a, b);
|
|
}
|
|
std::string toString(Runtime& runtime) const {
|
|
return runtime.symbolToString(*this);
|
|
}
|
|
friend
|
|
friend
|
|
class __attribute__((visibility("default"))) BigInt : public Pointer {
|
|
public:
|
|
using Pointer::Pointer;
|
|
BigInt(BigInt&& other) = default;
|
|
BigInt& operator=(BigInt&& other) = default;
|
|
static BigInt fromInt64(Runtime& runtime, int64_t value) {
|
|
return runtime.createBigIntFromInt64(value);
|
|
}
|
|
static BigInt fromUint64(Runtime& runtime, uint64_t value) {
|
|
return runtime.createBigIntFromUint64(value);
|
|
}
|
|
static bool strictEquals(Runtime& runtime, const BigInt& a, const BigInt& b) {
|
|
return runtime.strictEquals(a, b);
|
|
}
|
|
int64_t getInt64(Runtime& runtime) const {
|
|
return runtime.truncate(*this);
|
|
}
|
|
bool isInt64(Runtime& runtime) const {
|
|
return runtime.bigintIsInt64(*this);
|
|
}
|
|
int64_t asInt64(Runtime& runtime) const;
|
|
uint64_t getUint64(Runtime& runtime) const {
|
|
return runtime.truncate(*this);
|
|
}
|
|
bool isUint64(Runtime& runtime) const {
|
|
return runtime.bigintIsUint64(*this);
|
|
}
|
|
uint64_t asUint64(Runtime& runtime) const;
|
|
inline String toString(Runtime& runtime, int radix = 10) const;
|
|
friend
|
|
friend
|
|
class __attribute__((visibility("default"))) String : public Pointer {
|
|
public:
|
|
using Pointer::Pointer;
|
|
String(String&& other) = default;
|
|
String& operator=(String&& other) = default;
|
|
static String
|
|
createFromAscii(Runtime& runtime, const char* str, size_t length) {
|
|
return runtime.createStringFromAscii(str, length);
|
|
}
|
|
static String createFromAscii(Runtime& runtime, const char* str) {
|
|
return createFromAscii(runtime, str, strlen(str));
|
|
}
|
|
static String createFromAscii(Runtime& runtime, const std::string& str) {
|
|
return createFromAscii(runtime, str.c_str(), str.size());
|
|
}
|
|
static String
|
|
createFromUtf8(Runtime& runtime, const uint8_t* utf8, size_t length) {
|
|
return runtime.createStringFromUtf8(utf8, length);
|
|
}
|
|
static String createFromUtf8(Runtime& runtime, const std::string& utf8) {
|
|
return runtime.createStringFromUtf8(
|
|
reinterpret_cast<const uint8_t*>(utf8.data()), utf8.length());
|
|
}
|
|
static String
|
|
createFromUtf16(Runtime& runtime, const char16_t* utf16, size_t length) {
|
|
return runtime.createStringFromUtf16(utf16, length);
|
|
}
|
|
static String createFromUtf16(Runtime& runtime, const std::u16string& utf16) {
|
|
return runtime.createStringFromUtf16(utf16.data(), utf16.length());
|
|
}
|
|
static bool strictEquals(Runtime& runtime, const String& a, const String& b) {
|
|
return runtime.strictEquals(a, b);
|
|
}
|
|
std::string utf8(Runtime& runtime) const {
|
|
return runtime.utf8(*this);
|
|
}
|
|
std::u16string utf16(Runtime& runtime) const {
|
|
return runtime.utf16(*this);
|
|
}
|
|
template <typename CB>
|
|
void getStringData(Runtime& runtime, CB& cb) const {
|
|
runtime.getStringData(
|
|
*this, &cb, [](void* ctx, bool ascii, const void* data, size_t num) {
|
|
(*((CB*)ctx))(ascii, data, num);
|
|
});
|
|
}
|
|
friend
|
|
friend
|
|
class __attribute__((visibility("default"))) Object : public Pointer {
|
|
public:
|
|
using Pointer::Pointer;
|
|
Object(Object&& other) = default;
|
|
Object& operator=(Object&& other) = default;
|
|
Object(Runtime& runtime) : Object(runtime.createObject()) {}
|
|
static Object createFromHostObject(
|
|
Runtime& runtime,
|
|
std::shared_ptr<HostObject> ho) {
|
|
return runtime.createObject(ho);
|
|
}
|
|
static Object create(Runtime& runtime, const Value& prototype) {
|
|
return runtime.createObjectWithPrototype(prototype);
|
|
}
|
|
static bool strictEquals(Runtime& runtime, const Object& a, const Object& b) {
|
|
return runtime.strictEquals(a, b);
|
|
}
|
|
bool instanceOf(Runtime& rt, const Function& ctor) const {
|
|
return rt.instanceOf(*this, ctor);
|
|
}
|
|
void setPrototype(Runtime& runtime, const Value& prototype) const {
|
|
return runtime.setPrototypeOf(*this, prototype);
|
|
}
|
|
inline Value getPrototype(Runtime& runtime) const;
|
|
Value getProperty(Runtime& runtime, const char* name) const;
|
|
Value getProperty(Runtime& runtime, const String& name) const;
|
|
Value getProperty(Runtime& runtime, const PropNameID& name) const;
|
|
bool hasProperty(Runtime& runtime, const char* name) const;
|
|
bool hasProperty(Runtime& runtime, const String& name) const;
|
|
bool hasProperty(Runtime& runtime, const PropNameID& name) const;
|
|
template <typename T>
|
|
void setProperty(Runtime& runtime, const char* name, T&& value) const;
|
|
template <typename T>
|
|
void setProperty(Runtime& runtime, const String& name, T&& value) const;
|
|
template <typename T>
|
|
void setProperty(Runtime& runtime, const PropNameID& name, T&& value) const;
|
|
bool isArray(Runtime& runtime) const {
|
|
return runtime.isArray(*this);
|
|
}
|
|
bool isArrayBuffer(Runtime& runtime) const {
|
|
return runtime.isArrayBuffer(*this);
|
|
}
|
|
bool isFunction(Runtime& runtime) const {
|
|
return runtime.isFunction(*this);
|
|
}
|
|
template <typename T = HostObject>
|
|
bool isHostObject(Runtime& runtime) const;
|
|
Array getArray(Runtime& runtime) const&;
|
|
Array getArray(Runtime& runtime) &&;
|
|
Array asArray(Runtime& runtime) const&;
|
|
Array asArray(Runtime& runtime) &&;
|
|
ArrayBuffer getArrayBuffer(Runtime& runtime) const&;
|
|
ArrayBuffer getArrayBuffer(Runtime& runtime) &&;
|
|
Function getFunction(Runtime& runtime) const&;
|
|
Function getFunction(Runtime& runtime) &&;
|
|
Function asFunction(Runtime& runtime) const&;
|
|
Function asFunction(Runtime& runtime) &&;
|
|
template <typename T = HostObject>
|
|
std::shared_ptr<T> getHostObject(Runtime& runtime) const;
|
|
template <typename T = HostObject>
|
|
std::shared_ptr<T> asHostObject(Runtime& runtime) const;
|
|
template <typename T = NativeState>
|
|
bool hasNativeState(Runtime& runtime) const;
|
|
template <typename T = NativeState>
|
|
std::shared_ptr<T> getNativeState(Runtime& runtime) const;
|
|
void setNativeState(Runtime& runtime, std::shared_ptr<NativeState> state)
|
|
const;
|
|
Object getPropertyAsObject(Runtime& runtime, const char* name) const;
|
|
Function getPropertyAsFunction(Runtime& runtime, const char* name) const;
|
|
Array getPropertyNames(Runtime& runtime) const;
|
|
void setExternalMemoryPressure(Runtime& runtime, size_t amt) const;
|
|
|
|
protected:
|
|
void setPropertyValue(
|
|
Runtime& runtime,
|
|
const String& name,
|
|
const Value& value) const {
|
|
return runtime.setPropertyValue(*this, name, value);
|
|
}
|
|
void setPropertyValue(
|
|
Runtime& runtime,
|
|
const PropNameID& name,
|
|
const Value& value) const {
|
|
return runtime.setPropertyValue(*this, name, value);
|
|
}
|
|
friend
|
|
friend
|
|
class __attribute__((visibility("default"))) WeakObject : public Pointer {
|
|
public:
|
|
using Pointer::Pointer;
|
|
WeakObject(WeakObject&& other) = default;
|
|
WeakObject& operator=(WeakObject&& other) = default;
|
|
WeakObject(Runtime& runtime, const Object& o)
|
|
: WeakObject(runtime.createWeakObject(o)) {}
|
|
Value lock(Runtime& runtime) const;
|
|
friend
|
|
class __attribute__((visibility("default"))) Array : public Object {
|
|
public:
|
|
Array(Array&&) = default;
|
|
Array(Runtime& runtime, size_t length) : Array(runtime.createArray(length)) {}
|
|
Array& operator=(Array&&) = default;
|
|
size_t size(Runtime& runtime) const {
|
|
return runtime.size(*this);
|
|
}
|
|
size_t length(Runtime& runtime) const {
|
|
return size(runtime);
|
|
}
|
|
Value getValueAtIndex(Runtime& runtime, size_t i) const;
|
|
template <typename T>
|
|
void setValueAtIndex(Runtime& runtime, size_t i, T&& value) const;
|
|
template <typename... Args>
|
|
static Array createWithElements(Runtime&, Args&&... args);
|
|
static Array createWithElements(
|
|
Runtime& runtime,
|
|
std::initializer_list<Value> elements);
|
|
};
|
|
class __attribute__((visibility("default"))) ArrayBuffer : public Object {
|
|
public:
|
|
ArrayBuffer(ArrayBuffer&&) = default;
|
|
ArrayBuffer& operator=(ArrayBuffer&&) = default;
|
|
ArrayBuffer(Runtime& runtime, std::shared_ptr<MutableBuffer> buffer)
|
|
: ArrayBuffer(runtime.createArrayBuffer(std::move(buffer))) {}
|
|
size_t size(Runtime& runtime) const {
|
|
return runtime.size(*this);
|
|
}
|
|
size_t length(Runtime& runtime) const {
|
|
return runtime.size(*this);
|
|
}
|
|
uint8_t* data(Runtime& runtime) const {
|
|
return runtime.data(*this);
|
|
}
|
|
};
|
|
class __attribute__((visibility("default"))) Function : public Object {
|
|
public:
|
|
Function(Function&&) = default;
|
|
Function& operator=(Function&&) = default;
|
|
static Function createFromHostFunction(
|
|
Runtime& runtime,
|
|
const jsi::PropNameID& name,
|
|
unsigned int paramCount,
|
|
jsi::HostFunctionType func);
|
|
Value call(Runtime& runtime, const Value* args, size_t count) const;
|
|
Value call(Runtime& runtime, std::initializer_list<Value> args) const;
|
|
template <typename... Args>
|
|
Value call(Runtime& runtime, Args&&... args) const;
|
|
Value callWithThis(
|
|
Runtime& Runtime,
|
|
const Object& jsThis,
|
|
const Value* args,
|
|
size_t count) const;
|
|
Value callWithThis(
|
|
Runtime& runtime,
|
|
const Object& jsThis,
|
|
std::initializer_list<Value> args) const;
|
|
template <typename... Args>
|
|
Value callWithThis(Runtime& runtime, const Object& jsThis, Args&&... args)
|
|
const;
|
|
Value callAsConstructor(Runtime& runtime, const Value* args, size_t count)
|
|
const;
|
|
Value callAsConstructor(Runtime& runtime, std::initializer_list<Value> args)
|
|
const;
|
|
template <typename... Args>
|
|
Value callAsConstructor(Runtime& runtime, Args&&... args) const;
|
|
bool isHostFunction(Runtime& runtime) const {
|
|
return runtime.isHostFunction(*this);
|
|
}
|
|
HostFunctionType& getHostFunction(Runtime& runtime) const {
|
|
assert(isHostFunction(runtime));
|
|
return runtime.getHostFunction(*this);
|
|
}
|
|
};
|
|
class __attribute__((visibility("default"))) Value {
|
|
public:
|
|
Value() noexcept : Value(UndefinedKind) {}
|
|
Value(std::nullptr_t) : kind_(NullKind) {}
|
|
Value(bool b) : Value(BooleanKind) {
|
|
data_.boolean = b;
|
|
}
|
|
Value(double d) : Value(NumberKind) {
|
|
data_.number = d;
|
|
}
|
|
Value(int i) : Value(NumberKind) {
|
|
data_.number = i;
|
|
}
|
|
template <
|
|
typename T,
|
|
typename = std::enable_if_t<
|
|
std::is_base_of<Symbol, T>::value ||
|
|
std::is_base_of<BigInt, T>::value ||
|
|
std::is_base_of<String, T>::value ||
|
|
std::is_base_of<Object, T>::value>>
|
|
Value(T&& other) : Value(kindOf(other)) {
|
|
new (&data_.pointer) T(std::move(other));
|
|
}
|
|
template <typename T = void>
|
|
Value(const char*) {
|
|
static_assert(
|
|
!std::is_same<void, T>::value,
|
|
"Value cannot be constructed directly from const char*");
|
|
}
|
|
Value(Value&& other) noexcept;
|
|
Value(Runtime& runtime, const Symbol& sym) : Value(SymbolKind) {
|
|
new (&data_.pointer) Symbol(runtime.cloneSymbol(sym.ptr_));
|
|
}
|
|
Value(Runtime& runtime, const BigInt& bigint) : Value(BigIntKind) {
|
|
new (&data_.pointer) BigInt(runtime.cloneBigInt(bigint.ptr_));
|
|
}
|
|
Value(Runtime& runtime, const String& str) : Value(StringKind) {
|
|
new (&data_.pointer) String(runtime.cloneString(str.ptr_));
|
|
}
|
|
Value(Runtime& runtime, const Object& obj) : Value(ObjectKind) {
|
|
new (&data_.pointer) Object(runtime.cloneObject(obj.ptr_));
|
|
}
|
|
Value(Runtime& runtime, const Value& value);
|
|
template <typename T = void>
|
|
Value(Runtime&, const char*) {
|
|
static_assert(
|
|
!std::is_same<T, void>::value,
|
|
"Value cannot be constructed directly from const char*");
|
|
}
|
|
~Value();
|
|
static Value undefined() {
|
|
return Value();
|
|
}
|
|
static Value null() {
|
|
return Value(nullptr);
|
|
}
|
|
static Value
|
|
createFromJsonUtf8(Runtime& runtime, const uint8_t* json, size_t length) {
|
|
return runtime.createValueFromJsonUtf8(json, length);
|
|
}
|
|
static bool strictEquals(Runtime& runtime, const Value& a, const Value& b);
|
|
Value& operator=(Value&& other) noexcept {
|
|
this->~Value();
|
|
new (this) Value(std::move(other));
|
|
return *this;
|
|
}
|
|
bool isUndefined() const {
|
|
return kind_ == UndefinedKind;
|
|
}
|
|
bool isNull() const {
|
|
return kind_ == NullKind;
|
|
}
|
|
bool isBool() const {
|
|
return kind_ == BooleanKind;
|
|
}
|
|
bool isNumber() const {
|
|
return kind_ == NumberKind;
|
|
}
|
|
bool isString() const {
|
|
return kind_ == StringKind;
|
|
}
|
|
bool isBigInt() const {
|
|
return kind_ == BigIntKind;
|
|
}
|
|
bool isSymbol() const {
|
|
return kind_ == SymbolKind;
|
|
}
|
|
bool isObject() const {
|
|
return kind_ == ObjectKind;
|
|
}
|
|
bool getBool() const {
|
|
assert(isBool());
|
|
return data_.boolean;
|
|
}
|
|
bool asBool() const;
|
|
double getNumber() const {
|
|
assert(isNumber());
|
|
return data_.number;
|
|
}
|
|
double asNumber() const;
|
|
Symbol getSymbol(Runtime& runtime) const& {
|
|
assert(isSymbol());
|
|
return Symbol(runtime.cloneSymbol(data_.pointer.ptr_));
|
|
}
|
|
Symbol getSymbol(Runtime&) && {
|
|
assert(isSymbol());
|
|
auto ptr = data_.pointer.ptr_;
|
|
data_.pointer.ptr_ = nullptr;
|
|
return static_cast<Symbol>(ptr);
|
|
}
|
|
Symbol asSymbol(Runtime& runtime) const&;
|
|
Symbol asSymbol(Runtime& runtime) &&;
|
|
BigInt getBigInt(Runtime& runtime) const& {
|
|
assert(isBigInt());
|
|
return BigInt(runtime.cloneBigInt(data_.pointer.ptr_));
|
|
}
|
|
BigInt getBigInt(Runtime&) && {
|
|
assert(isBigInt());
|
|
auto ptr = data_.pointer.ptr_;
|
|
data_.pointer.ptr_ = nullptr;
|
|
return static_cast<BigInt>(ptr);
|
|
}
|
|
BigInt asBigInt(Runtime& runtime) const&;
|
|
BigInt asBigInt(Runtime& runtime) &&;
|
|
String getString(Runtime& runtime) const& {
|
|
assert(isString());
|
|
return String(runtime.cloneString(data_.pointer.ptr_));
|
|
}
|
|
String getString(Runtime&) && {
|
|
assert(isString());
|
|
auto ptr = data_.pointer.ptr_;
|
|
data_.pointer.ptr_ = nullptr;
|
|
return static_cast<String>(ptr);
|
|
}
|
|
String asString(Runtime& runtime) const&;
|
|
String asString(Runtime& runtime) &&;
|
|
Object getObject(Runtime& runtime) const& {
|
|
assert(isObject());
|
|
return Object(runtime.cloneObject(data_.pointer.ptr_));
|
|
}
|
|
Object getObject(Runtime&) && {
|
|
assert(isObject());
|
|
auto ptr = data_.pointer.ptr_;
|
|
data_.pointer.ptr_ = nullptr;
|
|
return static_cast<Object>(ptr);
|
|
}
|
|
Object asObject(Runtime& runtime) const&;
|
|
Object asObject(Runtime& runtime) &&;
|
|
String toString(Runtime& runtime) const;
|
|
};
|
|
union Data {
|
|
Data() {
|
|
static_assert(
|
|
sizeof(Data) == sizeof(uint64_t),
|
|
"Value data should fit in a 64-bit register");
|
|
}
|
|
~Data() {}
|
|
bool boolean;
|
|
double number;
|
|
Pointer pointer;
|
|
};
|
|
Value(ValueKind kind) : kind_(kind) {}
|
|
constexpr static ValueKind kindOf(const Symbol&) {
|
|
return SymbolKind;
|
|
}
|
|
constexpr static ValueKind kindOf(const BigInt&) {
|
|
return BigIntKind;
|
|
}
|
|
constexpr static ValueKind kindOf(const String&) {
|
|
return StringKind;
|
|
}
|
|
constexpr static ValueKind kindOf(const Object&) {
|
|
return ObjectKind;
|
|
}
|
|
ValueKind kind_;
|
|
Data data_;
|
|
};
|
|
class __attribute__((visibility("default"))) Scope {
|
|
public:
|
|
explicit Scope(Runtime& rt) : rt_(rt), prv_(rt.pushScope()) {}
|
|
~Scope() {
|
|
rt_.popScope(prv_);
|
|
}
|
|
Scope(const Scope&) = delete;
|
|
Scope(Scope&&) = delete;
|
|
Scope& operator=(const Scope&) = delete;
|
|
Scope& operator=(Scope&&) = delete;
|
|
template <typename F>
|
|
static auto callInNewScope(Runtime& rt, F f) -> decltype(f()) {
|
|
Scope s(rt);
|
|
return f();
|
|
}
|
|
};
|
|
class __attribute__((visibility("default"))) JSIException
|
|
: public std::exception {
|
|
protected:
|
|
JSIException() {}
|
|
JSIException(std::string what) : what_(std::move(what)) {}
|
|
|
|
public:
|
|
JSIException(const JSIException&) = default;
|
|
virtual const char* what() const noexcept override {
|
|
return what_.c_str();
|
|
}
|
|
virtual ~JSIException() override;
|
|
|
|
protected:
|
|
std::string what_;
|
|
};
|
|
class __attribute__((visibility("default"))) JSINativeException
|
|
: public JSIException {
|
|
public:
|
|
JSINativeException(std::string what) : JSIException(std::move(what)) {}
|
|
JSINativeException(const JSINativeException&) = default;
|
|
virtual ~JSINativeException();
|
|
};
|
|
class __attribute__((visibility("default"))) JSError : public JSIException {
|
|
public:
|
|
JSError(Runtime& r, Value&& value);
|
|
JSError(Runtime& rt, std::string message);
|
|
JSError(Runtime& rt, const char* message)
|
|
: JSError(rt, std::string(message)) {}
|
|
JSError(Runtime& rt, std::string message, std::string stack);
|
|
JSError(std::string what, Runtime& rt, Value&& value);
|
|
JSError(Value&& value, std::string message, std::string stack);
|
|
JSError(const JSError&) = default;
|
|
virtual ~JSError();
|
|
const std::string& getStack() const {
|
|
return stack_;
|
|
}
|
|
const std::string& getMessage() const {
|
|
return message_;
|
|
}
|
|
const jsi::Value& value() const {
|
|
assert(value_);
|
|
return *value_;
|
|
}
|
|
};
|
|
template <typename U, typename T>
|
|
U* castInterface(T* ptr) {
|
|
if (ptr) {
|
|
return static_cast<U*>(ptr->castInterface(U::uuid));
|
|
}
|
|
return nullptr;
|
|
};
|
|
template <typename U, typename T>
|
|
std::shared_ptr<U> dynamicInterfaceCast(T&& ptr) {
|
|
auto* p = ptr->castInterface(U::uuid);
|
|
U* res = static_cast<U*>(p);
|
|
if (res) {
|
|
return std::shared_ptr<U>(std::forward<T>(ptr), res);
|
|
}
|
|
return nullptr;
|
|
}
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/jsilib.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
class FileBuffer : public Buffer {
|
|
public:
|
|
FileBuffer(const std::string& path);
|
|
~FileBuffer() override;
|
|
size_t size() const override {
|
|
return size_;
|
|
}
|
|
const uint8_t* data() const override {
|
|
return data_;
|
|
}
|
|
};
|
|
class SourceJavaScriptPreparation final : public jsi::PreparedJavaScript,
|
|
public jsi::Buffer {
|
|
std::shared_ptr<const jsi::Buffer> buf_;
|
|
std::string sourceURL_;
|
|
|
|
public:
|
|
SourceJavaScriptPreparation(
|
|
std::shared_ptr<const jsi::Buffer> buf,
|
|
std::string sourceURL)
|
|
: buf_(std::move(buf)), sourceURL_(std::move(sourceURL)) {}
|
|
const std::string& sourceURL() const {
|
|
return sourceURL_;
|
|
}
|
|
size_t size() const override {
|
|
return buf_->size();
|
|
}
|
|
const uint8_t* data() const override {
|
|
return buf_->data();
|
|
}
|
|
};
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/test/testlib.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
using RuntimeFactory = std::function<std::shared_ptr<Runtime>()>;
|
|
std::vector<RuntimeFactory> runtimeGenerators();
|
|
class JSITestBase : public ::testing::TestWithParam<RuntimeFactory> {
|
|
public:
|
|
JSITestBase() : factory(GetParam()), runtime(factory()), rt(*runtime) {}
|
|
Value eval(const char* code) {
|
|
return rt.global().getPropertyAsFunction(rt, "eval").call(rt, code);
|
|
}
|
|
Function function(const std::string& code) {
|
|
return eval(("(" + code + ")").c_str()).getObject(rt).getFunction(rt);
|
|
}
|
|
bool checkValue(const Value& value, const std::string& jsValue) {
|
|
return function("function(value) { return value == " + jsValue + "; }")
|
|
.call(rt, std::move(value))
|
|
.getBool();
|
|
}
|
|
RuntimeFactory factory;
|
|
std::shared_ptr<Runtime> runtime;
|
|
Runtime& rt;
|
|
};
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsi/jsi/threadsafe.h}:
|
|
namespace facebook {
|
|
namespace jsi {
|
|
class ThreadSafeRuntime : public Runtime {
|
|
public:
|
|
virtual void lock() const = 0;
|
|
virtual void unlock() const = 0;
|
|
virtual Runtime& getUnsafeRuntime() = 0;
|
|
};
|
|
namespace detail {
|
|
template <typename R, typename L>
|
|
struct WithLock {
|
|
L lock;
|
|
WithLock(R& r) : lock(r) {}
|
|
void before() {
|
|
lock.lock();
|
|
}
|
|
void after() {
|
|
lock.unlock();
|
|
}
|
|
};
|
|
template <typename R, typename L>
|
|
class ThreadSafeRuntimeImpl final
|
|
: public WithRuntimeDecorator<WithLock<R, L>, R, ThreadSafeRuntime> {
|
|
public:
|
|
template <typename... Args>
|
|
ThreadSafeRuntimeImpl(Args&&... args)
|
|
: WithRuntimeDecorator<WithLock<R, L>, R, ThreadSafeRuntime>(
|
|
unsafe_,
|
|
lock_),
|
|
unsafe_(std::forward<Args>(args)...),
|
|
lock_(unsafe_) {}
|
|
R& getUnsafeRuntime() override {
|
|
return WithRuntimeDecorator<WithLock<R, L>, R, ThreadSafeRuntime>::plain();
|
|
}
|
|
void lock() const override {
|
|
lock_.before();
|
|
}
|
|
void unlock() const override {
|
|
lock_.after();
|
|
}
|
|
};
|
|
} // namespace detail
|
|
} // namespace jsi
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsiexecutor/jsireact/JSIExecutor.h}:
|
|
namespace facebook::react {
|
|
using JSIScopedTimeoutInvoker = std::function<void(
|
|
const std::function<void()>& invokee,
|
|
std::function<std::string()> errorMessageProducer)>;
|
|
class BigStringBuffer : public jsi::Buffer {
|
|
public:
|
|
BigStringBuffer(std::unique_ptr<const JSBigString> script)
|
|
: script_(std::move(script)) {}
|
|
size_t size() const override {
|
|
return script_->size();
|
|
}
|
|
const uint8_t* data() const override {
|
|
return reinterpret_cast<const uint8_t*>(script_->c_str());
|
|
}
|
|
};
|
|
class JSIExecutor : public JSExecutor {
|
|
public:
|
|
using RuntimeInstaller = std::function<void(jsi::Runtime& runtime)>;
|
|
JSIExecutor(
|
|
std::shared_ptr<jsi::Runtime> runtime,
|
|
std::shared_ptr<ExecutorDelegate> delegate,
|
|
const JSIScopedTimeoutInvoker& timeoutInvoker,
|
|
RuntimeInstaller runtimeInstaller);
|
|
void initializeRuntime() override;
|
|
void loadBundle(
|
|
std::unique_ptr<const JSBigString> script,
|
|
std::string sourceURL) override;
|
|
void setBundleRegistry(std::unique_ptr<RAMBundleRegistry>) override;
|
|
void registerBundle(uint32_t bundleId, const std::string& bundlePath)
|
|
override;
|
|
void callFunction(
|
|
const std::string& moduleId,
|
|
const std::string& methodId,
|
|
const folly::dynamic& arguments) override;
|
|
void invokeCallback(const double callbackId, const folly::dynamic& arguments)
|
|
override;
|
|
void setGlobalVariable(
|
|
std::string propName,
|
|
std::unique_ptr<const JSBigString> jsonValue) override;
|
|
std::string getDescription() override;
|
|
void* getJavaScriptContext() override;
|
|
bool isInspectable() override;
|
|
void handleMemoryPressure(int pressureLevel) override;
|
|
static void defaultTimeoutInvoker(
|
|
const std::function<void()>& invokee,
|
|
std::function<std::string()> errorMessageProducer) {
|
|
(void)errorMessageProducer;
|
|
invokee();
|
|
}
|
|
void flush() override;
|
|
};
|
|
using Logger =
|
|
std::function<void(const std::string& message, unsigned int logLevel)>;
|
|
void bindNativeLogger(jsi::Runtime& runtime, Logger logger);
|
|
void bindNativePerformanceNow(jsi::Runtime& runtime);
|
|
double performanceNow();
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsiexecutor/jsireact/JSINativeModules.h}:
|
|
namespace facebook::react {
|
|
class JSINativeModules {
|
|
public:
|
|
explicit JSINativeModules(std::shared_ptr<ModuleRegistry> moduleRegistry);
|
|
jsi::Value getModule(jsi::Runtime& rt, const jsi::PropNameID& name);
|
|
void reset();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/Base64.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
namespace {
|
|
constexpr char kBase64Charset[] =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
constexpr char kBase64URLCharset[] =
|
|
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
|
|
template <bool isURL>
|
|
struct Base64ScalarImpl {
|
|
static constexpr const char* kCharset =
|
|
isURL ? kBase64URLCharset : kBase64Charset;
|
|
static constexpr char* encodeTail(const char* f, const char* l, char* o) {
|
|
if (f == l) {
|
|
return o;
|
|
}
|
|
std::uint8_t aaab = f[0];
|
|
std::uint8_t aaa = aaab >> 2;
|
|
*o++ = kCharset[aaa];
|
|
if (l - f == 1) {
|
|
std::uint8_t b00 = aaab << 4 & 0x3f;
|
|
*o++ = kCharset[b00];
|
|
if constexpr (!isURL) {
|
|
*o++ = '=';
|
|
*o++ = '=';
|
|
}
|
|
return o;
|
|
}
|
|
std::uint8_t bbcc = f[1];
|
|
std::uint8_t bbb = ((aaab << 4) | (bbcc >> 4)) & 0x3f;
|
|
std::uint8_t cc0 = (bbcc << 2) & 0x3f;
|
|
*o++ = kCharset[bbb];
|
|
*o++ = kCharset[cc0];
|
|
if constexpr (!isURL) {
|
|
*o++ = '=';
|
|
}
|
|
return o;
|
|
}
|
|
static constexpr char* encode(const char* f, const char* l, char* o) {
|
|
while ((l - f) >= 3) {
|
|
std::uint8_t aaab = f[0];
|
|
std::uint8_t bbcc = f[1];
|
|
std::uint8_t cddd = f[2];
|
|
std::uint8_t aaa = aaab >> 2;
|
|
std::uint8_t bbb = ((aaab << 4) | (bbcc >> 4)) & 0x3f;
|
|
std::uint8_t ccc = ((bbcc << 2) | (cddd >> 6)) & 0x3f;
|
|
std::uint8_t ddd = cddd & 0x3f;
|
|
o[0] = kCharset[aaa];
|
|
o[1] = kCharset[bbb];
|
|
o[2] = kCharset[ccc];
|
|
o[3] = kCharset[ddd];
|
|
f += 3;
|
|
o += 4;
|
|
}
|
|
return encodeTail(f, l, o);
|
|
}
|
|
};
|
|
constexpr std::size_t base64EncodedSize(std::size_t inSize) {
|
|
return ((inSize + 2) / 3) * 4;
|
|
}
|
|
} // namespace
|
|
inline std::string base64Encode(const std::string_view s) {
|
|
std::string res(base64EncodedSize(s.size()), '\0');
|
|
Base64ScalarImpl<false>::encode(s.data(), s.data() + s.size(), res.data());
|
|
return res;
|
|
}
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/StackTrace.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
enum class ConsoleAPIType {
|
|
kLog,
|
|
kDebug,
|
|
kInfo,
|
|
kError,
|
|
kWarning,
|
|
kDir,
|
|
kDirXML,
|
|
kTable,
|
|
kTrace,
|
|
kStartGroup,
|
|
kStartGroupCollapsed,
|
|
kEndGroup,
|
|
kClear,
|
|
kAssert,
|
|
kTimeEnd,
|
|
kCount
|
|
};
|
|
struct SimpleConsoleMessage {
|
|
double timestamp;
|
|
ConsoleAPIType type;
|
|
std::vector<std::string> args;
|
|
SimpleConsoleMessage(
|
|
double timestamp,
|
|
ConsoleAPIType type,
|
|
std::vector<std::string> args);
|
|
SimpleConsoleMessage(ConsoleAPIType type, std::vector<std::string> args);
|
|
SimpleConsoleMessage(const SimpleConsoleMessage& other) = delete;
|
|
SimpleConsoleMessage(SimpleConsoleMessage&& other) noexcept = default;
|
|
SimpleConsoleMessage& operator=(const SimpleConsoleMessage& other) = delete;
|
|
SimpleConsoleMessage& operator=(SimpleConsoleMessage&& other) noexcept =
|
|
default;
|
|
~SimpleConsoleMessage() = default;
|
|
};
|
|
struct ConsoleMessage {
|
|
double timestamp;
|
|
ConsoleAPIType type;
|
|
std::vector<jsi::Value> args;
|
|
std::unique_ptr<StackTrace> stackTrace;
|
|
ConsoleMessage(
|
|
double timestamp,
|
|
ConsoleAPIType type,
|
|
std::vector<jsi::Value> args,
|
|
std::unique_ptr<StackTrace> stackTrace = StackTrace::empty())
|
|
: timestamp(timestamp),
|
|
type(type),
|
|
args(std::move(args)),
|
|
stackTrace(std::move(stackTrace)) {}
|
|
ConsoleMessage(jsi::Runtime& runtime, SimpleConsoleMessage message);
|
|
ConsoleMessage(const ConsoleMessage& other) = delete;
|
|
ConsoleMessage(ConsoleMessage&& other) noexcept = default;
|
|
ConsoleMessage& operator=(const ConsoleMessage& other) = delete;
|
|
ConsoleMessage& operator=(ConsoleMessage&& other) noexcept = default;
|
|
~ConsoleMessage() = default;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/UniqueMonostate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct ExecutionContextDescription {
|
|
int32_t id{};
|
|
std::string origin;
|
|
std::string name{"<anonymous>"};
|
|
std::optional<std::string> uniqueId;
|
|
};
|
|
class ExecutionContextSelector {
|
|
public:
|
|
bool matches(const ExecutionContextDescription& context) const noexcept;
|
|
static ExecutionContextSelector byId(int32_t id);
|
|
static ExecutionContextSelector byName(std::string name);
|
|
static ExecutionContextSelector all();
|
|
ExecutionContextSelector() = delete;
|
|
ExecutionContextSelector(const ExecutionContextSelector& other) = default;
|
|
ExecutionContextSelector(ExecutionContextSelector&& other) noexcept = default;
|
|
ExecutionContextSelector& operator=(const ExecutionContextSelector& other) =
|
|
default;
|
|
ExecutionContextSelector& operator=(
|
|
ExecutionContextSelector&& other) noexcept = default;
|
|
~ExecutionContextSelector() = default;
|
|
inline bool operator==(const ExecutionContextSelector& other) const noexcept {
|
|
return value_ == other.value_;
|
|
}
|
|
};
|
|
using ExecutionContextSelectorSet =
|
|
std::unordered_set<ExecutionContextSelector>;
|
|
bool matchesAny(
|
|
const ExecutionContextDescription& context,
|
|
const ExecutionContextSelectorSet& selectors);
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace std {
|
|
template <>
|
|
struct hash<::facebook::react::jsinspector_modern::ExecutionContextSelector> {
|
|
size_t operator()(
|
|
const ::facebook::react::jsinspector_modern::ExecutionContextSelector&
|
|
selector) const {
|
|
return hash<::facebook::react::jsinspector_modern::
|
|
ExecutionContextSelector::Representation>{}(
|
|
selector.value_);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContextManager.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class ExecutionContextManager {
|
|
public:
|
|
int32_t allocateExecutionContextId();
|
|
};
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/FallbackRuntimeAgentDelegate.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class FallbackRuntimeAgentDelegate : public RuntimeAgentDelegate {
|
|
public:
|
|
FallbackRuntimeAgentDelegate(
|
|
FrontendChannel frontendChannel,
|
|
const SessionState& sessionState,
|
|
std::string engineDescription);
|
|
bool handleRequest(const cdp::PreparsedRequest& req) override;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/FallbackRuntimeTargetDelegate.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class FallbackRuntimeTargetDelegate : public RuntimeTargetDelegate {
|
|
public:
|
|
explicit FallbackRuntimeTargetDelegate(std::string engineDescription);
|
|
std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) override;
|
|
void addConsoleMessage(jsi::Runtime& runtime, ConsoleMessage message)
|
|
override;
|
|
bool supportsConsole() const override;
|
|
std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip) override;
|
|
void enableSamplingProfiler() override;
|
|
void disableSamplingProfiler() override;
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile() override;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/HostAgent.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContextManager.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/HostCommand.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InstanceTargetDelegate {
|
|
public:
|
|
InstanceTargetDelegate() = default;
|
|
InstanceTargetDelegate(const InstanceTargetDelegate&) = delete;
|
|
InstanceTargetDelegate(InstanceTargetDelegate&&) = default;
|
|
InstanceTargetDelegate& operator=(const InstanceTargetDelegate&) = delete;
|
|
InstanceTargetDelegate& operator=(InstanceTargetDelegate&&) = default;
|
|
virtual ~InstanceTargetDelegate();
|
|
};
|
|
class InstanceTarget : public EnableExecutorFromThis<InstanceTarget> {
|
|
public:
|
|
static std::shared_ptr<InstanceTarget> create(
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager,
|
|
InstanceTargetDelegate& delegate,
|
|
VoidExecutor executor);
|
|
InstanceTarget(const InstanceTarget&) = delete;
|
|
InstanceTarget(InstanceTarget&&) = delete;
|
|
InstanceTarget& operator=(const InstanceTarget&) = delete;
|
|
InstanceTarget& operator=(InstanceTarget&&) = delete;
|
|
~InstanceTarget();
|
|
std::shared_ptr<InstanceAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
RuntimeTarget& registerRuntime(
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor executor);
|
|
void unregisterRuntime(RuntimeTarget& runtime);
|
|
};
|
|
WeakList<InstanceAgent> agents_;
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager_;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
using StreamID = const std::string;
|
|
using Headers = std::map<std::string, std::string>;
|
|
using IOReadError = const std::string;
|
|
namespace {
|
|
using StreamsMap = std::unordered_map<std::string, std::shared_ptr<Stream>>;
|
|
} // namespace
|
|
struct LoadNetworkResourceRequest {
|
|
std::string url;
|
|
};
|
|
struct ReadStreamParams {
|
|
StreamID handle;
|
|
std::optional<unsigned long> size;
|
|
std::optional<unsigned long> offset;
|
|
};
|
|
struct NetworkResource {
|
|
bool success{};
|
|
std::optional<std::string> stream;
|
|
std::optional<uint32_t> httpStatusCode;
|
|
std::optional<std::string> netErrorName;
|
|
std::optional<Headers> headers;
|
|
folly::dynamic toDynamic() const {
|
|
auto dynamicResource = folly::dynamic::object("success", success);
|
|
if (success) {
|
|
assert(stream);
|
|
dynamicResource("stream", *stream);
|
|
}
|
|
if (netErrorName) {
|
|
assert(!success);
|
|
dynamicResource("netErrorName", *netErrorName);
|
|
}
|
|
if (httpStatusCode) {
|
|
dynamicResource("httpStatusCode", *httpStatusCode);
|
|
} else {
|
|
assert(!success);
|
|
}
|
|
if (headers) {
|
|
auto dynamicHeaders = folly::dynamic::object();
|
|
for (const auto& pair : *headers) {
|
|
dynamicHeaders(pair.first, pair.second);
|
|
}
|
|
dynamicResource("headers", std::move(dynamicHeaders));
|
|
} else {
|
|
assert(!success);
|
|
}
|
|
return dynamicResource;
|
|
}
|
|
};
|
|
struct IOReadResult {
|
|
std::string data;
|
|
bool eof;
|
|
bool base64Encoded;
|
|
folly::dynamic toDynamic() const {
|
|
auto obj = folly::dynamic::object("data", data);
|
|
obj("eof", eof);
|
|
obj("base64Encoded", base64Encoded);
|
|
return obj;
|
|
}
|
|
};
|
|
struct GetResponseBodyResult {
|
|
std::string body;
|
|
bool base64Encoded;
|
|
folly::dynamic toDynamic() const {
|
|
folly::dynamic params = folly::dynamic::object;
|
|
params["body"] = body;
|
|
params["base64Encoded"] = base64Encoded;
|
|
return params;
|
|
}
|
|
};
|
|
class NetworkRequestListener {
|
|
public:
|
|
NetworkRequestListener() = default;
|
|
NetworkRequestListener(const NetworkRequestListener&) = delete;
|
|
NetworkRequestListener& operator=(const NetworkRequestListener&) = delete;
|
|
NetworkRequestListener(NetworkRequestListener&&) noexcept = default;
|
|
NetworkRequestListener& operator=(NetworkRequestListener&&) noexcept =
|
|
default;
|
|
virtual ~NetworkRequestListener() = default;
|
|
virtual void onHeaders(uint32_t httpStatusCode, const Headers& headers) = 0;
|
|
virtual void onData(std::string_view data) = 0;
|
|
virtual void onError(const std::string& message) = 0;
|
|
virtual void onCompletion() = 0;
|
|
virtual void setCancelFunction(std::function<void()> cancelFunction) = 0;
|
|
};
|
|
class LoadNetworkResourceDelegate {
|
|
public:
|
|
LoadNetworkResourceDelegate() = default;
|
|
LoadNetworkResourceDelegate(const LoadNetworkResourceDelegate&) = delete;
|
|
LoadNetworkResourceDelegate& operator=(const LoadNetworkResourceDelegate&) =
|
|
delete;
|
|
LoadNetworkResourceDelegate(LoadNetworkResourceDelegate&&) noexcept = delete;
|
|
LoadNetworkResourceDelegate& operator=(
|
|
LoadNetworkResourceDelegate&&) noexcept = delete;
|
|
virtual ~LoadNetworkResourceDelegate() = default;
|
|
virtual void loadNetworkResource(
|
|
[[maybe_unused]] const LoadNetworkResourceRequest& params,
|
|
[[maybe_unused]] ScopedExecutor<NetworkRequestListener> executor) = 0;
|
|
};
|
|
class NetworkIOAgent {
|
|
public:
|
|
NetworkIOAgent(FrontendChannel frontendChannel, VoidExecutor executor)
|
|
: frontendChannel_(frontendChannel),
|
|
executor_(executor),
|
|
streams_(std::make_shared<StreamsMap>()) {}
|
|
bool handleRequest(
|
|
const cdp::PreparsedRequest& req,
|
|
LoadNetworkResourceDelegate& delegate);
|
|
};
|
|
void handleLoadNetworkResource(
|
|
const cdp::PreparsedRequest& req,
|
|
LoadNetworkResourceDelegate& delegate);
|
|
void handleIoRead(const cdp::PreparsedRequest& req);
|
|
void handleIoClose(const cdp::PreparsedRequest& req);
|
|
void handleGetResponseBody(const cdp::PreparsedRequest& req);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct HostTargetMetadata {
|
|
std::optional<std::string> appDisplayName;
|
|
std::optional<std::string> appIdentifier;
|
|
std::optional<std::string> deviceName;
|
|
std::optional<std::string> integrationName;
|
|
std::optional<std::string> platform;
|
|
std::optional<std::string> reactNativeVersion;
|
|
};
|
|
class HostTargetDelegate : public LoadNetworkResourceDelegate {
|
|
public:
|
|
HostTargetDelegate() = default;
|
|
HostTargetDelegate(const HostTargetDelegate&) = delete;
|
|
HostTargetDelegate(HostTargetDelegate&&) = delete;
|
|
HostTargetDelegate& operator=(const HostTargetDelegate&) = delete;
|
|
HostTargetDelegate& operator=(HostTargetDelegate&&) = delete;
|
|
struct PageReloadRequest {
|
|
std::optional<bool> ignoreCache;
|
|
std::optional<std::string> scriptToEvaluateOnLoad;
|
|
inline bool operator==(const PageReloadRequest& rhs) const {
|
|
return ignoreCache == rhs.ignoreCache &&
|
|
scriptToEvaluateOnLoad == rhs.scriptToEvaluateOnLoad;
|
|
}
|
|
};
|
|
struct OverlaySetPausedInDebuggerMessageRequest {
|
|
std::optional<std::string> message;
|
|
inline bool operator==(
|
|
const OverlaySetPausedInDebuggerMessageRequest& rhs) const {
|
|
return message == rhs.message;
|
|
}
|
|
};
|
|
virtual ~HostTargetDelegate() override;
|
|
virtual HostTargetMetadata getMetadata() = 0;
|
|
virtual void onReload(const PageReloadRequest& request) = 0;
|
|
virtual void onSetPausedInDebuggerMessage(
|
|
const OverlaySetPausedInDebuggerMessageRequest& request) = 0;
|
|
void loadNetworkResource(
|
|
const LoadNetworkResourceRequest&,
|
|
ScopedExecutor<NetworkRequestListener>) override {
|
|
throw NotImplementedException(
|
|
"LoadNetworkResourceDelegate.loadNetworkResource is not implemented by this host target delegate.");
|
|
}
|
|
};
|
|
class HostTargetController final {
|
|
public:
|
|
explicit HostTargetController(HostTarget& target);
|
|
HostTargetDelegate& getDelegate();
|
|
bool hasInstance() const;
|
|
void incrementPauseOverlayCounter();
|
|
bool decrementPauseOverlayCounter();
|
|
};
|
|
};
|
|
class __attribute__((visibility("default"))) HostTarget
|
|
: public EnableExecutorFromThis<HostTarget> {
|
|
public:
|
|
static std::shared_ptr<HostTarget> create(
|
|
HostTargetDelegate& delegate,
|
|
VoidExecutor executor);
|
|
HostTarget(const HostTarget&) = delete;
|
|
HostTarget(HostTarget&&) = delete;
|
|
HostTarget& operator=(const HostTarget&) = delete;
|
|
HostTarget& operator=(HostTarget&&) = delete;
|
|
~HostTarget();
|
|
std::unique_ptr<ILocalConnection> connect(
|
|
std::unique_ptr<IRemoteConnection> connectionToFrontend);
|
|
InstanceTarget& registerInstance(InstanceTargetDelegate& delegate);
|
|
void unregisterInstance(InstanceTarget& instance);
|
|
void sendCommand(HostCommand command);
|
|
};
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager_;
|
|
std::shared_ptr<InstanceTarget> currentInstance_{nullptr};
|
|
std::unique_ptr<HostCommandSender> commandSender_;
|
|
inline HostTargetDelegate& getDelegate() {
|
|
return delegate_;
|
|
}
|
|
inline bool hasInstance() const {
|
|
return currentInstance_ != nullptr;
|
|
}
|
|
friend
|
|
folly::dynamic createHostMetadataPayload(const HostTargetMetadata& metadata);
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class HostAgent final {
|
|
public:
|
|
HostAgent(
|
|
const FrontendChannel& frontendChannel,
|
|
HostTargetController& targetController,
|
|
HostTargetMetadata hostMetadata,
|
|
SessionState& sessionState,
|
|
VoidExecutor executor);
|
|
HostAgent(const HostAgent&) = delete;
|
|
HostAgent(HostAgent&&) = delete;
|
|
HostAgent& operator=(const HostAgent&) = delete;
|
|
HostAgent& operator=(HostAgent&&) = delete;
|
|
~HostAgent();
|
|
void handleRequest(const cdp::PreparsedRequest& req);
|
|
void setCurrentInstanceAgent(std::shared_ptr<InstanceAgent> agent);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/HostCommand.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
enum class HostCommand { DebuggerResume, DebuggerStepOver };
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/HostTarget.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContextManager.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/HostCommand.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InstanceTargetDelegate {
|
|
public:
|
|
InstanceTargetDelegate() = default;
|
|
InstanceTargetDelegate(const InstanceTargetDelegate&) = delete;
|
|
InstanceTargetDelegate(InstanceTargetDelegate&&) = default;
|
|
InstanceTargetDelegate& operator=(const InstanceTargetDelegate&) = delete;
|
|
InstanceTargetDelegate& operator=(InstanceTargetDelegate&&) = default;
|
|
virtual ~InstanceTargetDelegate();
|
|
};
|
|
class InstanceTarget : public EnableExecutorFromThis<InstanceTarget> {
|
|
public:
|
|
static std::shared_ptr<InstanceTarget> create(
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager,
|
|
InstanceTargetDelegate& delegate,
|
|
VoidExecutor executor);
|
|
InstanceTarget(const InstanceTarget&) = delete;
|
|
InstanceTarget(InstanceTarget&&) = delete;
|
|
InstanceTarget& operator=(const InstanceTarget&) = delete;
|
|
InstanceTarget& operator=(InstanceTarget&&) = delete;
|
|
~InstanceTarget();
|
|
std::shared_ptr<InstanceAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
RuntimeTarget& registerRuntime(
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor executor);
|
|
void unregisterRuntime(RuntimeTarget& runtime);
|
|
};
|
|
WeakList<InstanceAgent> agents_;
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager_;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
using StreamID = const std::string;
|
|
using Headers = std::map<std::string, std::string>;
|
|
using IOReadError = const std::string;
|
|
namespace {
|
|
using StreamsMap = std::unordered_map<std::string, std::shared_ptr<Stream>>;
|
|
} // namespace
|
|
struct LoadNetworkResourceRequest {
|
|
std::string url;
|
|
};
|
|
struct ReadStreamParams {
|
|
StreamID handle;
|
|
std::optional<unsigned long> size;
|
|
std::optional<unsigned long> offset;
|
|
};
|
|
struct NetworkResource {
|
|
bool success{};
|
|
std::optional<std::string> stream;
|
|
std::optional<uint32_t> httpStatusCode;
|
|
std::optional<std::string> netErrorName;
|
|
std::optional<Headers> headers;
|
|
folly::dynamic toDynamic() const {
|
|
auto dynamicResource = folly::dynamic::object("success", success);
|
|
if (success) {
|
|
assert(stream);
|
|
dynamicResource("stream", *stream);
|
|
}
|
|
if (netErrorName) {
|
|
assert(!success);
|
|
dynamicResource("netErrorName", *netErrorName);
|
|
}
|
|
if (httpStatusCode) {
|
|
dynamicResource("httpStatusCode", *httpStatusCode);
|
|
} else {
|
|
assert(!success);
|
|
}
|
|
if (headers) {
|
|
auto dynamicHeaders = folly::dynamic::object();
|
|
for (const auto& pair : *headers) {
|
|
dynamicHeaders(pair.first, pair.second);
|
|
}
|
|
dynamicResource("headers", std::move(dynamicHeaders));
|
|
} else {
|
|
assert(!success);
|
|
}
|
|
return dynamicResource;
|
|
}
|
|
};
|
|
struct IOReadResult {
|
|
std::string data;
|
|
bool eof;
|
|
bool base64Encoded;
|
|
folly::dynamic toDynamic() const {
|
|
auto obj = folly::dynamic::object("data", data);
|
|
obj("eof", eof);
|
|
obj("base64Encoded", base64Encoded);
|
|
return obj;
|
|
}
|
|
};
|
|
struct GetResponseBodyResult {
|
|
std::string body;
|
|
bool base64Encoded;
|
|
folly::dynamic toDynamic() const {
|
|
folly::dynamic params = folly::dynamic::object;
|
|
params["body"] = body;
|
|
params["base64Encoded"] = base64Encoded;
|
|
return params;
|
|
}
|
|
};
|
|
class NetworkRequestListener {
|
|
public:
|
|
NetworkRequestListener() = default;
|
|
NetworkRequestListener(const NetworkRequestListener&) = delete;
|
|
NetworkRequestListener& operator=(const NetworkRequestListener&) = delete;
|
|
NetworkRequestListener(NetworkRequestListener&&) noexcept = default;
|
|
NetworkRequestListener& operator=(NetworkRequestListener&&) noexcept =
|
|
default;
|
|
virtual ~NetworkRequestListener() = default;
|
|
virtual void onHeaders(uint32_t httpStatusCode, const Headers& headers) = 0;
|
|
virtual void onData(std::string_view data) = 0;
|
|
virtual void onError(const std::string& message) = 0;
|
|
virtual void onCompletion() = 0;
|
|
virtual void setCancelFunction(std::function<void()> cancelFunction) = 0;
|
|
};
|
|
class LoadNetworkResourceDelegate {
|
|
public:
|
|
LoadNetworkResourceDelegate() = default;
|
|
LoadNetworkResourceDelegate(const LoadNetworkResourceDelegate&) = delete;
|
|
LoadNetworkResourceDelegate& operator=(const LoadNetworkResourceDelegate&) =
|
|
delete;
|
|
LoadNetworkResourceDelegate(LoadNetworkResourceDelegate&&) noexcept = delete;
|
|
LoadNetworkResourceDelegate& operator=(
|
|
LoadNetworkResourceDelegate&&) noexcept = delete;
|
|
virtual ~LoadNetworkResourceDelegate() = default;
|
|
virtual void loadNetworkResource(
|
|
[[maybe_unused]] const LoadNetworkResourceRequest& params,
|
|
[[maybe_unused]] ScopedExecutor<NetworkRequestListener> executor) = 0;
|
|
};
|
|
class NetworkIOAgent {
|
|
public:
|
|
NetworkIOAgent(FrontendChannel frontendChannel, VoidExecutor executor)
|
|
: frontendChannel_(frontendChannel),
|
|
executor_(executor),
|
|
streams_(std::make_shared<StreamsMap>()) {}
|
|
bool handleRequest(
|
|
const cdp::PreparsedRequest& req,
|
|
LoadNetworkResourceDelegate& delegate);
|
|
};
|
|
void handleLoadNetworkResource(
|
|
const cdp::PreparsedRequest& req,
|
|
LoadNetworkResourceDelegate& delegate);
|
|
void handleIoRead(const cdp::PreparsedRequest& req);
|
|
void handleIoClose(const cdp::PreparsedRequest& req);
|
|
void handleGetResponseBody(const cdp::PreparsedRequest& req);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct HostTargetMetadata {
|
|
std::optional<std::string> appDisplayName;
|
|
std::optional<std::string> appIdentifier;
|
|
std::optional<std::string> deviceName;
|
|
std::optional<std::string> integrationName;
|
|
std::optional<std::string> platform;
|
|
std::optional<std::string> reactNativeVersion;
|
|
};
|
|
class HostTargetDelegate : public LoadNetworkResourceDelegate {
|
|
public:
|
|
HostTargetDelegate() = default;
|
|
HostTargetDelegate(const HostTargetDelegate&) = delete;
|
|
HostTargetDelegate(HostTargetDelegate&&) = delete;
|
|
HostTargetDelegate& operator=(const HostTargetDelegate&) = delete;
|
|
HostTargetDelegate& operator=(HostTargetDelegate&&) = delete;
|
|
struct PageReloadRequest {
|
|
std::optional<bool> ignoreCache;
|
|
std::optional<std::string> scriptToEvaluateOnLoad;
|
|
inline bool operator==(const PageReloadRequest& rhs) const {
|
|
return ignoreCache == rhs.ignoreCache &&
|
|
scriptToEvaluateOnLoad == rhs.scriptToEvaluateOnLoad;
|
|
}
|
|
};
|
|
struct OverlaySetPausedInDebuggerMessageRequest {
|
|
std::optional<std::string> message;
|
|
inline bool operator==(
|
|
const OverlaySetPausedInDebuggerMessageRequest& rhs) const {
|
|
return message == rhs.message;
|
|
}
|
|
};
|
|
virtual ~HostTargetDelegate() override;
|
|
virtual HostTargetMetadata getMetadata() = 0;
|
|
virtual void onReload(const PageReloadRequest& request) = 0;
|
|
virtual void onSetPausedInDebuggerMessage(
|
|
const OverlaySetPausedInDebuggerMessageRequest& request) = 0;
|
|
void loadNetworkResource(
|
|
const LoadNetworkResourceRequest&,
|
|
ScopedExecutor<NetworkRequestListener>) override {
|
|
throw NotImplementedException(
|
|
"LoadNetworkResourceDelegate.loadNetworkResource is not implemented by this host target delegate.");
|
|
}
|
|
};
|
|
class HostTargetController final {
|
|
public:
|
|
explicit HostTargetController(HostTarget& target);
|
|
HostTargetDelegate& getDelegate();
|
|
bool hasInstance() const;
|
|
void incrementPauseOverlayCounter();
|
|
bool decrementPauseOverlayCounter();
|
|
};
|
|
};
|
|
class __attribute__((visibility("default"))) HostTarget
|
|
: public EnableExecutorFromThis<HostTarget> {
|
|
public:
|
|
static std::shared_ptr<HostTarget> create(
|
|
HostTargetDelegate& delegate,
|
|
VoidExecutor executor);
|
|
HostTarget(const HostTarget&) = delete;
|
|
HostTarget(HostTarget&&) = delete;
|
|
HostTarget& operator=(const HostTarget&) = delete;
|
|
HostTarget& operator=(HostTarget&&) = delete;
|
|
~HostTarget();
|
|
std::unique_ptr<ILocalConnection> connect(
|
|
std::unique_ptr<IRemoteConnection> connectionToFrontend);
|
|
InstanceTarget& registerInstance(InstanceTargetDelegate& delegate);
|
|
void unregisterInstance(InstanceTarget& instance);
|
|
void sendCommand(HostCommand command);
|
|
};
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager_;
|
|
std::shared_ptr<InstanceTarget> currentInstance_{nullptr};
|
|
std::unique_ptr<HostCommandSender> commandSender_;
|
|
inline HostTargetDelegate& getDelegate() {
|
|
return delegate_;
|
|
}
|
|
inline bool hasInstance() const {
|
|
return currentInstance_ != nullptr;
|
|
}
|
|
friend
|
|
folly::dynamic createHostMetadataPayload(const HostTargetMetadata& metadata);
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InspectorFlags.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InspectorFlags {
|
|
public:
|
|
static InspectorFlags& getInstance();
|
|
bool getFuseboxEnabled() const;
|
|
bool getIsProfilingBuild() const;
|
|
bool getNetworkInspectionEnabled() const;
|
|
void dangerouslyDisableFuseboxForTest();
|
|
void dangerouslyResetFlags();
|
|
};
|
|
InspectorFlags() = default;
|
|
InspectorFlags(const InspectorFlags&) = delete;
|
|
InspectorFlags& operator=(const InspectorFlags&) = default;
|
|
~InspectorFlags() = default;
|
|
mutable std::optional<Values> cachedValues_;
|
|
mutable bool inconsistentFlagsStateLogged_{false};
|
|
bool fuseboxDisabledForTest_{false};
|
|
const Values& loadFlagsAndAssertUnchanged() const;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class IDestructible {
|
|
public:
|
|
virtual ~IDestructible() = 0;
|
|
};
|
|
struct InspectorTargetCapabilities {
|
|
bool nativePageReloads = false;
|
|
bool nativeSourceCodeFetching = false;
|
|
bool prefersFuseboxFrontend = false;
|
|
};
|
|
folly::dynamic targetCapabilitiesToDynamic(
|
|
const InspectorTargetCapabilities& capabilities);
|
|
struct InspectorPageDescription {
|
|
const int id;
|
|
const std::string description;
|
|
const std::string vm;
|
|
const InspectorTargetCapabilities capabilities;
|
|
};
|
|
using InspectorPage = InspectorPageDescription;
|
|
class __attribute__((visibility("default"))) IRemoteConnection
|
|
: public IDestructible {
|
|
public:
|
|
virtual ~IRemoteConnection() = 0;
|
|
virtual void onMessage(std::string message) = 0;
|
|
virtual void onDisconnect() = 0;
|
|
};
|
|
class __attribute__((visibility("default"))) ILocalConnection
|
|
: public IDestructible {
|
|
public:
|
|
virtual ~ILocalConnection() = 0;
|
|
virtual void sendMessage(std::string message) = 0;
|
|
virtual void disconnect() = 0;
|
|
};
|
|
class __attribute__((visibility("default"))) IPageStatusListener
|
|
: public IDestructible {
|
|
public:
|
|
virtual ~IPageStatusListener() = 0;
|
|
virtual void onPageRemoved(int pageId) = 0;
|
|
};
|
|
class __attribute__((visibility("default"))) IInspector : public IDestructible {
|
|
public:
|
|
using ConnectFunc = std::function<std::unique_ptr<ILocalConnection>(
|
|
std::unique_ptr<IRemoteConnection>)>;
|
|
virtual ~IInspector() = 0;
|
|
virtual int addPage(
|
|
const std::string& description,
|
|
const std::string& vm,
|
|
ConnectFunc connectFunc,
|
|
InspectorTargetCapabilities capabilities = {}) = 0;
|
|
virtual void removePage(int pageId) = 0;
|
|
virtual std::vector<InspectorPageDescription> getPages() const = 0;
|
|
virtual std::unique_ptr<ILocalConnection> connect(
|
|
int pageId,
|
|
std::unique_ptr<IRemoteConnection> remote) = 0;
|
|
virtual void registerPageStatusListener(
|
|
std::weak_ptr<IPageStatusListener> listener) = 0;
|
|
};
|
|
class NotImplementedException : public std::exception {
|
|
public:
|
|
explicit NotImplementedException(std::string message)
|
|
: msg_(std::move(message)) {}
|
|
const char* what() const noexcept override {
|
|
return msg_.c_str();
|
|
}
|
|
};
|
|
extern IInspector& getInspectorInstance();
|
|
extern std::unique_ptr<IInspector> makeTestInspectorInstance();
|
|
using FrontendChannel = std::function<void(std::string_view messageJson)>;
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WebSocketInterfaces.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InspectorPackagerConnection {
|
|
public:
|
|
InspectorPackagerConnection(
|
|
std::string url,
|
|
std::string deviceName,
|
|
std::string appName,
|
|
std::unique_ptr<InspectorPackagerConnectionDelegate> delegate);
|
|
bool isConnected() const;
|
|
void connect();
|
|
void closeQuietly();
|
|
void sendEventToAllConnections(std::string event);
|
|
};
|
|
class InspectorPackagerConnectionDelegate {
|
|
public:
|
|
virtual ~InspectorPackagerConnectionDelegate() = default;
|
|
virtual std::unique_ptr<IWebSocket> connectWebSocket(
|
|
const std::string& url,
|
|
std::weak_ptr<IWebSocketDelegate> delegate) = 0;
|
|
virtual void scheduleCallback(
|
|
std::function<void(void)> callback,
|
|
std::chrono::milliseconds delayMs) = 0;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnectionImpl.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorPackagerConnection.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InspectorPackagerConnection::Impl
|
|
: public IWebSocketDelegate,
|
|
public IPageStatusListener,
|
|
public std::enable_shared_from_this<InspectorPackagerConnection::Impl> {
|
|
public:
|
|
using SessionId = uint32_t;
|
|
static std::shared_ptr<Impl> create(
|
|
std::string url,
|
|
std::string deviceName,
|
|
std::string appName,
|
|
std::unique_ptr<InspectorPackagerConnectionDelegate> delegate);
|
|
bool isConnected() const;
|
|
void connect();
|
|
void closeQuietly();
|
|
void sendEventToAllConnections(std::string event);
|
|
std::unique_ptr<ILocalConnection> removeConnectionForPage(std::string pageId);
|
|
void scheduleSendToPackager(
|
|
folly::dynamic message,
|
|
SessionId sourceSessionId,
|
|
std::string sourcePageId);
|
|
};
|
|
Impl(
|
|
std::string url,
|
|
std::string deviceName,
|
|
std::string appName,
|
|
std::unique_ptr<InspectorPackagerConnectionDelegate> delegate);
|
|
Impl(const Impl&) = delete;
|
|
Impl& operator=(const Impl&) = delete;
|
|
void handleDisconnect(folly::const_dynamic_view payload);
|
|
void handleConnect(folly::const_dynamic_view payload);
|
|
void handleWrappedEvent(folly::const_dynamic_view wrappedEvent);
|
|
void handleProxyMessage(folly::const_dynamic_view message);
|
|
folly::dynamic pages();
|
|
void reconnect();
|
|
void closeAllConnections();
|
|
void disposeWebSocket();
|
|
void sendToPackager(folly::dynamic message);
|
|
void abort(
|
|
std::optional<int> posixCode,
|
|
const std::string& message,
|
|
const std::string& cause);
|
|
virtual void didFailWithError(std::optional<int> posixCode, std::string error)
|
|
override;
|
|
virtual void didReceiveMessage(std::string_view message) override;
|
|
virtual void didOpen() override;
|
|
virtual void didClose() override;
|
|
virtual void onPageRemoved(int pageId) override;
|
|
const std::string url_;
|
|
const std::string deviceName_;
|
|
const std::string appName_;
|
|
const std::unique_ptr<InspectorPackagerConnectionDelegate> delegate_;
|
|
std::unordered_map<std::string, Session> inspectorSessions_;
|
|
std::unique_ptr<IWebSocket> webSocket_;
|
|
bool connected_{false};
|
|
bool closed_{false};
|
|
bool suppressConnectionErrors_{false};
|
|
bool reconnectPending_{false};
|
|
SessionId nextSessionId_{1};
|
|
};
|
|
class InspectorPackagerConnection::Impl::RemoteConnection
|
|
: public IRemoteConnection {
|
|
public:
|
|
RemoteConnection(
|
|
std::weak_ptr<InspectorPackagerConnection::Impl> owningPackagerConnection,
|
|
std::string pageId,
|
|
SessionId sessionId);
|
|
void onMessage(std::string message) override;
|
|
void onDisconnect() override;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InspectorUtilities.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class CallbackLocalConnection : public ILocalConnection {
|
|
public:
|
|
explicit CallbackLocalConnection(std::function<void(std::string)> handler);
|
|
void sendMessage(std::string message) override;
|
|
void disconnect() override;
|
|
};
|
|
class RAIIRemoteConnection {
|
|
public:
|
|
explicit RAIIRemoteConnection(std::unique_ptr<IRemoteConnection> remote);
|
|
void onMessage(std::string message);
|
|
~RAIIRemoteConnection();
|
|
};
|
|
class NullRemoteConnection : public IRemoteConnection {
|
|
inline void onMessage(std::string) override {}
|
|
inline void onDisconnect() override {}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InstanceAgent.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InstanceAgent final {
|
|
public:
|
|
explicit InstanceAgent(
|
|
FrontendChannel frontendChannel,
|
|
InstanceTarget& target,
|
|
SessionState& sessionState);
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
void setCurrentRuntime(RuntimeTarget* runtime);
|
|
void sendConsoleMessage(SimpleConsoleMessage message);
|
|
void startTracing();
|
|
void stopTracing();
|
|
tracing::InstanceTracingProfile collectTracingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/InstanceTarget.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContextManager.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InstanceTargetDelegate {
|
|
public:
|
|
InstanceTargetDelegate() = default;
|
|
InstanceTargetDelegate(const InstanceTargetDelegate&) = delete;
|
|
InstanceTargetDelegate(InstanceTargetDelegate&&) = default;
|
|
InstanceTargetDelegate& operator=(const InstanceTargetDelegate&) = delete;
|
|
InstanceTargetDelegate& operator=(InstanceTargetDelegate&&) = default;
|
|
virtual ~InstanceTargetDelegate();
|
|
};
|
|
class InstanceTarget : public EnableExecutorFromThis<InstanceTarget> {
|
|
public:
|
|
static std::shared_ptr<InstanceTarget> create(
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager,
|
|
InstanceTargetDelegate& delegate,
|
|
VoidExecutor executor);
|
|
InstanceTarget(const InstanceTarget&) = delete;
|
|
InstanceTarget(InstanceTarget&&) = delete;
|
|
InstanceTarget& operator=(const InstanceTarget&) = delete;
|
|
InstanceTarget& operator=(InstanceTarget&&) = delete;
|
|
~InstanceTarget();
|
|
std::shared_ptr<InstanceAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
RuntimeTarget& registerRuntime(
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor executor);
|
|
void unregisterRuntime(RuntimeTarget& runtime);
|
|
};
|
|
WeakList<InstanceAgent> agents_;
|
|
std::shared_ptr<ExecutionContextManager> executionContextManager_;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/NetworkIOAgent.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
using StreamID = const std::string;
|
|
using Headers = std::map<std::string, std::string>;
|
|
using IOReadError = const std::string;
|
|
namespace {
|
|
using StreamsMap = std::unordered_map<std::string, std::shared_ptr<Stream>>;
|
|
} // namespace
|
|
struct LoadNetworkResourceRequest {
|
|
std::string url;
|
|
};
|
|
struct ReadStreamParams {
|
|
StreamID handle;
|
|
std::optional<unsigned long> size;
|
|
std::optional<unsigned long> offset;
|
|
};
|
|
struct NetworkResource {
|
|
bool success{};
|
|
std::optional<std::string> stream;
|
|
std::optional<uint32_t> httpStatusCode;
|
|
std::optional<std::string> netErrorName;
|
|
std::optional<Headers> headers;
|
|
folly::dynamic toDynamic() const {
|
|
auto dynamicResource = folly::dynamic::object("success", success);
|
|
if (success) {
|
|
assert(stream);
|
|
dynamicResource("stream", *stream);
|
|
}
|
|
if (netErrorName) {
|
|
assert(!success);
|
|
dynamicResource("netErrorName", *netErrorName);
|
|
}
|
|
if (httpStatusCode) {
|
|
dynamicResource("httpStatusCode", *httpStatusCode);
|
|
} else {
|
|
assert(!success);
|
|
}
|
|
if (headers) {
|
|
auto dynamicHeaders = folly::dynamic::object();
|
|
for (const auto& pair : *headers) {
|
|
dynamicHeaders(pair.first, pair.second);
|
|
}
|
|
dynamicResource("headers", std::move(dynamicHeaders));
|
|
} else {
|
|
assert(!success);
|
|
}
|
|
return dynamicResource;
|
|
}
|
|
};
|
|
struct IOReadResult {
|
|
std::string data;
|
|
bool eof;
|
|
bool base64Encoded;
|
|
folly::dynamic toDynamic() const {
|
|
auto obj = folly::dynamic::object("data", data);
|
|
obj("eof", eof);
|
|
obj("base64Encoded", base64Encoded);
|
|
return obj;
|
|
}
|
|
};
|
|
struct GetResponseBodyResult {
|
|
std::string body;
|
|
bool base64Encoded;
|
|
folly::dynamic toDynamic() const {
|
|
folly::dynamic params = folly::dynamic::object;
|
|
params["body"] = body;
|
|
params["base64Encoded"] = base64Encoded;
|
|
return params;
|
|
}
|
|
};
|
|
class NetworkRequestListener {
|
|
public:
|
|
NetworkRequestListener() = default;
|
|
NetworkRequestListener(const NetworkRequestListener&) = delete;
|
|
NetworkRequestListener& operator=(const NetworkRequestListener&) = delete;
|
|
NetworkRequestListener(NetworkRequestListener&&) noexcept = default;
|
|
NetworkRequestListener& operator=(NetworkRequestListener&&) noexcept =
|
|
default;
|
|
virtual ~NetworkRequestListener() = default;
|
|
virtual void onHeaders(uint32_t httpStatusCode, const Headers& headers) = 0;
|
|
virtual void onData(std::string_view data) = 0;
|
|
virtual void onError(const std::string& message) = 0;
|
|
virtual void onCompletion() = 0;
|
|
virtual void setCancelFunction(std::function<void()> cancelFunction) = 0;
|
|
};
|
|
class LoadNetworkResourceDelegate {
|
|
public:
|
|
LoadNetworkResourceDelegate() = default;
|
|
LoadNetworkResourceDelegate(const LoadNetworkResourceDelegate&) = delete;
|
|
LoadNetworkResourceDelegate& operator=(const LoadNetworkResourceDelegate&) =
|
|
delete;
|
|
LoadNetworkResourceDelegate(LoadNetworkResourceDelegate&&) noexcept = delete;
|
|
LoadNetworkResourceDelegate& operator=(
|
|
LoadNetworkResourceDelegate&&) noexcept = delete;
|
|
virtual ~LoadNetworkResourceDelegate() = default;
|
|
virtual void loadNetworkResource(
|
|
[[maybe_unused]] const LoadNetworkResourceRequest& params,
|
|
[[maybe_unused]] ScopedExecutor<NetworkRequestListener> executor) = 0;
|
|
};
|
|
class NetworkIOAgent {
|
|
public:
|
|
NetworkIOAgent(FrontendChannel frontendChannel, VoidExecutor executor)
|
|
: frontendChannel_(frontendChannel),
|
|
executor_(executor),
|
|
streams_(std::make_shared<StreamsMap>()) {}
|
|
bool handleRequest(
|
|
const cdp::PreparsedRequest& req,
|
|
LoadNetworkResourceDelegate& delegate);
|
|
};
|
|
void handleLoadNetworkResource(
|
|
const cdp::PreparsedRequest& req,
|
|
LoadNetworkResourceDelegate& delegate);
|
|
void handleIoRead(const cdp::PreparsedRequest& req);
|
|
void handleIoClose(const cdp::PreparsedRequest& req);
|
|
void handleGetResponseBody(const cdp::PreparsedRequest& req);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/ReactCdp.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgent.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgentDelegate {
|
|
public:
|
|
class ExportedState {
|
|
public:
|
|
virtual ~ExportedState() = default;
|
|
};
|
|
virtual ~RuntimeAgentDelegate() = default;
|
|
virtual bool handleRequest(const cdp::PreparsedRequest& req) = 0;
|
|
inline virtual std::unique_ptr<ExportedState> getExportedState() {
|
|
return std::make_unique<ExportedState>();
|
|
}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/RuntimeTarget.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
template <typename Self>
|
|
using ScopedExecutor =
|
|
std::function<void(std::function<void(Self& self)>&& callback)>;
|
|
using VoidExecutor = std::function<void(std::function<void()>&& callback)>;
|
|
template <typename Self, typename Parent>
|
|
ScopedExecutor<Self> makeScopedExecutor(
|
|
std::shared_ptr<Self> self,
|
|
ScopedExecutor<Parent> executor) {
|
|
return makeScopedExecutor(self, makeVoidExecutor(executor));
|
|
}
|
|
template <typename Self>
|
|
ScopedExecutor<Self> makeScopedExecutor(
|
|
std::shared_ptr<Self> self,
|
|
VoidExecutor executor) {
|
|
return [self = std::weak_ptr(self), executor](auto&& callback) {
|
|
executor([self, callback = std::move(callback)]() {
|
|
auto lockedSelf = self.lock();
|
|
if (!lockedSelf) {
|
|
return;
|
|
}
|
|
callback(*lockedSelf);
|
|
});
|
|
};
|
|
}
|
|
template <typename Self>
|
|
VoidExecutor makeVoidExecutor(ScopedExecutor<Self> executor) {
|
|
return [executor](auto&& callback) {
|
|
executor([callback = std::move(callback)](Self&) { callback(); });
|
|
};
|
|
}
|
|
template <typename Self>
|
|
class EnableExecutorFromThis : public std::enable_shared_from_this<Self> {
|
|
public:
|
|
ScopedExecutor<Self> executorFromThis() {
|
|
assert(baseExecutor_);
|
|
return makeScopedExecutor(this->shared_from_this(), baseExecutor_);
|
|
}
|
|
template <typename Other>
|
|
void setExecutor(ScopedExecutor<Other> executor) {
|
|
setExecutor(makeVoidExecutor(executor));
|
|
}
|
|
void setExecutor(VoidExecutor executor) {
|
|
assert(executor);
|
|
assert(!baseExecutor_);
|
|
baseExecutor_ = std::move(executor);
|
|
}
|
|
};
|
|
}; // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/SessionState.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/StackTrace.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class StackTrace {
|
|
public:
|
|
static inline std::unique_ptr<StackTrace> empty() {
|
|
return std::make_unique<StackTrace>();
|
|
}
|
|
StackTrace() = default;
|
|
StackTrace(const StackTrace&) = delete;
|
|
StackTrace& operator=(const StackTrace&) = delete;
|
|
StackTrace(StackTrace&&) = delete;
|
|
StackTrace& operator=(StackTrace&&) = delete;
|
|
virtual ~StackTrace() = default;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/TracingAgent.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/InspectorInterfaces.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ConsoleMessage.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ExecutionContext.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/RuntimeAgentDelegate.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeAgent final {
|
|
public:
|
|
RuntimeAgent(
|
|
FrontendChannel frontendChannel,
|
|
RuntimeTargetController& targetController,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate> delegate);
|
|
~RuntimeAgent();
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
inline const ExecutionContextDescription& getExecutionContextDescription()
|
|
const {
|
|
return executionContextDescription_;
|
|
}
|
|
void notifyBindingCalled(
|
|
const std::string& bindingName,
|
|
const std::string& payload);
|
|
struct ExportedState {
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState> delegateState;
|
|
};
|
|
ExportedState getExportedState();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/ScopedExecutor.h}
|
|
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class RuntimeTargetDelegate {
|
|
public:
|
|
virtual ~RuntimeTargetDelegate() = default;
|
|
virtual std::unique_ptr<RuntimeAgentDelegate> createAgentDelegate(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState,
|
|
std::unique_ptr<RuntimeAgentDelegate::ExportedState>
|
|
previouslyExportedState,
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeExecutor runtimeExecutor) = 0;
|
|
virtual void addConsoleMessage(
|
|
jsi::Runtime& runtime,
|
|
ConsoleMessage message) = 0;
|
|
virtual bool supportsConsole() const = 0;
|
|
virtual std::unique_ptr<StackTrace> captureStackTrace(
|
|
jsi::Runtime& runtime,
|
|
size_t framesToSkip = 0) = 0;
|
|
virtual void enableSamplingProfiler() = 0;
|
|
virtual void disableSamplingProfiler() = 0;
|
|
virtual tracing::RuntimeSamplingProfile collectSamplingProfile() = 0;
|
|
};
|
|
class RuntimeTargetController {
|
|
public:
|
|
explicit RuntimeTargetController(RuntimeTarget& target);
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void notifyDebuggerSessionCreated();
|
|
void notifyDebuggerSessionDestroyed();
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
class __attribute__((visibility("default"))) RuntimeTarget
|
|
: public EnableExecutorFromThis<RuntimeTarget> {
|
|
public:
|
|
static std::shared_ptr<RuntimeTarget> create(
|
|
const ExecutionContextDescription& executionContextDescription,
|
|
RuntimeTargetDelegate& delegate,
|
|
RuntimeExecutor jsExecutor,
|
|
VoidExecutor selfExecutor);
|
|
RuntimeTarget(const RuntimeTarget&) = delete;
|
|
RuntimeTarget(RuntimeTarget&&) = delete;
|
|
RuntimeTarget& operator=(const RuntimeTarget&) = delete;
|
|
RuntimeTarget& operator=(RuntimeTarget&&) = delete;
|
|
~RuntimeTarget();
|
|
std::shared_ptr<RuntimeAgent> createAgent(
|
|
FrontendChannel channel,
|
|
SessionState& sessionState);
|
|
void registerForTracing();
|
|
void enableSamplingProfiler();
|
|
void disableSamplingProfiler();
|
|
tracing::RuntimeSamplingProfile collectSamplingProfile();
|
|
};
|
|
void installBindingHandler(const std::string& bindingName);
|
|
void installGlobals();
|
|
void installConsoleHandler();
|
|
void installDebuggerSessionObserver();
|
|
void emitDebuggerSessionCreated();
|
|
void emitDebuggerSessionDestroyed();
|
|
friend
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct SessionState {
|
|
public:
|
|
bool isDebuggerDomainEnabled{false};
|
|
bool isLogDomainEnabled{false};
|
|
bool isReactNativeApplicationDomainEnabled{false};
|
|
bool isRuntimeDomainEnabled{false};
|
|
std::unordered_map<std::string, ExecutionContextSelectorSet>
|
|
subscribedBindings;
|
|
std::vector<SimpleConsoleMessage> pendingSimpleConsoleMessages;
|
|
RuntimeAgent::ExportedState lastRuntimeAgentExportedState;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class InstanceAgent final {
|
|
public:
|
|
explicit InstanceAgent(
|
|
FrontendChannel frontendChannel,
|
|
InstanceTarget& target,
|
|
SessionState& sessionState);
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
void setCurrentRuntime(RuntimeTarget* runtime);
|
|
void sendConsoleMessage(SimpleConsoleMessage message);
|
|
void startTracing();
|
|
void stopTracing();
|
|
tracing::InstanceTracingProfile collectTracingProfile();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace facebook::react::jsinspector_modern {
|
|
class TracingAgent {
|
|
public:
|
|
explicit TracingAgent(FrontendChannel frontendChannel)
|
|
: frontendChannel_(std::move(frontendChannel)) {}
|
|
bool handleRequest(const cdp::PreparsedRequest& req);
|
|
void setCurrentInstanceAgent(std::shared_ptr<InstanceAgent> agent);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/UniqueMonostate.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
template <size_t key>
|
|
struct UniqueMonostate {
|
|
constexpr bool operator==(const UniqueMonostate<key>&) const noexcept {
|
|
return true;
|
|
}
|
|
constexpr bool operator!=(const UniqueMonostate<key>&) const noexcept {
|
|
return false;
|
|
}
|
|
constexpr bool operator<(const UniqueMonostate<key>&) const noexcept {
|
|
return false;
|
|
}
|
|
constexpr bool operator>(const UniqueMonostate<key>&) const noexcept {
|
|
return false;
|
|
}
|
|
constexpr bool operator<=(const UniqueMonostate<key>&) const noexcept {
|
|
return true;
|
|
}
|
|
constexpr bool operator>=(const UniqueMonostate<key>&) const noexcept {
|
|
return true;
|
|
}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
namespace std {
|
|
template <size_t key>
|
|
struct hash<::facebook::react::jsinspector_modern::UniqueMonostate<key>> {
|
|
size_t operator()(
|
|
const ::facebook::react::jsinspector_modern::UniqueMonostate<key>&)
|
|
const noexcept {
|
|
return key;
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/Utf8.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
inline void truncateToValidUTF8(std::vector<char>& buffer) {
|
|
const auto length = buffer.size();
|
|
if (length > 0 && (buffer[length - 1] & 0b10000000) == 0b10000000) {
|
|
int continuationBytes = 0;
|
|
while ((buffer[length - continuationBytes - 1] & 0b11000000) !=
|
|
0b11000000) {
|
|
continuationBytes++;
|
|
if (continuationBytes > 3 || continuationBytes >= length - 1) {
|
|
throw std::runtime_error("Invalid UTF-8 sequence");
|
|
}
|
|
}
|
|
char firstByteOfSequence = buffer[length - continuationBytes - 1];
|
|
char mask = static_cast<char>(0b11111000 << (3 - continuationBytes));
|
|
char expectedBitsAfterMask = static_cast<char>(mask << 1);
|
|
if (continuationBytes == 0 ||
|
|
(firstByteOfSequence & mask) != expectedBitsAfterMask) {
|
|
buffer.resize(length - (continuationBytes + 1));
|
|
}
|
|
}
|
|
}
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/WeakList.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
template <typename T>
|
|
class WeakList {
|
|
public:
|
|
template <typename Fn>
|
|
void forEach(Fn&& fn) const {
|
|
for (auto it = ptrs_.begin(); it != ptrs_.end();) {
|
|
if (auto ptr = it->lock()) {
|
|
fn(*ptr);
|
|
++it;
|
|
} else {
|
|
it = ptrs_.erase(it);
|
|
}
|
|
}
|
|
}
|
|
size_t size() const {
|
|
size_t count{0};
|
|
forEach([&count](const auto&) { ++count; });
|
|
return count;
|
|
}
|
|
bool empty() const {
|
|
return !size();
|
|
}
|
|
void insert(std::weak_ptr<T> ptr) {
|
|
ptrs_.push_back(ptr);
|
|
}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/WebSocketInterfaces.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
class IWebSocket {
|
|
public:
|
|
virtual ~IWebSocket() = default;
|
|
virtual void send(std::string_view message) = 0;
|
|
};
|
|
class IWebSocketDelegate {
|
|
public:
|
|
virtual ~IWebSocketDelegate() = default;
|
|
virtual void didFailWithError(
|
|
std::optional<int> posixCode,
|
|
std::string error) = 0;
|
|
virtual void didReceiveMessage(std::string_view message) = 0;
|
|
virtual void didOpen() = 0;
|
|
virtual void didClose() = 0;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/cdp/CdpJson.h}:
|
|
namespace facebook::react::jsinspector_modern::cdp {
|
|
using RequestId = long long;
|
|
enum class ErrorCode {
|
|
ParseError = -32700,
|
|
InvalidRequest = -32600,
|
|
MethodNotFound = -32601,
|
|
InvalidParams = -32602,
|
|
InternalError = -32603
|
|
};
|
|
struct PreparsedRequest {
|
|
public:
|
|
RequestId id{};
|
|
std::string method;
|
|
folly::dynamic params;
|
|
inline bool operator==(const PreparsedRequest& rhs) const {
|
|
return id == rhs.id && method == rhs.method && params == rhs.params;
|
|
}
|
|
std::string toJson() const;
|
|
};
|
|
PreparsedRequest preparse(std::string_view message);
|
|
using TypeError = folly::TypeError;
|
|
using ParseError = folly::json::parse_error;
|
|
std::string jsonError(
|
|
std::optional<RequestId> id,
|
|
ErrorCode code,
|
|
std::optional<std::string> message = std::nullopt);
|
|
std::string jsonResult(
|
|
RequestId id,
|
|
const folly::dynamic& result = folly::dynamic::object());
|
|
std::string jsonNotification(
|
|
std::string_view method,
|
|
std::optional<folly::dynamic> params = std::nullopt);
|
|
std::string jsonRequest(
|
|
RequestId id,
|
|
std::string_view method,
|
|
std::optional<folly::dynamic> params = std::nullopt);
|
|
} // namespace facebook::react::jsinspector_modern::cdp
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/network/BoundedRequestBuffer.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
constexpr size_t REQUEST_BUFFER_MAX_SIZE_BYTES = 100 * 1024 * 1024;
|
|
class BoundedRequestBuffer {
|
|
public:
|
|
struct ResponseBody {
|
|
std::string data;
|
|
bool base64Encoded;
|
|
};
|
|
bool put(
|
|
const std::string& requestId,
|
|
std::string_view data,
|
|
bool base64Encoded) noexcept;
|
|
std::shared_ptr<const ResponseBody> get(const std::string& requestId) const;
|
|
void clear();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/network/CdpNetwork.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/network/NetworkTypes.h}
|
|
namespace facebook::react::jsinspector_modern::cdp::network {
|
|
struct Request {
|
|
std::string url;
|
|
std::string method;
|
|
std::optional<Headers> headers;
|
|
std::optional<std::string> postData;
|
|
static Request fromInputParams(const RequestInfo& requestInfo);
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct Response {
|
|
std::string url;
|
|
uint16_t status;
|
|
std::string statusText;
|
|
std::optional<Headers> headers;
|
|
std::string mimeType;
|
|
int encodedDataLength;
|
|
static Response fromInputParams(
|
|
const ResponseInfo& responseInfo,
|
|
int encodedDataLength);
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct ConnectTiming {
|
|
double requestTime;
|
|
};
|
|
struct RequestWillBeSentParams {
|
|
std::string requestId;
|
|
std::string loaderId;
|
|
std::string documentURL;
|
|
Request request;
|
|
double timestamp;
|
|
double wallTime;
|
|
folly::dynamic initiator;
|
|
bool redirectHasExtraInfo;
|
|
std::optional<Response> redirectResponse;
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct RequestWillBeSentExtraInfoParams {
|
|
std::string requestId;
|
|
Headers headers;
|
|
ConnectTiming connectTiming;
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct ResponseReceivedParams {
|
|
std::string requestId;
|
|
std::string loaderId;
|
|
double timestamp;
|
|
std::string type;
|
|
Response response;
|
|
bool hasExtraInfo;
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct DataReceivedParams {
|
|
std::string requestId;
|
|
double timestamp;
|
|
int dataLength;
|
|
int encodedDataLength;
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct LoadingFailedParams {
|
|
std::string requestId;
|
|
double timestamp;
|
|
std::string type;
|
|
std::string errorText;
|
|
bool canceled;
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
struct LoadingFinishedParams {
|
|
std::string requestId;
|
|
double timestamp;
|
|
int encodedDataLength;
|
|
folly::dynamic toDynamic() const;
|
|
};
|
|
std::string resourceTypeFromMimeType(const std::string& mimeType);
|
|
} // namespace facebook::react::jsinspector_modern::cdp::network
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/network/HttpUtils.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/network/NetworkTypes.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
std::string httpReasonPhrase(uint16_t status);
|
|
std::string mimeTypeFromHeaders(const Headers& headers);
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/network/NetworkReporter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/network/BoundedRequestBuffer.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/network/NetworkTypes.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
using FrontendChannel = std::function<void(std::string_view messageJson)>;
|
|
struct ResourceTimingData {
|
|
std::string url;
|
|
HighResTimeStamp fetchStart;
|
|
HighResTimeStamp requestStart;
|
|
std::optional<HighResTimeStamp> connectStart;
|
|
std::optional<HighResTimeStamp> connectEnd;
|
|
std::optional<HighResTimeStamp> responseStart;
|
|
std::optional<int> responseStatus;
|
|
};
|
|
class NetworkReporter {
|
|
public:
|
|
static NetworkReporter& getInstance();
|
|
void setFrontendChannel(FrontendChannel frontendChannel);
|
|
bool enableDebugging();
|
|
bool disableDebugging();
|
|
inline bool isDebuggingEnabled() const {
|
|
return debuggingEnabled_.load(std::memory_order_acquire);
|
|
}
|
|
void reportRequestStart(
|
|
const std::string& requestId,
|
|
const RequestInfo& requestInfo,
|
|
int encodedDataLength,
|
|
const std::optional<ResponseInfo>& redirectResponse);
|
|
void reportConnectionTiming(
|
|
const std::string& requestId,
|
|
const std::optional<Headers>& headers);
|
|
void reportResponseStart(
|
|
const std::string& requestId,
|
|
const ResponseInfo& responseInfo,
|
|
int encodedDataLength);
|
|
void reportDataReceived(
|
|
const std::string& requestId,
|
|
int dataLength,
|
|
const std::optional<int>& encodedDataLength);
|
|
void reportResponseEnd(const std::string& requestId, int encodedDataLength);
|
|
void reportRequestFailed(const std::string& requestId, bool cancelled) const;
|
|
void storeResponseBody(
|
|
const std::string& requestId,
|
|
std::string_view body,
|
|
bool base64Encoded);
|
|
std::optional<std::tuple<std::string, bool>> getResponseBody(
|
|
const std::string& requestId);
|
|
};
|
|
inline bool isDebuggingEnabledNoSync() const {
|
|
return debuggingEnabled_.load(std::memory_order_relaxed);
|
|
}
|
|
FrontendChannel frontendChannel_;
|
|
std::unordered_map<std::string, ResourceTimingData> perfTimingsBuffer_{};
|
|
std::mutex perfTimingsMutex_;
|
|
std::map<std::string, std::string> resourceTypeMap_{};
|
|
BoundedRequestBuffer requestBodyBuffer_{};
|
|
std::mutex requestBodyMutex_;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/network/NetworkTypes.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
using Headers = std::map<std::string, std::string>;
|
|
struct RequestInfo {
|
|
std::string url;
|
|
std::string httpMethod;
|
|
std::optional<Headers> headers;
|
|
std::optional<std::string> httpBody;
|
|
};
|
|
struct ResponseInfo {
|
|
std::string url;
|
|
uint16_t statusCode;
|
|
std::optional<Headers> headers;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tests/engines/JsiIntegrationTestGenericEngineAdapter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class JsiIntegrationTestGenericEngineAdapter {
|
|
public:
|
|
explicit JsiIntegrationTestGenericEngineAdapter(folly::Executor& jsExecutor);
|
|
static InspectorFlagOverrides getInspectorFlagOverrides() noexcept;
|
|
RuntimeTargetDelegate& getRuntimeTargetDelegate();
|
|
jsi::Runtime& getRuntime() const noexcept;
|
|
RuntimeExecutor getRuntimeExecutor() const noexcept;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tests/engines/JsiIntegrationTestHermesEngineAdapter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h}
|
|
namespace facebook::react::jsinspector_modern {
|
|
class JsiIntegrationTestHermesEngineAdapter {
|
|
public:
|
|
explicit JsiIntegrationTestHermesEngineAdapter(folly::Executor& jsExecutor);
|
|
static InspectorFlagOverrides getInspectorFlagOverrides() noexcept;
|
|
RuntimeTargetDelegate& getRuntimeTargetDelegate();
|
|
jsi::Runtime& getRuntime() const noexcept;
|
|
RuntimeExecutor getRuntimeExecutor() const noexcept;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tests/utils/InspectorFlagOverridesGuard.h}:
|
|
namespace facebook::react::jsinspector_modern {
|
|
struct InspectorFlagOverrides {
|
|
std::optional<bool> fuseboxEnabledRelease;
|
|
std::optional<bool> networkInspectionEnabled;
|
|
};
|
|
class InspectorFlagOverridesGuard {
|
|
public:
|
|
explicit InspectorFlagOverridesGuard(const InspectorFlagOverrides& overrides);
|
|
InspectorFlagOverridesGuard(const InspectorFlagOverridesGuard&) = delete;
|
|
InspectorFlagOverridesGuard(InspectorFlagOverridesGuard&&) = default;
|
|
InspectorFlagOverridesGuard& operator=(const InspectorFlagOverridesGuard&) =
|
|
delete;
|
|
InspectorFlagOverridesGuard& operator=(InspectorFlagOverridesGuard&&) =
|
|
default;
|
|
~InspectorFlagOverridesGuard();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/ConsoleTimeStamp.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
using ConsoleTimeStampEntry = std::variant<HighResTimeStamp, std::string>;
|
|
enum class ConsoleTimeStampColor {
|
|
Primary,
|
|
PrimaryLight,
|
|
PrimaryDark,
|
|
Secondary,
|
|
SecondaryLight,
|
|
SecondaryDark,
|
|
Tertiary,
|
|
TertiaryLight,
|
|
TertiaryDark,
|
|
Warning,
|
|
Error,
|
|
};
|
|
inline std::string consoleTimeStampColorToString(ConsoleTimeStampColor color) {
|
|
switch (color) {
|
|
case ConsoleTimeStampColor::Primary:
|
|
return "primary";
|
|
case ConsoleTimeStampColor::PrimaryLight:
|
|
return "primary-light";
|
|
case ConsoleTimeStampColor::PrimaryDark:
|
|
return "primary-dark";
|
|
case ConsoleTimeStampColor::Secondary:
|
|
return "secondary";
|
|
case ConsoleTimeStampColor::SecondaryLight:
|
|
return "secondary-light";
|
|
case ConsoleTimeStampColor::SecondaryDark:
|
|
return "secondary-dark";
|
|
case ConsoleTimeStampColor::Tertiary:
|
|
return "tertiary";
|
|
case ConsoleTimeStampColor::TertiaryLight:
|
|
return "tertiary-light";
|
|
case ConsoleTimeStampColor::TertiaryDark:
|
|
return "tertiary-dark";
|
|
case ConsoleTimeStampColor::Warning:
|
|
return "warning";
|
|
case ConsoleTimeStampColor::Error:
|
|
return "error";
|
|
default:
|
|
throw std::runtime_error("Unknown ConsoleTimeStampColor");
|
|
}
|
|
};
|
|
inline std::optional<ConsoleTimeStampColor> getConsoleTimeStampColorFromString(
|
|
const std::string& str) {
|
|
if (str == "primary") {
|
|
return ConsoleTimeStampColor::Primary;
|
|
} else if (str == "primary-light") {
|
|
return ConsoleTimeStampColor::PrimaryLight;
|
|
} else if (str == "primary-dark") {
|
|
return ConsoleTimeStampColor::PrimaryDark;
|
|
} else if (str == "secondary") {
|
|
return ConsoleTimeStampColor::Secondary;
|
|
} else if (str == "secondary-light") {
|
|
return ConsoleTimeStampColor::SecondaryLight;
|
|
} else if (str == "secondary-dark") {
|
|
return ConsoleTimeStampColor::SecondaryDark;
|
|
} else if (str == "tertiary") {
|
|
return ConsoleTimeStampColor::Tertiary;
|
|
} else if (str == "tertiary-light") {
|
|
return ConsoleTimeStampColor::TertiaryLight;
|
|
} else if (str == "tertiary-dark") {
|
|
return ConsoleTimeStampColor::TertiaryDark;
|
|
} else if (str == "warning") {
|
|
return ConsoleTimeStampColor::Warning;
|
|
} else if (str == "error") {
|
|
return ConsoleTimeStampColor::Error;
|
|
} else {
|
|
return std::nullopt;
|
|
}
|
|
};
|
|
}; // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/EventLoopReporter.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
enum class EventLoopPhase {
|
|
Task,
|
|
Microtasks,
|
|
};
|
|
struct EventLoopReporter {
|
|
public:
|
|
explicit EventLoopReporter(EventLoopPhase phase);
|
|
EventLoopReporter(const EventLoopReporter&) = delete;
|
|
EventLoopReporter(EventLoopReporter&&) = delete;
|
|
EventLoopReporter& operator=(const EventLoopReporter&) = delete;
|
|
EventLoopReporter& operator=(EventLoopReporter&&) = delete;
|
|
~EventLoopReporter();
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/InstanceTracingProfile.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfile.h}
|
|
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
struct InstanceTracingProfile {
|
|
public:
|
|
explicit InstanceTracingProfile(RuntimeSamplingProfile runtimeSamplingProfile)
|
|
: runtimeSamplingProfile_(std::move(runtimeSamplingProfile)) {}
|
|
const RuntimeSamplingProfile& getRuntimeSamplingProfile() const {
|
|
return runtimeSamplingProfile_;
|
|
}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/PerformanceTracer.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/ConsoleTimeStamp.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/TraceEvent.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/TraceEventProfile.h}
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
class PerformanceTracer {
|
|
public:
|
|
static PerformanceTracer& getInstance();
|
|
bool startTracing();
|
|
bool stopTracing();
|
|
inline bool isTracing() const {
|
|
return tracingAtomic_;
|
|
}
|
|
void collectEvents(
|
|
const std::function<void(const folly::dynamic& eventsChunk)>&
|
|
resultCallback,
|
|
uint16_t chunkSize);
|
|
folly::dynamic collectEvents(uint16_t chunkSize);
|
|
void reportMark(
|
|
const std::string_view& name,
|
|
HighResTimeStamp start,
|
|
folly::dynamic&& detail = nullptr);
|
|
void reportMeasure(
|
|
const std::string_view& name,
|
|
HighResTimeStamp start,
|
|
HighResDuration duration,
|
|
folly::dynamic&& detail = nullptr);
|
|
void reportTimeStamp(
|
|
std::string name,
|
|
std::optional<ConsoleTimeStampEntry> start = std::nullopt,
|
|
std::optional<ConsoleTimeStampEntry> end = std::nullopt,
|
|
std::optional<std::string> trackName = std::nullopt,
|
|
std::optional<std::string> trackGroup = std::nullopt,
|
|
std::optional<ConsoleTimeStampColor> color = std::nullopt);
|
|
void reportProcess(uint64_t id, const std::string& name);
|
|
void reportThread(uint64_t id, const std::string& name);
|
|
void reportJavaScriptThread();
|
|
void reportEventLoopTask(HighResTimeStamp start, HighResTimeStamp end);
|
|
void reportEventLoopMicrotasks(HighResTimeStamp start, HighResTimeStamp end);
|
|
folly::dynamic getSerializedRuntimeProfileTraceEvent(
|
|
uint64_t threadId,
|
|
uint16_t profileId,
|
|
HighResTimeStamp profileTimestamp);
|
|
folly::dynamic getSerializedRuntimeProfileChunkTraceEvent(
|
|
uint16_t profileId,
|
|
uint64_t threadId,
|
|
HighResTimeStamp chunkTimestamp,
|
|
const TraceEventProfileChunk& traceEventProfileChunk);
|
|
};
|
|
uint32_t performanceMeasureCount_{0};
|
|
std::vector<TraceEvent> buffer_;
|
|
std::mutex mutex_;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/ProfileTreeNode.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
class ProfileTreeNode {
|
|
public:
|
|
enum class CodeType {
|
|
JavaScript,
|
|
Other,
|
|
};
|
|
static constexpr uint32_t NO_PARENT = UINT32_MAX;
|
|
ProfileTreeNode(
|
|
uint32_t id,
|
|
CodeType codeType,
|
|
RuntimeSamplingProfile::SampleCallStackFrame callFrame,
|
|
uint32_t parentId = NO_PARENT)
|
|
: id_(id),
|
|
codeType_(codeType),
|
|
parentId_(parentId),
|
|
callFrame_(std::move(callFrame)) {}
|
|
uint32_t getId() const {
|
|
return id_;
|
|
}
|
|
CodeType getCodeType() const {
|
|
return codeType_;
|
|
}
|
|
inline bool hasParent() const {
|
|
return parentId_ != NO_PARENT;
|
|
}
|
|
uint32_t getParentId() const {
|
|
return parentId_;
|
|
}
|
|
const RuntimeSamplingProfile::SampleCallStackFrame& getCallFrame() const {
|
|
return callFrame_;
|
|
}
|
|
ProfileTreeNode* getIfAlreadyExists(
|
|
CodeType childCodeType,
|
|
const RuntimeSamplingProfile::SampleCallStackFrame& childCallFrame) {
|
|
for (auto& existingChild : children_) {
|
|
if (existingChild.getCodeType() == childCodeType &&
|
|
existingChild.getCallFrame() == childCallFrame) {
|
|
return &existingChild;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
ProfileTreeNode* addChild(
|
|
uint32_t childId,
|
|
CodeType childCodeType,
|
|
RuntimeSamplingProfile::SampleCallStackFrame childCallFrame) {
|
|
return &children_.emplace_back(
|
|
childId, childCodeType, std::move(childCallFrame), id_);
|
|
}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfile.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
class RawRuntimeProfile {
|
|
public:
|
|
virtual ~RawRuntimeProfile() = default;
|
|
};
|
|
struct RuntimeSamplingProfile {
|
|
public:
|
|
struct SampleCallStackFrame {
|
|
enum class Kind {
|
|
JSFunction,
|
|
NativeFunction,
|
|
HostFunction,
|
|
GarbageCollector,
|
|
};
|
|
|
|
public:
|
|
SampleCallStackFrame(
|
|
const Kind kind,
|
|
const uint32_t scriptId,
|
|
std::string_view functionName,
|
|
std::optional<std::string_view> url = std::nullopt,
|
|
const std::optional<uint32_t>& lineNumber = std::nullopt,
|
|
const std::optional<uint32_t>& columnNumber = std::nullopt)
|
|
: kind_(kind),
|
|
scriptId_(scriptId),
|
|
functionName_(std::move(functionName)),
|
|
url_(std::move(url)),
|
|
lineNumber_(lineNumber),
|
|
columnNumber_(columnNumber) {}
|
|
Kind getKind() const {
|
|
return kind_;
|
|
}
|
|
uint32_t getScriptId() const {
|
|
return scriptId_;
|
|
}
|
|
std::string_view getFunctionName() const {
|
|
return functionName_;
|
|
}
|
|
bool hasUrl() const {
|
|
return url_.has_value();
|
|
}
|
|
std::string_view getUrl() const {
|
|
return url_.value();
|
|
}
|
|
bool hasLineNumber() const {
|
|
return lineNumber_.has_value();
|
|
}
|
|
uint32_t getLineNumber() const {
|
|
return lineNumber_.value();
|
|
}
|
|
bool hasColumnNumber() const {
|
|
return columnNumber_.has_value();
|
|
}
|
|
uint32_t getColumnNumber() const {
|
|
return columnNumber_.value();
|
|
}
|
|
inline bool operator==(const SampleCallStackFrame& rhs) const noexcept {
|
|
return kind_ == rhs.kind_ && scriptId_ == rhs.scriptId_ &&
|
|
functionName_ == rhs.functionName_ && url_ == rhs.url_ &&
|
|
lineNumber_ == rhs.lineNumber_ && columnNumber_ == rhs.columnNumber_;
|
|
}
|
|
|
|
private:
|
|
Kind kind_;
|
|
uint32_t scriptId_;
|
|
std::string_view functionName_;
|
|
std::optional<std::string_view> url_;
|
|
std::optional<uint32_t> lineNumber_;
|
|
std::optional<uint32_t> columnNumber_;
|
|
};
|
|
struct Sample {
|
|
public:
|
|
Sample(
|
|
uint64_t timestamp,
|
|
uint64_t threadId,
|
|
std::vector<SampleCallStackFrame> callStack)
|
|
: timestamp_(timestamp),
|
|
threadId_(threadId),
|
|
callStack_(std::move(callStack)) {}
|
|
Sample& operator=(Sample&&) = default;
|
|
Sample(Sample&&) = default;
|
|
Sample(const Sample&) = delete;
|
|
Sample& operator=(const Sample&) = delete;
|
|
uint64_t getTimestamp() const {
|
|
return timestamp_;
|
|
}
|
|
uint64_t getThreadId() const {
|
|
return threadId_;
|
|
}
|
|
const std::vector<SampleCallStackFrame>& getCallStack() const {
|
|
return callStack_;
|
|
}
|
|
|
|
private:
|
|
uint64_t timestamp_;
|
|
uint64_t threadId_;
|
|
std::vector<SampleCallStackFrame> callStack_;
|
|
};
|
|
RuntimeSamplingProfile(
|
|
std::string runtimeName,
|
|
std::vector<Sample> samples,
|
|
std::unique_ptr<RawRuntimeProfile> rawRuntimeProfile)
|
|
: runtimeName_(std::move(runtimeName)),
|
|
samples_(std::move(samples)),
|
|
rawRuntimeProfile_(std::move(rawRuntimeProfile)) {}
|
|
RuntimeSamplingProfile& operator=(RuntimeSamplingProfile&&) = default;
|
|
RuntimeSamplingProfile(RuntimeSamplingProfile&&) = default;
|
|
RuntimeSamplingProfile(const RuntimeSamplingProfile&) = delete;
|
|
RuntimeSamplingProfile& operator=(const RuntimeSamplingProfile&) = delete;
|
|
const std::string& getRuntimeName() const {
|
|
return runtimeName_;
|
|
}
|
|
const std::vector<Sample>& getSamples() const {
|
|
return samples_;
|
|
}
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfileTraceEventSerializer.h}:
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/ConsoleTimeStamp.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/TraceEvent.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/TraceEventProfile.h}
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
class PerformanceTracer {
|
|
public:
|
|
static PerformanceTracer& getInstance();
|
|
bool startTracing();
|
|
bool stopTracing();
|
|
inline bool isTracing() const {
|
|
return tracingAtomic_;
|
|
}
|
|
void collectEvents(
|
|
const std::function<void(const folly::dynamic& eventsChunk)>&
|
|
resultCallback,
|
|
uint16_t chunkSize);
|
|
folly::dynamic collectEvents(uint16_t chunkSize);
|
|
void reportMark(
|
|
const std::string_view& name,
|
|
HighResTimeStamp start,
|
|
folly::dynamic&& detail = nullptr);
|
|
void reportMeasure(
|
|
const std::string_view& name,
|
|
HighResTimeStamp start,
|
|
HighResDuration duration,
|
|
folly::dynamic&& detail = nullptr);
|
|
void reportTimeStamp(
|
|
std::string name,
|
|
std::optional<ConsoleTimeStampEntry> start = std::nullopt,
|
|
std::optional<ConsoleTimeStampEntry> end = std::nullopt,
|
|
std::optional<std::string> trackName = std::nullopt,
|
|
std::optional<std::string> trackGroup = std::nullopt,
|
|
std::optional<ConsoleTimeStampColor> color = std::nullopt);
|
|
void reportProcess(uint64_t id, const std::string& name);
|
|
void reportThread(uint64_t id, const std::string& name);
|
|
void reportJavaScriptThread();
|
|
void reportEventLoopTask(HighResTimeStamp start, HighResTimeStamp end);
|
|
void reportEventLoopMicrotasks(HighResTimeStamp start, HighResTimeStamp end);
|
|
folly::dynamic getSerializedRuntimeProfileTraceEvent(
|
|
uint64_t threadId,
|
|
uint16_t profileId,
|
|
HighResTimeStamp profileTimestamp);
|
|
folly::dynamic getSerializedRuntimeProfileChunkTraceEvent(
|
|
uint16_t profileId,
|
|
uint64_t threadId,
|
|
HighResTimeStamp chunkTimestamp,
|
|
const TraceEventProfileChunk& traceEventProfileChunk);
|
|
};
|
|
uint32_t performanceMeasureCount_{0};
|
|
std::vector<TraceEvent> buffer_;
|
|
std::mutex mutex_;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/ProfileTreeNode.h}
|
|
/// @dep {packages/react-native/ReactCommon/jsinspector-modern/tracing/RuntimeSamplingProfile.h}
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
namespace {
|
|
struct NodeIdGenerator {
|
|
public:
|
|
uint32_t getNext() {
|
|
return ++counter_;
|
|
}
|
|
};
|
|
} // namespace
|
|
class RuntimeSamplingProfileTraceEventSerializer {
|
|
struct ProfileChunk {
|
|
ProfileChunk(
|
|
uint16_t chunkSize,
|
|
uint64_t chunkThreadId,
|
|
HighResTimeStamp chunkTimestamp)
|
|
: size(chunkSize), threadId(chunkThreadId), timestamp(chunkTimestamp) {
|
|
samples.reserve(size);
|
|
timeDeltas.reserve(size);
|
|
}
|
|
bool isFull() const {
|
|
return samples.size() == size;
|
|
}
|
|
bool isEmpty() const {
|
|
return samples.empty();
|
|
}
|
|
std::vector<ProfileTreeNode> nodes;
|
|
std::vector<uint32_t> samples;
|
|
std::vector<HighResDuration> timeDeltas;
|
|
uint16_t size;
|
|
uint64_t threadId;
|
|
HighResTimeStamp timestamp;
|
|
};
|
|
|
|
public:
|
|
RuntimeSamplingProfileTraceEventSerializer(
|
|
PerformanceTracer& performanceTracer,
|
|
std::function<void(const folly::dynamic& traceEventsChunk)>
|
|
notificationCallback,
|
|
uint16_t traceEventChunkSize,
|
|
uint16_t profileChunkSize = 10)
|
|
: performanceTracer_(performanceTracer),
|
|
notificationCallback_(std::move(notificationCallback)),
|
|
traceEventChunkSize_(traceEventChunkSize),
|
|
profileChunkSize_(profileChunkSize) {
|
|
traceEventBuffer_ = folly::dynamic::array();
|
|
traceEventBuffer_.reserve(traceEventChunkSize);
|
|
}
|
|
void serializeAndNotify(
|
|
const RuntimeSamplingProfile& profile,
|
|
HighResTimeStamp tracingStartTime);
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/Timing.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
constexpr HighResTimeStamp TRACING_TIME_ORIGIN =
|
|
HighResTimeStamp::fromChronoSteadyClockTimePoint(
|
|
std::chrono::steady_clock::time_point());
|
|
inline uint64_t highResTimeStampToTracingClockTimeStamp(
|
|
HighResTimeStamp timestamp) {
|
|
assert(
|
|
timestamp >= TRACING_TIME_ORIGIN &&
|
|
"Provided timestamp is before time origin");
|
|
auto duration = timestamp - TRACING_TIME_ORIGIN;
|
|
return static_cast<uint64_t>(
|
|
static_cast<double>(duration.toNanoseconds()) / 1e3);
|
|
}
|
|
inline int64_t highResDurationToTracingClockDuration(HighResDuration duration) {
|
|
return static_cast<int64_t>(
|
|
static_cast<double>(duration.toNanoseconds()) / 1e3);
|
|
}
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/TraceEvent.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
struct TraceEvent {
|
|
std::optional<uint32_t> id;
|
|
std::string name;
|
|
std::string cat;
|
|
char ph;
|
|
HighResTimeStamp ts;
|
|
uint64_t pid;
|
|
uint64_t tid;
|
|
folly::dynamic args = folly::dynamic::object();
|
|
std::optional<HighResDuration> dur;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsinspector-modern/tracing/TraceEventProfile.h}:
|
|
namespace facebook::react::jsinspector_modern::tracing {
|
|
struct TraceEventProfileChunk {
|
|
struct TimeDeltas {
|
|
folly::dynamic toDynamic() const {
|
|
auto value = folly::dynamic::array();
|
|
value.reserve(deltas.size());
|
|
for (const auto& delta : deltas) {
|
|
value.push_back(highResDurationToTracingClockDuration(delta));
|
|
}
|
|
return value;
|
|
}
|
|
std::vector<HighResDuration> deltas;
|
|
};
|
|
struct CPUProfile {
|
|
struct Node {
|
|
struct CallFrame {
|
|
folly::dynamic toDynamic() const {
|
|
folly::dynamic dynamicCallFrame = folly::dynamic::object();
|
|
dynamicCallFrame["codeType"] = codeType;
|
|
dynamicCallFrame["scriptId"] = scriptId;
|
|
dynamicCallFrame["functionName"] = functionName;
|
|
if (url.has_value()) {
|
|
dynamicCallFrame["url"] = url.value();
|
|
}
|
|
if (lineNumber.has_value()) {
|
|
dynamicCallFrame["lineNumber"] = lineNumber.value();
|
|
}
|
|
if (columnNumber.has_value()) {
|
|
dynamicCallFrame["columnNumber"] = columnNumber.value();
|
|
}
|
|
return dynamicCallFrame;
|
|
}
|
|
std::string codeType;
|
|
uint32_t scriptId;
|
|
std::string functionName;
|
|
std::optional<std::string> url;
|
|
std::optional<uint32_t> lineNumber;
|
|
std::optional<uint32_t> columnNumber;
|
|
};
|
|
folly::dynamic toDynamic() const {
|
|
folly::dynamic dynamicNode = folly::dynamic::object();
|
|
dynamicNode["callFrame"] = callFrame.toDynamic();
|
|
dynamicNode["id"] = id;
|
|
if (parentId.has_value()) {
|
|
dynamicNode["parent"] = parentId.value();
|
|
}
|
|
return dynamicNode;
|
|
}
|
|
uint32_t id;
|
|
CallFrame callFrame;
|
|
std::optional<uint32_t> parentId;
|
|
};
|
|
folly::dynamic toDynamic() const {
|
|
folly::dynamic dynamicNodes = folly::dynamic::array();
|
|
dynamicNodes.reserve(nodes.size());
|
|
for (const auto& node : nodes) {
|
|
dynamicNodes.push_back(node.toDynamic());
|
|
}
|
|
folly::dynamic dynamicSamples =
|
|
folly::dynamic::array(samples.begin(), samples.end());
|
|
return folly::dynamic::object("nodes", dynamicNodes)(
|
|
"samples", dynamicSamples);
|
|
}
|
|
std::vector<Node> nodes;
|
|
std::vector<uint32_t> samples;
|
|
};
|
|
folly::dynamic toDynamic() const {
|
|
return folly::dynamic::object("cpuProfile", cpuProfile.toDynamic())(
|
|
"timeDeltas", timeDeltas.toDynamic());
|
|
}
|
|
CPUProfile cpuProfile;
|
|
TimeDeltas timeDeltas;
|
|
};
|
|
} // namespace facebook::react::jsinspector_modern::tracing
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsitooling/react/runtime/JSRuntimeFactory.h}:
|
|
namespace facebook::react {
|
|
class JSRuntime {
|
|
public:
|
|
virtual jsi::Runtime& getRuntime() noexcept = 0;
|
|
virtual ~JSRuntime() = default;
|
|
virtual jsinspector_modern::RuntimeTargetDelegate& getRuntimeTargetDelegate();
|
|
virtual void unstable_initializeOnJsThread() {}
|
|
};
|
|
class JSRuntimeFactory {
|
|
public:
|
|
virtual std::unique_ptr<JSRuntime> createJSRuntime(
|
|
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept = 0;
|
|
virtual ~JSRuntimeFactory() = default;
|
|
};
|
|
class JSIRuntimeHolder : public JSRuntime {
|
|
public:
|
|
jsi::Runtime& getRuntime() noexcept override;
|
|
explicit JSIRuntimeHolder(std::unique_ptr<jsi::Runtime> runtime);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/jsitooling/react/runtime/JSRuntimeFactoryCAPI.h}:
|
|
extern "C" {
|
|
typedef void* JSRuntimeFactoryRef;
|
|
void js_runtime_factory_destroy(JSRuntimeFactoryRef factory);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/logger/react_native_log.h}:
|
|
enum ReactNativeLogLevel {
|
|
ReactNativeLogLevelInfo = 1,
|
|
ReactNativeLogLevelWarning = 2,
|
|
ReactNativeLogLevelError = 3,
|
|
ReactNativeLogLevelFatal = 4
|
|
};
|
|
using reactnativelogfunctype = void (*)(ReactNativeLogLevel, const char*);
|
|
extern "C" {
|
|
void set_react_native_logfunc(reactnativelogfunctype newlogfunc);
|
|
void react_native_log_info(const char* text);
|
|
void react_native_log_warn(const char* text);
|
|
void react_native_log_error(const char* text);
|
|
void react_native_log_fatal(const char* text);
|
|
void _react_native_log(ReactNativeLogLevel level, const char* text);
|
|
void _react_native_log_default(ReactNativeLogLevel level, const char* text);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/oscompat/OSCompat.h}:
|
|
namespace facebook::react::oscompat {
|
|
uint64_t getCurrentProcessId();
|
|
uint64_t getCurrentThreadId();
|
|
} // namespace facebook::react::oscompat
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/AString.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<std::string> {
|
|
static std::string fromJs(jsi::Runtime& rt, const jsi::String& value) {
|
|
return value.utf8(rt);
|
|
}
|
|
static jsi::String toJs(jsi::Runtime& rt, const std::string& value) {
|
|
return jsi::String::createFromUtf8(rt, value);
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<std::string_view> {
|
|
static jsi::String toJs(jsi::Runtime& rt, std::string_view value) {
|
|
return jsi::String::createFromUtf8(
|
|
rt, reinterpret_cast<const uint8_t*>(value.data()), value.length());
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<const char*> : Bridging<std::string_view> {};
|
|
template <size_t N>
|
|
struct Bridging<char[N]> : Bridging<std::string_view> {};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Array.h}:
|
|
namespace facebook::react {
|
|
namespace array_detail {
|
|
template <typename T, size_t N>
|
|
struct BridgingStatic {
|
|
static jsi::Array toJs(
|
|
jsi::Runtime& rt,
|
|
const T& array,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return toJs(rt, array, jsInvoker, std::make_index_sequence<N>{});
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct BridgingDynamic {
|
|
static jsi::Array toJs(
|
|
jsi::Runtime& rt,
|
|
const T& list,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
jsi::Array result(rt, list.size());
|
|
size_t index = 0;
|
|
for (const auto& item : list) {
|
|
result.setValueAtIndex(rt, index++, bridging::toJs(rt, item, jsInvoker));
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
} // namespace array_detail
|
|
template <typename T, size_t N>
|
|
struct Bridging<std::array<T, N>>
|
|
: array_detail::BridgingStatic<std::array<T, N>, N> {
|
|
static std::array<T, N> fromJs(
|
|
facebook::jsi::Runtime& rt,
|
|
const jsi::Array& array,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
size_t length = array.length(rt);
|
|
std::array<T, N> result;
|
|
for (size_t i = 0; i < length; i++) {
|
|
result[i] =
|
|
bridging::fromJs<T>(rt, array.getValueAtIndex(rt, i), jsInvoker);
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
template <typename T1, typename T2>
|
|
struct Bridging<std::pair<T1, T2>>
|
|
: array_detail::BridgingStatic<std::pair<T1, T2>, 2> {
|
|
static std::pair<T1, T1> fromJs(
|
|
facebook::jsi::Runtime& rt,
|
|
const jsi::Array& array,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return std::make_pair(
|
|
bridging::fromJs<T1>(rt, array.getValueAtIndex(rt, 0), jsInvoker),
|
|
bridging::fromJs<T2>(rt, array.getValueAtIndex(rt, 1), jsInvoker));
|
|
}
|
|
};
|
|
template <typename... Types>
|
|
struct Bridging<std::tuple<Types...>>
|
|
: array_detail::BridgingStatic<std::tuple<Types...>, sizeof...(Types)> {};
|
|
template <typename T>
|
|
struct Bridging<std::deque<T>> : array_detail::BridgingDynamic<std::deque<T>> {
|
|
};
|
|
template <typename T>
|
|
struct Bridging<std::initializer_list<T>>
|
|
: array_detail::BridgingDynamic<std::initializer_list<T>> {};
|
|
template <typename T>
|
|
struct Bridging<std::list<T>> : array_detail::BridgingDynamic<std::list<T>> {};
|
|
template <typename T>
|
|
struct Bridging<std::vector<T>>
|
|
: array_detail::BridgingDynamic<std::vector<T>> {
|
|
static std::vector<T> fromJs(
|
|
facebook::jsi::Runtime& rt,
|
|
const jsi::Array& array,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
size_t length = array.length(rt);
|
|
std::vector<T> vector;
|
|
vector.reserve(length);
|
|
for (size_t i = 0; i < length; i++) {
|
|
vector.push_back(
|
|
bridging::fromJs<T>(rt, array.getValueAtIndex(rt, i), jsInvoker));
|
|
}
|
|
return vector;
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Bridging<std::set<T>> : array_detail::BridgingDynamic<std::set<T>> {
|
|
static std::set<T> fromJs(
|
|
facebook::jsi::Runtime& rt,
|
|
const jsi::Array& array,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
size_t length = array.length(rt);
|
|
std::set<T> set;
|
|
for (size_t i = 0; i < length; i++) {
|
|
set.insert(
|
|
bridging::fromJs<T>(rt, array.getValueAtIndex(rt, i), jsInvoker));
|
|
}
|
|
return set;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Base.h}:
|
|
namespace facebook::react {
|
|
template <typename T, typename = void>
|
|
template <>
|
|
struct Bridging<void> {
|
|
static void fromJs(jsi::Runtime&, const jsi::Value&) {}
|
|
};
|
|
namespace bridging {
|
|
namespace detail {
|
|
template <typename F>
|
|
template <typename ClassT, typename ReturnT, typename... ArgsT>
|
|
struct function_wrapper<ReturnT (ClassT::*)(ArgsT...)> {
|
|
using type = std::function<ReturnT(ArgsT...)>;
|
|
};
|
|
template <typename ClassT, typename ReturnT, typename... ArgsT>
|
|
struct function_wrapper<ReturnT (ClassT::*)(ArgsT...) const> {
|
|
using type = std::function<ReturnT(ArgsT...)>;
|
|
};
|
|
template <typename T, typename = void>
|
|
struct bridging_wrapper {
|
|
using type = remove_cvref_t<T>;
|
|
};
|
|
template <typename T>
|
|
struct bridging_wrapper<
|
|
T,
|
|
std::void_t<decltype(&remove_cvref_t<T>::operator())>>
|
|
: function_wrapper<decltype(&remove_cvref_t<T>::operator())> {};
|
|
} // namespace detail
|
|
template <typename T>
|
|
using bridging_t = typename detail::bridging_wrapper<T>::type;
|
|
template <typename ReturnT, typename JSArgT>
|
|
requires is_jsi_v<JSArgT>
|
|
auto fromJs(
|
|
jsi::Runtime& rt,
|
|
JSArgT&& value,
|
|
const std::shared_ptr<CallInvoker>&)
|
|
-> decltype(static_cast<ReturnT>(
|
|
std::move(convert(rt, std::forward<JSArgT>(value))))) {
|
|
return static_cast<ReturnT>(
|
|
std::move(convert(rt, std::forward<JSArgT>(value))));
|
|
}
|
|
template <typename ReturnT, typename JSArgT>
|
|
auto fromJs(
|
|
jsi::Runtime& rt,
|
|
JSArgT&& value,
|
|
const std::shared_ptr<CallInvoker>&)
|
|
-> decltype(Bridging<remove_cvref_t<ReturnT>>::fromJs(
|
|
rt,
|
|
convert(rt, std::forward<JSArgT>(value)))) {
|
|
return Bridging<remove_cvref_t<ReturnT>>::fromJs(
|
|
rt, convert(rt, std::forward<JSArgT>(value)));
|
|
}
|
|
template <typename ReturnT, typename JSArgT>
|
|
auto fromJs(
|
|
jsi::Runtime& rt,
|
|
JSArgT&& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker)
|
|
-> decltype(Bridging<remove_cvref_t<ReturnT>>::fromJs(
|
|
rt,
|
|
convert(rt, std::forward<JSArgT>(value)),
|
|
jsInvoker)) {
|
|
return Bridging<remove_cvref_t<ReturnT>>::fromJs(
|
|
rt, convert(rt, std::forward<JSArgT>(value)), jsInvoker);
|
|
}
|
|
template <typename T>
|
|
requires is_jsi_v<T>
|
|
auto toJs(
|
|
jsi::Runtime& rt,
|
|
T&& value,
|
|
const std::shared_ptr<CallInvoker>& = nullptr) -> remove_cvref_t<T> {
|
|
return convert(rt, std::forward<T>(value));
|
|
}
|
|
template <typename T>
|
|
auto toJs(
|
|
jsi::Runtime& rt,
|
|
T&& value,
|
|
const std::shared_ptr<CallInvoker>& = nullptr)
|
|
-> decltype(Bridging<bridging_t<T>>::toJs(rt, std::forward<T>(value))) {
|
|
return Bridging<bridging_t<T>>::toJs(rt, std::forward<T>(value));
|
|
}
|
|
template <typename T>
|
|
auto toJs(
|
|
jsi::Runtime& rt,
|
|
T&& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker)
|
|
-> decltype(Bridging<bridging_t<T>>::toJs(
|
|
rt,
|
|
std::forward<T>(value),
|
|
jsInvoker)) {
|
|
return Bridging<bridging_t<T>>::toJs(rt, std::forward<T>(value), jsInvoker);
|
|
}
|
|
template <typename, typename = jsi::Value, typename = void>
|
|
inline constexpr bool supportsFromJs = false;
|
|
template <typename T, typename Arg>
|
|
inline constexpr bool supportsFromJs<
|
|
T,
|
|
Arg,
|
|
std::void_t<decltype(fromJs<T>(
|
|
std::declval<jsi::Runtime&>(),
|
|
std::declval<Arg>(),
|
|
nullptr))>> = true;
|
|
template <typename T>
|
|
inline constexpr bool supportsFromJs<
|
|
T,
|
|
jsi::Value,
|
|
std::void_t<decltype(fromJs<T>(
|
|
std::declval<jsi::Runtime&>(),
|
|
std::declval<jsi::Value>(),
|
|
nullptr))>> = true;
|
|
template <typename, typename = jsi::Value, typename = void>
|
|
inline constexpr bool supportsToJs = false;
|
|
template <typename JSReturnT, typename ReturnT>
|
|
inline constexpr bool supportsToJs<
|
|
JSReturnT,
|
|
ReturnT,
|
|
std::void_t<decltype(toJs(
|
|
std::declval<jsi::Runtime&>(),
|
|
std::declval<JSReturnT>(),
|
|
nullptr))>> =
|
|
std::is_convertible_v<
|
|
decltype(toJs(
|
|
std::declval<jsi::Runtime&>(),
|
|
std::declval<JSReturnT>(),
|
|
nullptr)),
|
|
ReturnT>;
|
|
template <typename ReturnT>
|
|
inline constexpr bool supportsToJs<
|
|
ReturnT,
|
|
jsi::Value,
|
|
std::void_t<decltype(toJs(
|
|
std::declval<jsi::Runtime&>(),
|
|
std::declval<ReturnT>(),
|
|
nullptr))>> =
|
|
std::is_convertible_v<
|
|
decltype(toJs(
|
|
std::declval<jsi::Runtime&>(),
|
|
std::declval<ReturnT>(),
|
|
nullptr)),
|
|
jsi::Value>;
|
|
} // namespace bridging
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Bool.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<bool> {
|
|
static bool fromJs(jsi::Runtime&, const jsi::Value& value) {
|
|
return value.asBool();
|
|
}
|
|
static bool toJs(jsi::Runtime&, bool value) {
|
|
return value;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Bridging.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/CallbackWrapper.h}:
|
|
namespace facebook::react {
|
|
class CallbackWrapper : public LongLivedObject { public:
|
|
static std::weak_ptr<CallbackWrapper> createWeak(
|
|
jsi::Function&& callback,
|
|
jsi::Runtime& runtime,
|
|
std::shared_ptr<CallInvoker> jsInvoker) {
|
|
auto wrapper = std::shared_ptr<CallbackWrapper>(new CallbackWrapper(
|
|
std::move(callback), runtime, std::move(jsInvoker)));
|
|
LongLivedObjectCollection::get(runtime).add(wrapper);
|
|
return wrapper;
|
|
}
|
|
void destroy() {
|
|
allowRelease();
|
|
}
|
|
jsi::Function& callback() noexcept {
|
|
return callback_;
|
|
}
|
|
jsi::Runtime& runtime() noexcept {
|
|
return runtime_;
|
|
}
|
|
CallInvoker& jsInvoker() noexcept {
|
|
return *(jsInvoker_);
|
|
}
|
|
std::shared_ptr<CallInvoker> jsInvokerPtr() noexcept {
|
|
return jsInvoker_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Class.h}:
|
|
namespace facebook::react::bridging {
|
|
template <
|
|
typename JSReturnT,
|
|
typename ClassT,
|
|
typename ReturnT,
|
|
typename... ArgsT,
|
|
typename... JSArgsT>
|
|
JSReturnT callFromJs(
|
|
jsi::Runtime& rt,
|
|
ReturnT (ClassT::*method)(jsi::Runtime&, ArgsT...),
|
|
const std::shared_ptr<CallInvoker>& jsInvoker,
|
|
ClassT* instance,
|
|
JSArgsT&&... args) {
|
|
static_assert(
|
|
sizeof...(ArgsT) == sizeof...(JSArgsT), "Incorrect arguments length");
|
|
static_assert(
|
|
(supportsFromJs<ArgsT, JSArgsT> && ...), "Incompatible arguments");
|
|
if constexpr (std::is_void_v<JSReturnT>) {
|
|
(instance->*method)(
|
|
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...);
|
|
} else if constexpr (std::is_void_v<ReturnT>) {
|
|
static_assert(
|
|
std::is_same_v<JSReturnT, jsi::Value>,
|
|
"Void functions may only return undefined");
|
|
(instance->*method)(
|
|
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...);
|
|
return jsi::Value();
|
|
} else if constexpr (
|
|
is_jsi_v<JSReturnT> || supportsToJs<ReturnT, JSReturnT>) {
|
|
static_assert(supportsToJs<ReturnT, JSReturnT>, "Incompatible return type");
|
|
return toJs(
|
|
rt,
|
|
(instance->*method)(
|
|
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...),
|
|
jsInvoker);
|
|
} else if constexpr (is_optional_jsi_v<JSReturnT>) {
|
|
static_assert(
|
|
is_optional_v<ReturnT>
|
|
? supportsToJs<
|
|
typename ReturnT::value_type,
|
|
typename JSReturnT::value_type>
|
|
: supportsToJs<ReturnT, typename JSReturnT::value_type>,
|
|
"Incompatible return type");
|
|
auto result = toJs(
|
|
rt,
|
|
(instance->*method)(
|
|
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...),
|
|
jsInvoker);
|
|
if constexpr (std::is_same_v<decltype(result), jsi::Value>) {
|
|
if (result.isNull() || result.isUndefined()) {
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
return convert(rt, std::move(result));
|
|
} else {
|
|
static_assert(
|
|
std::is_convertible_v<ReturnT, JSReturnT>, "Incompatible return type");
|
|
return (instance->*method)(
|
|
rt, fromJs<ArgsT>(rt, std::forward<JSArgsT>(args), jsInvoker)...);
|
|
}
|
|
}
|
|
template <typename ReturnT, typename... ArgsT>
|
|
constexpr size_t getParameterCount(ReturnT (*)(ArgsT...)) {
|
|
return sizeof...(ArgsT);
|
|
}
|
|
template <typename Class, typename ReturnT, typename... ArgsT>
|
|
constexpr size_t getParameterCount(ReturnT (Class::*)(ArgsT...)) {
|
|
return sizeof...(ArgsT);
|
|
}
|
|
} // namespace facebook::react::bridging
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Convert.h}:
|
|
namespace facebook::react::bridging {
|
|
template <typename T>
|
|
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
|
template <typename T>
|
|
inline constexpr bool is_jsi_v =
|
|
std::is_same_v<jsi::Value, remove_cvref_t<T>> ||
|
|
std::is_same_v<jsi::String, remove_cvref_t<T>> ||
|
|
std::is_base_of_v<jsi::Object, remove_cvref_t<T>>;
|
|
template <typename>
|
|
struct is_optional : std::false_type {};
|
|
template <typename T>
|
|
struct is_optional<std::optional<T>> : std::true_type {};
|
|
template <typename T>
|
|
inline constexpr bool is_optional_v = is_optional<T>::value;
|
|
template <typename T, typename = void>
|
|
inline constexpr bool is_optional_jsi_v = false;
|
|
template <typename T>
|
|
inline constexpr bool
|
|
is_optional_jsi_v<T, typename std::enable_if_t<is_optional_v<T>>> =
|
|
is_jsi_v<typename T::value_type>;
|
|
template <typename T>
|
|
template <typename T>
|
|
struct ConverterBase {
|
|
using BaseT = remove_cvref_t<T>;
|
|
ConverterBase(jsi::Runtime& rt, T&& value)
|
|
: rt_(rt), value_(std::forward<T>(value)) {}
|
|
operator BaseT() && {
|
|
if constexpr (std::is_lvalue_reference_v<T>) {
|
|
auto value = jsi::Value(rt_, value_);
|
|
if constexpr (std::is_same_v<BaseT, jsi::Value>) {
|
|
return std::move(value);
|
|
} else if constexpr (std::is_same_v<BaseT, jsi::String>) {
|
|
return std::move(value).getString(rt_);
|
|
} else if constexpr (std::is_same_v<BaseT, jsi::Object>) {
|
|
return std::move(value).getObject(rt_);
|
|
} else if constexpr (std::is_same_v<BaseT, jsi::Array>) {
|
|
return std::move(value).getObject(rt_).getArray(rt_);
|
|
} else if constexpr (std::is_same_v<BaseT, jsi::Function>) {
|
|
return std::move(value).getObject(rt_).getFunction(rt_);
|
|
}
|
|
} else {
|
|
return std::move(value_);
|
|
}
|
|
}
|
|
template <
|
|
typename U,
|
|
std::enable_if_t<
|
|
std::is_lvalue_reference_v<T> &&
|
|
std::is_convertible_v<Converter<BaseT>, U>,
|
|
int> = 0>
|
|
operator U() && {
|
|
return Converter<BaseT>(rt_, std::move(*this).operator BaseT());
|
|
}
|
|
template <
|
|
typename U,
|
|
std::enable_if_t<is_jsi_v<T> && std::is_same_v<U, jsi::Value>, int> = 0>
|
|
operator U() && = delete;
|
|
|
|
protected:
|
|
jsi::Runtime& rt_;
|
|
T value_;
|
|
};
|
|
template <typename T>
|
|
struct Converter : public ConverterBase<T> {
|
|
using ConverterBase<T>::ConverterBase;
|
|
};
|
|
template <>
|
|
struct Converter<jsi::Value> : public ConverterBase<jsi::Value> {
|
|
using ConverterBase<jsi::Value>::ConverterBase;
|
|
operator jsi::String() && {
|
|
return std::move(value_).asString(rt_);
|
|
}
|
|
operator jsi::Object() && {
|
|
return std::move(value_).asObject(rt_);
|
|
}
|
|
operator jsi::Array() && {
|
|
return std::move(value_).asObject(rt_).asArray(rt_);
|
|
}
|
|
operator jsi::Function() && {
|
|
return std::move(value_).asObject(rt_).asFunction(rt_);
|
|
}
|
|
};
|
|
template <>
|
|
struct Converter<jsi::Object> : public ConverterBase<jsi::Object> {
|
|
using ConverterBase<jsi::Object>::ConverterBase;
|
|
operator jsi::Array() && {
|
|
return std::move(value_).asArray(rt_);
|
|
}
|
|
operator jsi::Function() && {
|
|
return std::move(value_).asFunction(rt_);
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Converter<std::optional<T>> : public ConverterBase<jsi::Value> {
|
|
Converter(jsi::Runtime& rt, std::optional<T> value)
|
|
: ConverterBase(rt, value ? std::move(*value) : jsi::Value::null()) {}
|
|
operator std::optional<T>() && {
|
|
if (value_.isNull() || value_.isUndefined()) {
|
|
return {};
|
|
}
|
|
return std::move(value_);
|
|
}
|
|
};
|
|
template <typename T, std::enable_if_t<is_jsi_v<T>, int> = 0>
|
|
auto convert(jsi::Runtime& rt, T&& value) {
|
|
return Converter<T>(rt, std::forward<T>(value));
|
|
}
|
|
template <
|
|
typename T,
|
|
std::enable_if_t<is_jsi_v<T> || std::is_scalar_v<T>, int> = 0>
|
|
auto convert(jsi::Runtime& rt, std::optional<T> value) {
|
|
return Converter<std::optional<T>>(rt, std::move(value));
|
|
}
|
|
template <typename T, std::enable_if_t<std::is_scalar_v<T>, int> = 0>
|
|
auto convert(jsi::Runtime&, T&& value) {
|
|
return value;
|
|
}
|
|
template <typename T>
|
|
auto convert(jsi::Runtime&, Converter<T>&& converter) {
|
|
return std::move(converter);
|
|
}
|
|
} // namespace facebook::react::bridging
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Dynamic.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<folly::dynamic> {
|
|
static folly::dynamic fromJs(jsi::Runtime& rt, const jsi::Value& value) {
|
|
return jsi::dynamicFromValue(rt, value);
|
|
}
|
|
static jsi::Value toJs(jsi::Runtime& rt, const folly::dynamic& value) {
|
|
return jsi::valueFromDynamic(rt, value);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Error.h}:
|
|
namespace facebook::react {
|
|
class Error {
|
|
public:
|
|
Error(std::string message) : message_(std::move(message)) {}
|
|
Error(const char* message) : Error(std::string(message)) {}
|
|
const std::string& message() const {
|
|
return message_;
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<jsi::JSError> {
|
|
static jsi::JSError fromJs(jsi::Runtime& rt, const jsi::Value& value) {
|
|
return jsi::JSError(rt, jsi::Value(rt, value));
|
|
}
|
|
static jsi::JSError fromJs(jsi::Runtime& rt, jsi::Value&& value) {
|
|
return jsi::JSError(rt, std::move(value));
|
|
}
|
|
static jsi::Value toJs(jsi::Runtime& rt, std::string message) {
|
|
return jsi::Value(rt, jsi::JSError(rt, std::move(message)).value());
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<Error> {
|
|
static jsi::Value toJs(jsi::Runtime& rt, const Error& error) {
|
|
return jsi::Value(rt, jsi::JSError(rt, error.message()).value());
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/EventEmitter.h}:
|
|
namespace facebook::react {
|
|
class EventSubscription {
|
|
public:
|
|
explicit EventSubscription(std::function<void()> remove)
|
|
: remove_(std::move(remove)) {}
|
|
~EventSubscription() = default;
|
|
EventSubscription(EventSubscription&&) noexcept = default;
|
|
EventSubscription& operator=(EventSubscription&&) noexcept = default;
|
|
EventSubscription(const EventSubscription&) = delete;
|
|
EventSubscription& operator=(const EventSubscription&) = delete;
|
|
};
|
|
template <>
|
|
struct Bridging<EventSubscription> {
|
|
static jsi::Object toJs(
|
|
jsi::Runtime& rt,
|
|
const EventSubscription& eventSubscription,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
auto result = jsi::Object(rt);
|
|
result.setProperty(
|
|
rt, "remove", bridging::toJs(rt, eventSubscription.remove_, jsInvoker));
|
|
return result;
|
|
}
|
|
};
|
|
class IAsyncEventEmitter {
|
|
public:
|
|
IAsyncEventEmitter() noexcept = default;
|
|
virtual ~IAsyncEventEmitter() noexcept = default;
|
|
IAsyncEventEmitter(IAsyncEventEmitter&&) noexcept = default;
|
|
IAsyncEventEmitter& operator=(IAsyncEventEmitter&&) noexcept = default;
|
|
IAsyncEventEmitter(const IAsyncEventEmitter&) = delete;
|
|
IAsyncEventEmitter& operator=(const IAsyncEventEmitter&) = delete;
|
|
virtual jsi::Object get(
|
|
jsi::Runtime& rt,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) const = 0;
|
|
};
|
|
template <typename... Args>
|
|
class AsyncEventEmitter : public IAsyncEventEmitter {
|
|
static_assert(
|
|
sizeof...(Args) <= 1,
|
|
"AsyncEventEmitter must have at most one argument");
|
|
|
|
public:
|
|
AsyncEventEmitter() : state_(std::make_shared<SharedState>()) {
|
|
listen_ = [state = state_](AsyncCallback<Args...> listener) {
|
|
std::lock_guard<std::mutex> lock(state->mutex);
|
|
auto listenerId = state->listenerId++;
|
|
state->listeners.emplace(listenerId, std::move(listener));
|
|
return EventSubscription([state, listenerId]() {
|
|
std::lock_guard<std::mutex> innerLock(state->mutex);
|
|
state->listeners.erase(listenerId);
|
|
});
|
|
};
|
|
}
|
|
~AsyncEventEmitter() override = default;
|
|
AsyncEventEmitter(AsyncEventEmitter&&) noexcept = default;
|
|
AsyncEventEmitter& operator=(AsyncEventEmitter&&) noexcept = default;
|
|
AsyncEventEmitter(const AsyncEventEmitter&) = delete;
|
|
AsyncEventEmitter& operator=(const AsyncEventEmitter&) = delete;
|
|
void emit(std::function<jsi::Value(jsi::Runtime&)>&& converter) {
|
|
std::lock_guard<std::mutex> lock(state_->mutex);
|
|
for (auto& [_, listener] : state_->listeners) {
|
|
listener.call([converter](jsi::Runtime& rt, jsi::Function& jsFunction) {
|
|
jsFunction.call(rt, converter(rt));
|
|
});
|
|
}
|
|
}
|
|
void emit(Args... value) {
|
|
std::lock_guard<std::mutex> lock(state_->mutex);
|
|
for (const auto& [_, listener] : state_->listeners) {
|
|
listener.call(static_cast<Args>(value)...);
|
|
}
|
|
}
|
|
jsi::Object get(
|
|
jsi::Runtime& rt,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) const override {
|
|
return bridging::toJs(rt, listen_, jsInvoker);
|
|
}
|
|
};
|
|
};
|
|
std::function<EventSubscription(AsyncCallback<Args...>)> listen_;
|
|
std::shared_ptr<SharedState> state_;
|
|
};
|
|
template <typename... Args>
|
|
struct Bridging<AsyncEventEmitter<Args...>> {
|
|
static jsi::Object toJs(
|
|
jsi::Runtime& rt,
|
|
const AsyncEventEmitter<Args...>& eventEmitter,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return eventEmitter.get(rt, jsInvoker);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Function.h}:
|
|
namespace facebook::react {
|
|
template <typename F>
|
|
template <typename... Args>
|
|
class AsyncCallback {
|
|
public:
|
|
AsyncCallback(
|
|
jsi::Runtime& runtime,
|
|
jsi::Function function,
|
|
std::shared_ptr<CallInvoker> jsInvoker)
|
|
: callback_(std::make_shared<SyncCallback<void(Args...)>>(
|
|
runtime,
|
|
std::move(function),
|
|
std::move(jsInvoker))) {}
|
|
void operator()(Args... args) const noexcept {
|
|
call(std::forward<Args>(args)...);
|
|
}
|
|
void call(Args... args) const noexcept {
|
|
callWithArgs(std::nullopt, std::forward<Args>(args)...);
|
|
}
|
|
void callWithPriority(SchedulerPriority priority, Args... args)
|
|
const noexcept {
|
|
callWithArgs(priority, std::forward<Args>(args)...);
|
|
}
|
|
void call(std::function<void(jsi::Runtime&, jsi::Function&)>&& callImpl)
|
|
const noexcept {
|
|
callWithFunction(std::nullopt, std::move(callImpl));
|
|
}
|
|
void callWithPriority(
|
|
SchedulerPriority priority,
|
|
std::function<void(jsi::Runtime&, jsi::Function&)>&& callImpl)
|
|
const noexcept {
|
|
callWithFunction(priority, std::move(callImpl));
|
|
}
|
|
};
|
|
auto& jsInvoker = wrapper->jsInvoker();
|
|
if (priority) {
|
|
jsInvoker.invokeAsync(*priority, std::move(fn));
|
|
} else {
|
|
jsInvoker.invokeAsync(std::move(fn));
|
|
}
|
|
}
|
|
}
|
|
void callWithFunction(
|
|
std::optional<SchedulerPriority> priority,
|
|
std::function<void(jsi::Runtime&, jsi::Function&)>&& callImpl)
|
|
const noexcept {
|
|
if (auto wrapper = callback_->wrapper_.lock()) {
|
|
auto fn = [callback = callback_,
|
|
callImpl = std::move(callImpl)](jsi::Runtime& rt) {
|
|
if (auto wrapper2 = callback->wrapper_.lock()) {
|
|
callImpl(rt, wrapper2->callback());
|
|
}
|
|
};
|
|
auto& jsInvoker = wrapper->jsInvoker();
|
|
if (priority) {
|
|
jsInvoker.invokeAsync(*priority, std::move(fn));
|
|
} else {
|
|
jsInvoker.invokeAsync(std::move(fn));
|
|
}
|
|
}
|
|
}
|
|
};
|
|
template <typename R, typename... Args>
|
|
class SyncCallback<R(Args...)> {
|
|
public:
|
|
SyncCallback(
|
|
jsi::Runtime& rt,
|
|
jsi::Function function,
|
|
std::shared_ptr<CallInvoker> jsInvoker)
|
|
: wrapper_(CallbackWrapper::createWeak(
|
|
std::move(function),
|
|
rt,
|
|
std::move(jsInvoker))) {}
|
|
SyncCallback(const SyncCallback&) = delete;
|
|
SyncCallback& operator=(const SyncCallback&) = delete;
|
|
SyncCallback(SyncCallback&& other) noexcept
|
|
: wrapper_(std::move(other.wrapper_)) {}
|
|
SyncCallback& operator=(SyncCallback&& other) noexcept {
|
|
wrapper_ = std::move(other.wrapper_);
|
|
return *this;
|
|
}
|
|
~SyncCallback() {
|
|
if (auto wrapper = wrapper_.lock()) {
|
|
wrapper->destroy();
|
|
}
|
|
}
|
|
R operator()(Args... args) const {
|
|
return call(std::forward<Args>(args)...);
|
|
}
|
|
R call(Args... args) const {
|
|
auto wrapper = wrapper_.lock();
|
|
if (!wrapper) {
|
|
if constexpr (std::is_void_v<R>) {
|
|
return;
|
|
} else {
|
|
throw std::runtime_error("Failed to call invalidated sync callback");
|
|
}
|
|
}
|
|
auto& callback = wrapper->callback();
|
|
auto& rt = wrapper->runtime();
|
|
auto jsInvoker = wrapper->jsInvokerPtr();
|
|
if constexpr (std::is_void_v<R>) {
|
|
callback.call(
|
|
rt, bridging::toJs(rt, std::forward<Args>(args), jsInvoker)...);
|
|
} else {
|
|
return bridging::fromJs<R>(
|
|
rt,
|
|
callback.call(
|
|
rt, bridging::toJs(rt, std::forward<Args>(args), jsInvoker)...),
|
|
jsInvoker);
|
|
}
|
|
}
|
|
};
|
|
template <typename... Args>
|
|
struct Bridging<AsyncCallback<Args...>> {
|
|
static AsyncCallback<Args...> fromJs(
|
|
jsi::Runtime& rt,
|
|
jsi::Function&& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return AsyncCallback<Args...>(rt, std::move(value), jsInvoker);
|
|
}
|
|
static jsi::Function toJs(
|
|
jsi::Runtime& rt,
|
|
const AsyncCallback<Args...>& value) {
|
|
return value.callback_->function_.getFunction(rt);
|
|
}
|
|
};
|
|
template <typename R, typename... Args>
|
|
struct Bridging<SyncCallback<R(Args...)>> {
|
|
static SyncCallback<R(Args...)> fromJs(
|
|
jsi::Runtime& rt,
|
|
jsi::Function&& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return SyncCallback<R(Args...)>(rt, std::move(value), jsInvoker);
|
|
}
|
|
static jsi::Function toJs(
|
|
jsi::Runtime& rt,
|
|
const SyncCallback<R(Args...)>& value) {
|
|
return value.function_.getFunction(rt);
|
|
}
|
|
};
|
|
template <typename R, typename... Args>
|
|
struct Bridging<std::function<R(Args...)>> {
|
|
using Func = std::function<R(Args...)>;
|
|
using IndexSequence = std::index_sequence_for<Args...>;
|
|
static constexpr size_t kArgumentCount = sizeof...(Args);
|
|
static jsi::Function toJs(
|
|
jsi::Runtime& rt,
|
|
Func fn,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return jsi::Function::createFromHostFunction(
|
|
rt,
|
|
jsi::PropNameID::forAscii(rt, "BridgedFunction"),
|
|
kArgumentCount,
|
|
[fn = std::make_shared<Func>(std::move(fn)), jsInvoker](
|
|
jsi::Runtime& rt,
|
|
const jsi::Value&,
|
|
const jsi::Value* args,
|
|
size_t count) -> jsi::Value {
|
|
if (count < kArgumentCount) {
|
|
throw jsi::JSError(rt, "Incorrect number of arguments");
|
|
}
|
|
if constexpr (std::is_void_v<R>) {
|
|
callFromJs(*fn, rt, args, jsInvoker, IndexSequence{});
|
|
return jsi::Value();
|
|
} else {
|
|
return bridging::toJs(
|
|
rt,
|
|
callFromJs(*fn, rt, args, jsInvoker, IndexSequence{}),
|
|
jsInvoker);
|
|
}
|
|
});
|
|
}
|
|
};
|
|
template <typename R, typename... Args>
|
|
struct Bridging<
|
|
std::function<R(Args...)>,
|
|
std::enable_if_t<
|
|
!std::is_same_v<std::function<R(Args...)>, std::function<R(Args...)>>>>
|
|
: Bridging<std::function<R(Args...)>> {};
|
|
template <typename R, typename... Args>
|
|
struct Bridging<R(Args...)> : Bridging<std::function<R(Args...)>> {};
|
|
template <typename R, typename... Args>
|
|
struct Bridging<R (*)(Args...)> : Bridging<std::function<R(Args...)>> {};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/HighResTimeStamp.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<HighResTimeStamp> {
|
|
static HighResTimeStamp fromJs(jsi::Runtime&, const jsi::Value& jsiValue) {
|
|
return HighResTimeStamp::fromDOMHighResTimeStamp(jsiValue.asNumber());
|
|
}
|
|
static double toJs(jsi::Runtime&, const HighResTimeStamp& value) {
|
|
return value.toDOMHighResTimeStamp();
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<HighResDuration> {
|
|
static HighResDuration fromJs(jsi::Runtime&, const jsi::Value& jsiValue) {
|
|
return HighResDuration::fromDOMHighResTimeStamp(jsiValue.asNumber());
|
|
}
|
|
static double toJs(jsi::Runtime&, const HighResDuration& value) {
|
|
return value.toDOMHighResTimeStamp();
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/LongLivedObject.h}:
|
|
namespace facebook::react {
|
|
class LongLivedObject {
|
|
public:
|
|
virtual void allowRelease();
|
|
|
|
protected:
|
|
explicit LongLivedObject(jsi::Runtime& runtime) : runtime_(runtime) {}
|
|
virtual ~LongLivedObject() = default;
|
|
jsi::Runtime& runtime_;
|
|
};
|
|
class LongLivedObjectCollection {
|
|
public:
|
|
static LongLivedObjectCollection& get(jsi::Runtime& runtime);
|
|
LongLivedObjectCollection() = default;
|
|
LongLivedObjectCollection(const LongLivedObjectCollection&) = delete;
|
|
void operator=(const LongLivedObjectCollection&) = delete;
|
|
void add(std::shared_ptr<LongLivedObject> o);
|
|
void remove(const LongLivedObject* o);
|
|
void clear();
|
|
size_t size() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Number.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<double> {
|
|
static double fromJs(jsi::Runtime&, const jsi::Value& value) {
|
|
return value.asNumber();
|
|
}
|
|
static double toJs(jsi::Runtime&, double value) {
|
|
return value;
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<float> {
|
|
static float fromJs(jsi::Runtime&, const jsi::Value& value) {
|
|
return (float)value.asNumber();
|
|
}
|
|
static float toJs(jsi::Runtime&, float value) {
|
|
return value;
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<int32_t> {
|
|
static int32_t fromJs(jsi::Runtime&, const jsi::Value& value) {
|
|
return (int32_t)value.asNumber();
|
|
}
|
|
static int32_t toJs(jsi::Runtime&, int32_t value) {
|
|
return value;
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<uint32_t> {
|
|
static uint32_t fromJs(jsi::Runtime&, const jsi::Value& value) {
|
|
return (uint32_t)value.asNumber();
|
|
}
|
|
static jsi::Value toJs(jsi::Runtime&, uint32_t value) {
|
|
return double(value);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Object.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<jsi::WeakObject> {
|
|
static jsi::WeakObject fromJs(jsi::Runtime& rt, const jsi::Object& value) {
|
|
return jsi::WeakObject(rt, value);
|
|
}
|
|
static jsi::Value toJs(jsi::Runtime& rt, jsi::WeakObject& value) {
|
|
return value.lock(rt);
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Bridging<
|
|
std::shared_ptr<T>,
|
|
std::enable_if_t<std::is_base_of_v<jsi::HostObject, T>>> {
|
|
static std::shared_ptr<T> fromJs(jsi::Runtime& rt, const jsi::Object& value) {
|
|
return value.getHostObject<T>(rt);
|
|
}
|
|
static jsi::Object toJs(jsi::Runtime& rt, std::shared_ptr<T> value) {
|
|
return jsi::Object::createFromHostObject(rt, std::move(value));
|
|
}
|
|
};
|
|
namespace map_detail {
|
|
template <typename T>
|
|
struct Bridging {
|
|
static T fromJs(
|
|
jsi::Runtime& rt,
|
|
const jsi::Object& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
T result;
|
|
auto propertyNames = value.getPropertyNames(rt);
|
|
auto length = propertyNames.length(rt);
|
|
for (size_t i = 0; i < length; i++) {
|
|
auto propertyName = propertyNames.getValueAtIndex(rt, i);
|
|
result.emplace(
|
|
bridging::fromJs<std::string>(rt, propertyName, jsInvoker),
|
|
bridging::fromJs<typename T::mapped_type>(
|
|
rt, value.getProperty(rt, propertyName.asString(rt)), jsInvoker));
|
|
}
|
|
return result;
|
|
}
|
|
static jsi::Object toJs(
|
|
jsi::Runtime& rt,
|
|
const T& map,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
auto resultObject = jsi::Object(rt);
|
|
for (const auto& [key, value] : map) {
|
|
resultObject.setProperty(
|
|
rt,
|
|
jsi::PropNameID::forUtf8(rt, key),
|
|
bridging::toJs(rt, value, jsInvoker));
|
|
}
|
|
return resultObject;
|
|
}
|
|
};
|
|
} // namespace map_detail
|
|
template <typename... Args>
|
|
struct Bridging<std::map<std::string, Args...>>
|
|
: map_detail::Bridging<std::map<std::string, Args...>> {};
|
|
template <typename... Args>
|
|
struct Bridging<std::unordered_map<std::string, Args...>>
|
|
: map_detail::Bridging<std::unordered_map<std::string, Args...>> {};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Promise.h}:
|
|
namespace facebook::react {
|
|
template <typename... T>
|
|
class AsyncPromise {
|
|
static_assert(
|
|
sizeof...(T) <= 1,
|
|
"AsyncPromise must have at most one argument");
|
|
|
|
public:
|
|
AsyncPromise(jsi::Runtime& rt, const std::shared_ptr<CallInvoker>& jsInvoker)
|
|
: state_(std::make_shared<SharedState>()) {
|
|
auto constructor = rt.global().getPropertyAsFunction(rt, "Promise");
|
|
auto promise = constructor.callAsConstructor(
|
|
rt,
|
|
bridging::toJs(
|
|
rt,
|
|
[this](
|
|
AsyncCallback<T...> resolve,
|
|
const AsyncCallback<Error>& reject) {
|
|
state_->resolve = std::move(resolve);
|
|
state_->reject = std::move(reject);
|
|
},
|
|
jsInvoker));
|
|
auto promiseHolder =
|
|
std::make_shared<PromiseHolder>(rt, promise.asObject(rt));
|
|
LongLivedObjectCollection::get(rt).add(promiseHolder);
|
|
state_->promiseHolder = promiseHolder;
|
|
}
|
|
void resolve(T... value) {
|
|
std::lock_guard<std::mutex> lock(state_->mutex);
|
|
if (state_->resolve) {
|
|
state_->resolve->call(std::forward<T>(value)...);
|
|
state_->resolve.reset();
|
|
state_->reject.reset();
|
|
}
|
|
}
|
|
void reject(Error error) {
|
|
std::lock_guard<std::mutex> lock(state_->mutex);
|
|
if (state_->reject) {
|
|
state_->reject->call(std::move(error));
|
|
state_->reject.reset();
|
|
state_->resolve.reset();
|
|
}
|
|
}
|
|
jsi::Object get(jsi::Runtime& rt) const {
|
|
if (auto holder = state_->promiseHolder.lock()) {
|
|
return jsi::Value(rt, holder->promise).asObject(rt);
|
|
} else {
|
|
throw jsi::JSError(rt, "Failed to get invalidated promise");
|
|
}
|
|
}
|
|
};
|
|
struct SharedState {
|
|
~SharedState() {
|
|
if (auto holder = promiseHolder.lock()) {
|
|
holder->allowRelease();
|
|
}
|
|
}
|
|
std::mutex mutex;
|
|
std::weak_ptr<PromiseHolder> promiseHolder;
|
|
std::optional<AsyncCallback<T...>> resolve;
|
|
std::optional<AsyncCallback<Error>> reject;
|
|
};
|
|
std::shared_ptr<SharedState> state_;
|
|
};
|
|
template <typename... T>
|
|
struct Bridging<AsyncPromise<T...>> {
|
|
static jsi::Object toJs(jsi::Runtime& rt, const AsyncPromise<T...>& promise) {
|
|
return promise.get(rt);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/Value.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<std::nullptr_t> {
|
|
static std::nullptr_t fromJs(jsi::Runtime& rt, const jsi::Value& value) {
|
|
if (value.isNull() || value.isUndefined()) {
|
|
return nullptr;
|
|
} else {
|
|
throw jsi::JSError(rt, "Cannot convert value to nullptr");
|
|
}
|
|
}
|
|
static std::nullptr_t toJs(jsi::Runtime&, std::nullptr_t) {
|
|
return nullptr;
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Bridging<std::optional<T>> {
|
|
static std::optional<T> fromJs(
|
|
jsi::Runtime& rt,
|
|
const jsi::Value& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
if (value.isNull() || value.isUndefined()) {
|
|
return {};
|
|
}
|
|
return bridging::fromJs<T>(rt, value, jsInvoker);
|
|
}
|
|
template <typename U>
|
|
static std::optional<T> fromJs(
|
|
jsi::Runtime& rt,
|
|
const std::optional<U>& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
if (value) {
|
|
return bridging::fromJs<T>(rt, *value, jsInvoker);
|
|
}
|
|
return {};
|
|
}
|
|
static jsi::Value toJs(
|
|
jsi::Runtime& rt,
|
|
const std::optional<T>& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
if (value) {
|
|
return bridging::toJs(rt, *value, jsInvoker);
|
|
}
|
|
return jsi::Value::null();
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Bridging<
|
|
std::shared_ptr<T>,
|
|
std::enable_if_t<!std::is_base_of_v<jsi::HostObject, T>>> {
|
|
static jsi::Value toJs(
|
|
jsi::Runtime& rt,
|
|
const std::shared_ptr<T>& ptr,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
if (ptr) {
|
|
return bridging::toJs(rt, *ptr, jsInvoker);
|
|
}
|
|
return jsi::Value::null();
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Bridging<std::unique_ptr<T>> {
|
|
static jsi::Value toJs(
|
|
jsi::Runtime& rt,
|
|
const std::unique_ptr<T>& ptr,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
if (ptr) {
|
|
return bridging::toJs(rt, *ptr, jsInvoker);
|
|
}
|
|
return jsi::Value::null();
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct Bridging<std::weak_ptr<T>> {
|
|
static jsi::Value toJs(
|
|
jsi::Runtime& rt,
|
|
const std::weak_ptr<T>& weakPtr,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
if (auto ptr = weakPtr.lock()) {
|
|
return bridging::toJs(rt, *ptr, jsInvoker);
|
|
}
|
|
return jsi::Value::null();
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/bridging/tests/BridgingTest.h}:
|
|
namespace facebook::react {
|
|
class BridgingTest : public ::testing::Test {
|
|
public:
|
|
BridgingTest(BridgingTest& other) = delete;
|
|
BridgingTest& operator=(BridgingTest& other) = delete;
|
|
BridgingTest(BridgingTest&& other) = delete;
|
|
BridgingTest& operator=(BridgingTest&& other) = delete;
|
|
|
|
protected:
|
|
BridgingTest()
|
|
: runtime(hermes::makeHermesRuntime(::hermes::vm::RuntimeConfig::Builder()
|
|
.withMicrotaskQueue(true)
|
|
.build())),
|
|
rt(*runtime),
|
|
invoker(std::make_shared<TestCallInvoker>(runtime)) {}
|
|
~BridgingTest() override {
|
|
LongLivedObjectCollection::get(rt).clear();
|
|
}
|
|
void TearDown() override {
|
|
flushQueue();
|
|
EXPECT_EQ(0, LongLivedObjectCollection::get(rt).size());
|
|
}
|
|
jsi::Value eval(const std::string& js) {
|
|
return rt.global().getPropertyAsFunction(rt, "eval").call(rt, js);
|
|
}
|
|
jsi::Function function(const std::string& js) {
|
|
return eval(("(" + js + ")").c_str()).getObject(rt).getFunction(rt);
|
|
}
|
|
void flushQueue() {
|
|
invoker->flushQueue();
|
|
}
|
|
std::shared_ptr<jsi::Runtime> runtime;
|
|
jsi::Runtime& rt;
|
|
std::shared_ptr<TestCallInvoker> invoker;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/debug/flags.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/debug/react_native_assert.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/debug/react_native_expect.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/CxxTurboModuleUtils.h}:
|
|
namespace facebook::react {
|
|
std::unordered_map<
|
|
std::string,
|
|
std::function<
|
|
std::shared_ptr<TurboModule>(std::shared_ptr<CallInvoker> jsInvoker)>>&
|
|
globalExportedCxxTurboModuleMap();
|
|
void registerCxxModuleToGlobalModuleMap(
|
|
std::string name,
|
|
std::function<std::shared_ptr<TurboModule>(
|
|
std::shared_ptr<CallInvoker> jsInvoker)> moduleProviderFunc);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboCxxModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.h}
|
|
|
|
namespace facebook::react {
|
|
class JSI_EXPORT TurboCxxModule : public TurboModule {
|
|
public:
|
|
TurboCxxModule(
|
|
std::unique_ptr<facebook::xplat::module::CxxModule> cxxModule,
|
|
std::shared_ptr<CallInvoker> jsInvoker);
|
|
facebook::jsi::Value create(
|
|
facebook::jsi::Runtime& runtime,
|
|
const facebook::jsi::PropNameID& propName) override;
|
|
std::vector<facebook::jsi::PropNameID> getPropertyNames(
|
|
facebook::jsi::Runtime& runtime) override;
|
|
jsi::Value invokeMethod(
|
|
jsi::Runtime& runtime,
|
|
const std::string& methodName,
|
|
const jsi::Value* args,
|
|
size_t count);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModule.h}:
|
|
namespace facebook::react {
|
|
enum TurboModuleMethodValueKind {
|
|
VoidKind,
|
|
BooleanKind,
|
|
NumberKind,
|
|
StringKind,
|
|
ObjectKind,
|
|
ArrayKind,
|
|
FunctionKind,
|
|
PromiseKind,
|
|
};
|
|
TurboModuleMethodValueKind getTurboModuleMethodValueKind(
|
|
jsi::Runtime& rt,
|
|
const jsi::Value* value);
|
|
class JSI_EXPORT TurboModule : public jsi::HostObject {
|
|
public:
|
|
TurboModule(std::string name, std::shared_ptr<CallInvoker> jsInvoker);
|
|
jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& propName)
|
|
override {
|
|
auto prop = create(runtime, propName);
|
|
if (jsRepresentation_ && !prop.isUndefined()) {
|
|
jsRepresentation_->lock(runtime).asObject(runtime).setProperty(
|
|
runtime, propName, prop);
|
|
}
|
|
return prop;
|
|
}
|
|
std::vector<jsi::PropNameID> getPropertyNames(
|
|
jsi::Runtime& runtime) override {
|
|
std::vector<jsi::PropNameID> result;
|
|
result.reserve(methodMap_.size());
|
|
for (auto it = methodMap_.cbegin(); it != methodMap_.cend(); ++it) {
|
|
result.push_back(jsi::PropNameID::forUtf8(runtime, it->first));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
protected:
|
|
const std::string name_;
|
|
std::shared_ptr<CallInvoker> jsInvoker_;
|
|
struct MethodMetadata {
|
|
size_t argCount;
|
|
jsi::Value (*invoker)(
|
|
jsi::Runtime& rt,
|
|
TurboModule& turboModule,
|
|
const jsi::Value* args,
|
|
size_t count);
|
|
};
|
|
std::unordered_map<std::string, MethodMetadata> methodMap_;
|
|
std::unordered_map<std::string, std::shared_ptr<IAsyncEventEmitter>>
|
|
eventEmitterMap_;
|
|
using ArgFactory =
|
|
std::function<void(jsi::Runtime& runtime, std::vector<jsi::Value>& args)>;
|
|
void emitDeviceEvent(
|
|
const std::string& eventName,
|
|
ArgFactory argFactory = nullptr);
|
|
void emitDeviceEvent(
|
|
jsi::Runtime&,
|
|
const std::string& eventName,
|
|
ArgFactory argFactory = nullptr) {
|
|
emitDeviceEvent(eventName, std::move(argFactory));
|
|
}
|
|
virtual jsi::Value create(
|
|
jsi::Runtime& runtime,
|
|
const jsi::PropNameID& propName) {
|
|
std::string propNameUtf8 = propName.utf8(runtime);
|
|
if (auto methodIter = methodMap_.find(propNameUtf8);
|
|
methodIter != methodMap_.end()) {
|
|
const MethodMetadata& meta = methodIter->second;
|
|
return jsi::Function::createFromHostFunction(
|
|
runtime,
|
|
propName,
|
|
static_cast<unsigned int>(meta.argCount),
|
|
[this, meta](
|
|
jsi::Runtime& rt,
|
|
[[maybe_unused]] const jsi::Value& thisVal,
|
|
const jsi::Value* args,
|
|
size_t count) { return meta.invoker(rt, *this, args, count); });
|
|
} else if (auto eventEmitterIter = eventEmitterMap_.find(propNameUtf8);
|
|
eventEmitterIter != eventEmitterMap_.end()) {
|
|
return eventEmitterIter->second->get(runtime, jsInvoker_);
|
|
} else {
|
|
return jsi::Value::undefined();
|
|
}
|
|
}
|
|
};
|
|
using TurboModuleProviderFunctionType =
|
|
std::function<std::shared_ptr<TurboModule>(const std::string& name)>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h}:
|
|
namespace facebook::react {
|
|
class TurboModuleBinding {
|
|
public:
|
|
static void install(
|
|
jsi::Runtime& runtime,
|
|
TurboModuleProviderFunctionType&& moduleProvider,
|
|
TurboModuleProviderFunctionType&& legacyModuleProvider = nullptr,
|
|
std::shared_ptr<LongLivedObjectCollection> longLivedObjectCollection =
|
|
nullptr);
|
|
TurboModuleBinding(
|
|
jsi::Runtime& runtime,
|
|
TurboModuleProviderFunctionType&& moduleProvider,
|
|
std::shared_ptr<LongLivedObjectCollection> longLivedObjectCollection);
|
|
virtual ~TurboModuleBinding();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModulePerfLogger.h}:
|
|
namespace facebook::react::TurboModulePerfLogger {
|
|
void enableLogging(std::unique_ptr<NativeModulePerfLogger>&& logger);
|
|
void disableLogging();
|
|
void moduleDataCreateStart(const char* moduleName, int32_t id);
|
|
void moduleDataCreateEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateStart(const char* moduleName, int32_t id);
|
|
void moduleCreateCacheHit(const char* moduleName, int32_t id);
|
|
void moduleCreateConstructStart(const char* moduleName, int32_t id);
|
|
void moduleCreateConstructEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateSetUpStart(const char* moduleName, int32_t id);
|
|
void moduleCreateSetUpEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateFail(const char* moduleName, int32_t id);
|
|
void moduleJSRequireBeginningStart(const char* moduleName);
|
|
void moduleJSRequireBeginningCacheHit(const char* moduleName);
|
|
void moduleJSRequireBeginningEnd(const char* moduleName);
|
|
void moduleJSRequireBeginningFail(const char* moduleName);
|
|
void moduleJSRequireEndingStart(const char* moduleName);
|
|
void moduleJSRequireEndingEnd(const char* moduleName);
|
|
void moduleJSRequireEndingFail(const char* moduleName);
|
|
void syncMethodCallStart(const char* moduleName, const char* methodName);
|
|
void syncMethodCallArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallExecutionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallExecutionEnd(const char* moduleName, const char* methodName);
|
|
void syncMethodCallReturnConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallReturnConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallEnd(const char* moduleName, const char* methodName);
|
|
void syncMethodCallFail(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallStart(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void asyncMethodCallArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void asyncMethodCallDispatch(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallEnd(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallFail(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallBatchPreprocessStart();
|
|
void asyncMethodCallBatchPreprocessEnd(int batchSize);
|
|
void asyncMethodCallExecutionStart(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionEnd(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionFail(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
} // namespace facebook::react::TurboModulePerfLogger
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleUtils.h}:
|
|
namespace facebook::react {
|
|
struct Promise : public LongLivedObject {
|
|
Promise(jsi::Runtime& rt, jsi::Function resolve, jsi::Function reject);
|
|
void resolve(const jsi::Value& result);
|
|
void reject(const std::string& error);
|
|
jsi::Function resolve_;
|
|
jsi::Function reject_;
|
|
};
|
|
using PromiseSetupFunctionType =
|
|
std::function<void(jsi::Runtime& rt, std::shared_ptr<Promise>)>;
|
|
jsi::Value createPromiseAsJSIValue(
|
|
jsi::Runtime& rt,
|
|
PromiseSetupFunctionType&& func);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleWithJSIBindings.h}:
|
|
namespace facebook::react {
|
|
class TurboModuleWithJSIBindings {
|
|
public:
|
|
virtual ~TurboModuleWithJSIBindings() = default;
|
|
static void installJSIBindings(
|
|
const std::shared_ptr<TurboModule>& cxxModule,
|
|
jsi::Runtime& runtime);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaInteropTurboModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h}
|
|
|
|
namespace facebook::react {
|
|
class JSI_EXPORT JavaInteropTurboModule : public JavaTurboModule {
|
|
public:
|
|
struct MethodDescriptor {
|
|
std::string methodName;
|
|
std::string jniSignature;
|
|
TurboModuleMethodValueKind jsiReturnKind;
|
|
int jsArgCount;
|
|
};
|
|
JavaInteropTurboModule(
|
|
const JavaTurboModule::InitParams& params,
|
|
std::vector<MethodDescriptor> methodDescriptors);
|
|
std::vector<facebook::jsi::PropNameID> getPropertyNames(
|
|
facebook::jsi::Runtime& runtime) override;
|
|
|
|
protected:
|
|
jsi::Value create(jsi::Runtime& runtime, const jsi::PropNameID& propName)
|
|
override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/platform/android/ReactCommon/JavaTurboModule.h}:
|
|
namespace facebook::react {
|
|
struct JTurboModule : jni::JavaClass<JTurboModule> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/turbomodule/core/interfaces/TurboModule;";
|
|
};
|
|
struct JTurboModuleWithJSIBindings
|
|
: jni::JavaClass<JTurboModuleWithJSIBindings> {
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/turbomodule/core/interfaces/TurboModuleWithJSIBindings;";
|
|
};
|
|
class JSI_EXPORT JavaTurboModule : public TurboModule {
|
|
public:
|
|
struct InitParams {
|
|
std::string moduleName;
|
|
jni::alias_ref<jobject> instance;
|
|
std::shared_ptr<CallInvoker> jsInvoker;
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker;
|
|
};
|
|
JavaTurboModule(const InitParams& params);
|
|
virtual ~JavaTurboModule();
|
|
jsi::Value invokeJavaMethod(
|
|
jsi::Runtime& runtime,
|
|
TurboModuleMethodValueKind valueKind,
|
|
const std::string& methodName,
|
|
const std::string& methodSignature,
|
|
const jsi::Value* args,
|
|
size_t argCount,
|
|
jmethodID& cachedMethodID);
|
|
|
|
protected:
|
|
void configureEventEmitterCallback();
|
|
[[deprecated]] void setEventEmitterCallback(jni::alias_ref<jobject>) {
|
|
configureEventEmitterCallback();
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTInteropTurboModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h}
|
|
|
|
namespace facebook::react {
|
|
class JSI_EXPORT ObjCInteropTurboModule : public ObjCTurboModule {
|
|
public:
|
|
struct MethodDescriptor {
|
|
std::string methodName;
|
|
SEL selector;
|
|
size_t jsArgCount;
|
|
TurboModuleMethodValueKind jsReturnKind;
|
|
};
|
|
ObjCInteropTurboModule(const ObjCTurboModule::InitParams ¶ms);
|
|
std::vector<facebook::jsi::PropNameID> getPropertyNames(facebook::jsi::Runtime &runtime) override;
|
|
|
|
protected:
|
|
jsi::Value create(jsi::Runtime &runtime, const jsi::PropNameID &propName) override;
|
|
jsi::Value convertReturnIdToJSIValue(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
TurboModuleMethodValueKind returnType,
|
|
id result) override;
|
|
NSString *getArgumentTypeName(jsi::Runtime &runtime, NSString *methodName, int argIndex) override;
|
|
void setInvocationArg(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
const std::string &objCArgType,
|
|
const jsi::Value &arg,
|
|
size_t i,
|
|
NSInvocation *inv,
|
|
NSMutableArray *retainedObjectsForInvocation) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModule.h}:
|
|
namespace facebook::react {
|
|
using EventEmitterCallback = std::function<void(const std::string &, id)>;
|
|
namespace TurboModuleConvertUtils {
|
|
jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value);
|
|
id convertJSIValueToObjCObject(
|
|
jsi::Runtime &runtime,
|
|
const jsi::Value &value,
|
|
const std::shared_ptr<CallInvoker> &jsInvoker,
|
|
BOOL useNSNull = NO);
|
|
} // namespace TurboModuleConvertUtils
|
|
template <>
|
|
struct Bridging<id> {
|
|
static jsi::Value toJs(jsi::Runtime &rt, const id &value)
|
|
{
|
|
return TurboModuleConvertUtils::convertObjCObjectToJSIValue(rt, value);
|
|
}
|
|
};
|
|
class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
|
public:
|
|
struct InitParams {
|
|
std::string moduleName;
|
|
id<RCTBridgeModule> instance;
|
|
std::shared_ptr<CallInvoker> jsInvoker;
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker;
|
|
bool isSyncModule;
|
|
bool shouldVoidMethodsExecuteSync;
|
|
};
|
|
ObjCTurboModule(const InitParams ¶ms);
|
|
jsi::Value invokeObjCMethod(
|
|
jsi::Runtime &runtime,
|
|
TurboModuleMethodValueKind returnType,
|
|
const std::string &methodName,
|
|
SEL selector,
|
|
const jsi::Value *args,
|
|
size_t count);
|
|
id<RCTBridgeModule> instance_;
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker_;
|
|
|
|
protected:
|
|
void setMethodArgConversionSelector(NSString *methodName, size_t argIndex, NSString *fnName);
|
|
void setEventEmitterCallback(EventEmitterCallback eventEmitterCallback);
|
|
virtual jsi::Value convertReturnIdToJSIValue(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
TurboModuleMethodValueKind returnType,
|
|
id result);
|
|
virtual NSString *getArgumentTypeName(jsi::Runtime &runtime, NSString *methodName, int argIndex);
|
|
virtual void setInvocationArg(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
const std::string &objCArgType,
|
|
const jsi::Value &arg,
|
|
size_t i,
|
|
NSInvocation *inv,
|
|
NSMutableArray *retainedObjectsForInvocation);
|
|
};
|
|
} // namespace facebook::react
|
|
@interface EventEmitterCallbackWrapper : NSObject {
|
|
@public
|
|
facebook::react::EventEmitterCallback _eventEmitterCallback;
|
|
}
|
|
@end
|
|
@protocol RCTModuleProvider <NSObject>
|
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
(const facebook::react::ObjCTurboModule::InitParams &)params;
|
|
@end
|
|
@protocol RCTTurboModule <RCTModuleProvider>
|
|
@optional
|
|
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
|
|
@end
|
|
@interface RCTBridge (RCTTurboModule)
|
|
- (std::shared_ptr<facebook::react::CallInvoker>)jsCallInvoker;
|
|
- (std::shared_ptr<facebook::react::NativeMethodCallInvoker>)decorateNativeMethodCallInvoker:
|
|
(std::shared_ptr<facebook::react::NativeMethodCallInvoker>)nativeMethodCallInvoker;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleManager.h}:
|
|
namespace facebook::react {
|
|
using EventEmitterCallback = std::function<void(const std::string &, id)>;
|
|
namespace TurboModuleConvertUtils {
|
|
jsi::Value convertObjCObjectToJSIValue(jsi::Runtime &runtime, id value);
|
|
id convertJSIValueToObjCObject(
|
|
jsi::Runtime &runtime,
|
|
const jsi::Value &value,
|
|
const std::shared_ptr<CallInvoker> &jsInvoker,
|
|
BOOL useNSNull = NO);
|
|
} // namespace TurboModuleConvertUtils
|
|
template <>
|
|
struct Bridging<id> {
|
|
static jsi::Value toJs(jsi::Runtime &rt, const id &value)
|
|
{
|
|
return TurboModuleConvertUtils::convertObjCObjectToJSIValue(rt, value);
|
|
}
|
|
};
|
|
class JSI_EXPORT ObjCTurboModule : public TurboModule {
|
|
public:
|
|
struct InitParams {
|
|
std::string moduleName;
|
|
id<RCTBridgeModule> instance;
|
|
std::shared_ptr<CallInvoker> jsInvoker;
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker;
|
|
bool isSyncModule;
|
|
bool shouldVoidMethodsExecuteSync;
|
|
};
|
|
ObjCTurboModule(const InitParams ¶ms);
|
|
jsi::Value invokeObjCMethod(
|
|
jsi::Runtime &runtime,
|
|
TurboModuleMethodValueKind returnType,
|
|
const std::string &methodName,
|
|
SEL selector,
|
|
const jsi::Value *args,
|
|
size_t count);
|
|
id<RCTBridgeModule> instance_;
|
|
std::shared_ptr<NativeMethodCallInvoker> nativeMethodCallInvoker_;
|
|
|
|
protected:
|
|
void setMethodArgConversionSelector(NSString *methodName, size_t argIndex, NSString *fnName);
|
|
void setEventEmitterCallback(EventEmitterCallback eventEmitterCallback);
|
|
virtual jsi::Value convertReturnIdToJSIValue(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
TurboModuleMethodValueKind returnType,
|
|
id result);
|
|
virtual NSString *getArgumentTypeName(jsi::Runtime &runtime, NSString *methodName, int argIndex);
|
|
virtual void setInvocationArg(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
const std::string &objCArgType,
|
|
const jsi::Value &arg,
|
|
size_t i,
|
|
NSInvocation *inv,
|
|
NSMutableArray *retainedObjectsForInvocation);
|
|
|
|
private:
|
|
const bool isSyncModule_;
|
|
const bool shouldVoidMethodsExecuteSync_;
|
|
NSMutableDictionary<NSString *, NSMutableArray *> *methodArgConversionSelectors_;
|
|
NSDictionary<NSString *, NSArray<NSString *> *> *methodArgumentTypeNames_;
|
|
bool isMethodSync(TurboModuleMethodValueKind returnType);
|
|
BOOL hasMethodArgConversionSelector(NSString *methodName, size_t argIndex);
|
|
SEL getMethodArgConversionSelector(NSString *methodName, size_t argIndex);
|
|
NSInvocation *createMethodInvocation(
|
|
jsi::Runtime &runtime,
|
|
bool isSync,
|
|
const char *methodName,
|
|
SEL selector,
|
|
const jsi::Value *args,
|
|
size_t count,
|
|
NSMutableArray *retainedObjectsForInvocation);
|
|
id performMethodInvocation(
|
|
jsi::Runtime &runtime,
|
|
bool isSync,
|
|
const char *methodName,
|
|
NSInvocation *inv,
|
|
NSMutableArray *retainedObjectsForInvocation);
|
|
void performVoidMethodInvocation(
|
|
jsi::Runtime &runtime,
|
|
const char *methodName,
|
|
NSInvocation *inv,
|
|
NSMutableArray *retainedObjectsForInvocation);
|
|
using PromiseInvocationBlock = void (^)(RCTPromiseResolveBlock resolveWrapper, RCTPromiseRejectBlock rejectWrapper);
|
|
jsi::Value createPromise(jsi::Runtime &runtime, const std::string &methodName, PromiseInvocationBlock invoke);
|
|
};
|
|
} // namespace facebook::react
|
|
@interface EventEmitterCallbackWrapper : NSObject {
|
|
@public
|
|
facebook::react::EventEmitterCallback _eventEmitterCallback;
|
|
}
|
|
@end
|
|
@protocol RCTModuleProvider <NSObject>
|
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:
|
|
(const facebook::react::ObjCTurboModule::InitParams &)params;
|
|
@end
|
|
@protocol RCTTurboModule <RCTModuleProvider>
|
|
@optional
|
|
- (void)setEventEmitterCallback:(EventEmitterCallbackWrapper *)eventEmitterCallbackWrapper;
|
|
@end
|
|
@interface RCTBridge (RCTTurboModule)
|
|
- (std::shared_ptr<facebook::react::CallInvoker>)jsCallInvoker;
|
|
- (std::shared_ptr<facebook::react::NativeMethodCallInvoker>)decorateNativeMethodCallInvoker:
|
|
(std::shared_ptr<facebook::react::NativeMethodCallInvoker>)nativeMethodCallInvoker;
|
|
@end
|
|
@protocol RCTTurboModuleManagerDelegate <NSObject>
|
|
- (Class)getModuleClassFromName:(const char *)name;
|
|
- (id<RCTTurboModule>)getModuleInstanceFromClass:(Class)moduleClass;
|
|
@optional
|
|
- (id<RCTModuleProvider>)getModuleProvider:(const char *)name;
|
|
- (std::shared_ptr<facebook::react::TurboModule>)getTurboModule:(const std::string &)name
|
|
jsInvoker:
|
|
(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;
|
|
- (NSArray<id<RCTBridgeModule>> *)extraModulesForBridge:(RCTBridge *)bridge
|
|
__attribute((deprecated("Please make all native modules returned from this method TurboModule-compatible.")));
|
|
@end
|
|
@interface RCTTurboModuleManager : NSObject <RCTTurboModuleRegistry>
|
|
- (instancetype)initWithBridge:(RCTBridge *)bridge
|
|
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
|
|
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;
|
|
- (instancetype)initWithBridgeProxy:(RCTBridgeProxy *)bridgeProxy
|
|
bridgeModuleDecorator:(RCTBridgeModuleDecorator *)bridgeModuleDecorator
|
|
delegate:(id<RCTTurboModuleManagerDelegate>)delegate
|
|
jsInvoker:(std::shared_ptr<facebook::react::CallInvoker>)jsInvoker;
|
|
- (void)installJSBindings:(facebook::jsi::Runtime &)runtime;
|
|
- (void)invalidate;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/platform/ios/ReactCommon/RCTTurboModuleWithJSIBindings.h}:
|
|
@protocol RCTTurboModuleWithJSIBindings <NSObject>
|
|
@optional
|
|
- (void)installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime
|
|
callInvoker:(const std::shared_ptr<facebook::react::CallInvoker> &)callinvoker;
|
|
- (void)installJSIBindingsWithRuntime:(facebook::jsi::Runtime &)runtime
|
|
__attribute__((deprecated("Use 'installJSIBindingsWithRuntime:callInvoker:' instead")));
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/core/tests/TurboModuleTestFixture.h}:
|
|
namespace facebook::react {
|
|
template <typename T, typename... Args>
|
|
class TurboModuleTestFixture : public ::testing::Test {
|
|
public:
|
|
explicit TurboModuleTestFixture(Args... args)
|
|
: runtime_(facebook::hermes::makeHermesRuntime()),
|
|
jsInvoker_(std::make_shared<TestCallInvoker>(runtime_)),
|
|
module_(std::make_shared<T>(jsInvoker_, std::forward<Args>(args)...)) {}
|
|
|
|
protected:
|
|
std::shared_ptr<jsi::Runtime> runtime_{};
|
|
std::shared_ptr<TestCallInvoker> jsInvoker_{};
|
|
std::shared_ptr<T> module_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/cputime/CPUTime.h}:
|
|
namespace facebook::react {
|
|
inline double getCPUTimeNanos() {
|
|
auto now = std::chrono::steady_clock::now();
|
|
return static_cast<double>(
|
|
std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
now.time_since_epoch())
|
|
.count());
|
|
}
|
|
inline bool hasAccurateCPUTimeNanosForBenchmarks() {
|
|
return false;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/cputime/NativeCPUTime.h}:
|
|
namespace facebook::react {
|
|
class NativeCPUTime : public NativeCPUTimeCxxSpec<NativeCPUTime> {
|
|
public:
|
|
explicit NativeCPUTime(std::shared_ptr<CallInvoker> jsInvoker);
|
|
double getCPUTimeNanos(jsi::Runtime& runtime);
|
|
bool hasAccurateCPUTimeNanosForBenchmarks(jsi::Runtime& runtime);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/defaults/DefaultTurboModules.h}:
|
|
namespace facebook::react {
|
|
struct DefaultTurboModules {
|
|
static std::shared_ptr<TurboModule> getTurboModule(
|
|
const std::string& name,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/devtoolsruntimesettings/DevToolsRuntimeSettingsModule.h}:
|
|
namespace facebook::react {
|
|
class DevToolsRuntimeSettingsModule
|
|
: public NativeReactDevToolsRuntimeSettingsModuleCxxSpec<
|
|
DevToolsRuntimeSettingsModule> {
|
|
public:
|
|
DevToolsRuntimeSettingsModule(std::shared_ptr<CallInvoker> jsInvoker);
|
|
void setReloadAndProfileConfig(
|
|
jsi::Runtime& rt,
|
|
NativePartialReloadAndProfileConfig config);
|
|
NativeReloadAndProfileConfig getReloadAndProfileConfig(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/dom/NativeDOM.h}:
|
|
namespace facebook::react {
|
|
using MeasureOnSuccessCallback =
|
|
SyncCallback<void(double, double, double, double, double, double)>;
|
|
using MeasureInWindowOnSuccessCallback =
|
|
SyncCallback<void(double, double, double, double)>;
|
|
using MeasureLayoutOnSuccessCallback =
|
|
SyncCallback<void(double, double, double, double)>;
|
|
class NativeDOM : public NativeDOMCxxSpec<NativeDOM> {
|
|
public:
|
|
NativeDOM(std::shared_ptr<CallInvoker> jsInvoker);
|
|
double compareDocumentPosition(
|
|
jsi::Runtime& rt,
|
|
jsi::Value nativeNodeReference,
|
|
jsi::Value otherNativeNodeReference);
|
|
std::vector<jsi::Value> getChildNodes(
|
|
jsi::Runtime& rt,
|
|
jsi::Value nativeNodeReference);
|
|
jsi::Value getParentNode(jsi::Runtime& rt, jsi::Value nativeNodeReference);
|
|
bool isConnected(jsi::Runtime& rt, jsi::Value nativeNodeReference);
|
|
std::tuple<int, int, int, int> getBorderWidth(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
std::tuple<double, double, double, double> getBoundingClientRect(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
bool includeTransform);
|
|
std::tuple<int, int> getInnerSize(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
std::tuple<double, double> getScrollPosition(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
std::tuple<int, int> getScrollSize(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
std::string getTagName(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
std::string getTextContent(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
bool hasPointerCapture(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
double pointerId);
|
|
void releasePointerCapture(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
double pointerId);
|
|
void setPointerCapture(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
double pointerId);
|
|
std::tuple<jsi::Value, double, double> getOffset(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode);
|
|
jsi::Value linkRootNode(
|
|
jsi::Runtime& rt,
|
|
SurfaceId surfaceId,
|
|
jsi::Value instanceHandle);
|
|
void measure(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
const MeasureOnSuccessCallback& callback);
|
|
void measureInWindow(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
const MeasureInWindowOnSuccessCallback& callback);
|
|
void measureLayout(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
std::shared_ptr<const ShadowNode> relativeToShadowNode,
|
|
jsi::Function onFail,
|
|
const MeasureLayoutOnSuccessCallback& onSuccess);
|
|
void setNativeProps(
|
|
jsi::Runtime& rt,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
jsi::Value updatePayload);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/fantomtestspecificmethods/NativeFantomTestSpecificMethods.h}:
|
|
namespace facebook::react {
|
|
class NativeFantomTestSpecificMethods
|
|
: public NativeFantomTestSpecificMethodsCxxSpec<
|
|
NativeFantomTestSpecificMethods> {
|
|
public:
|
|
explicit NativeFantomTestSpecificMethods(
|
|
std::shared_ptr<CallInvoker> jsInvoker);
|
|
void registerForcedCloneCommitHook(jsi::Runtime& runtime);
|
|
void takeFunctionAndNoop(jsi::Runtime& runtime, jsi::Function callback);
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/fantomtestspecificmethods/internal/FantomForcedCloneCommitHook.h}:
|
|
namespace facebook::react {
|
|
struct FantomForcedCloneCommitHook : public UIManagerCommitHook {
|
|
void commitHookWasRegistered(const UIManager&) noexcept override;
|
|
void commitHookWasUnregistered(const UIManager&) noexcept override;
|
|
RootShadowNode::Unshared shadowTreeWillCommit(
|
|
const ShadowTree& shadowTree,
|
|
const std::shared_ptr<const RootShadowNode>& oldRootShadowNode,
|
|
const RootShadowNode::Unshared& newRootShadowNode) noexcept override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/featureflags/NativeReactNativeFeatureFlags.h}:
|
|
namespace facebook::react {
|
|
class NativeReactNativeFeatureFlags
|
|
: public NativeReactNativeFeatureFlagsCxxSpecJSI {
|
|
public:
|
|
NativeReactNativeFeatureFlags(std::shared_ptr<CallInvoker> jsInvoker);
|
|
static constexpr std::string_view kModuleName =
|
|
"NativeReactNativeFeatureFlagsCxx";
|
|
bool commonTestFlag(jsi::Runtime& runtime);
|
|
bool commonTestFlagWithoutNativeImplementation(jsi::Runtime& runtime);
|
|
bool cxxNativeAnimatedEnabled(jsi::Runtime& runtime);
|
|
bool cxxNativeAnimatedRemoveJsSync(jsi::Runtime& runtime);
|
|
bool disableMountItemReorderingAndroid(jsi::Runtime& runtime);
|
|
bool disableOldAndroidAttachmentMetricsWorkarounds(jsi::Runtime& runtime);
|
|
bool disableTextLayoutManagerCacheAndroid(jsi::Runtime& runtime);
|
|
bool enableAccessibilityOrder(jsi::Runtime& runtime);
|
|
bool enableAccumulatedUpdatesInRawPropsAndroid(jsi::Runtime& runtime);
|
|
bool enableAndroidTextMeasurementOptimizations(jsi::Runtime& runtime);
|
|
bool enableBridgelessArchitecture(jsi::Runtime& runtime);
|
|
bool enableCppPropsIteratorSetter(jsi::Runtime& runtime);
|
|
bool enableCustomFocusSearchOnClippedElementsAndroid(jsi::Runtime& runtime);
|
|
bool enableDestroyShadowTreeRevisionAsync(jsi::Runtime& runtime);
|
|
bool enableDoubleMeasurementFixAndroid(jsi::Runtime& runtime);
|
|
bool enableEagerMainQueueModulesOnIOS(jsi::Runtime& runtime);
|
|
bool enableEagerRootViewAttachment(jsi::Runtime& runtime);
|
|
bool enableFabricLogs(jsi::Runtime& runtime);
|
|
bool enableFabricRenderer(jsi::Runtime& runtime);
|
|
bool enableFixForParentTagDuringReparenting(jsi::Runtime& runtime);
|
|
bool enableFontScaleChangesUpdatingLayout(jsi::Runtime& runtime);
|
|
bool enableIOSTextBaselineOffsetPerLine(jsi::Runtime& runtime);
|
|
bool enableIOSViewClipToPaddingBox(jsi::Runtime& runtime);
|
|
bool enableImagePrefetchingAndroid(jsi::Runtime& runtime);
|
|
bool enableImmediateUpdateModeForContentOffsetChanges(jsi::Runtime& runtime);
|
|
bool enableInteropViewManagerClassLookUpOptimizationIOS(
|
|
jsi::Runtime& runtime);
|
|
bool enableLayoutAnimationsOnAndroid(jsi::Runtime& runtime);
|
|
bool enableLayoutAnimationsOnIOS(jsi::Runtime& runtime);
|
|
bool enableMainQueueCoordinatorOnIOS(jsi::Runtime& runtime);
|
|
bool enableModuleArgumentNSNullConversionIOS(jsi::Runtime& runtime);
|
|
bool enableNativeCSSParsing(jsi::Runtime& runtime);
|
|
bool enableNetworkEventReporting(jsi::Runtime& runtime);
|
|
bool enableNewBackgroundAndBorderDrawables(jsi::Runtime& runtime);
|
|
bool enablePreparedTextLayout(jsi::Runtime& runtime);
|
|
bool enablePropsUpdateReconciliationAndroid(jsi::Runtime& runtime);
|
|
bool enableResourceTimingAPI(jsi::Runtime& runtime);
|
|
bool enableViewCulling(jsi::Runtime& runtime);
|
|
bool enableViewRecycling(jsi::Runtime& runtime);
|
|
bool enableViewRecyclingForText(jsi::Runtime& runtime);
|
|
bool enableViewRecyclingForView(jsi::Runtime& runtime);
|
|
bool enableVirtualViewDebugFeatures(jsi::Runtime& runtime);
|
|
bool enableVirtualViewRenderState(jsi::Runtime& runtime);
|
|
bool enableVirtualViewWindowFocusDetection(jsi::Runtime& runtime);
|
|
bool fixMappingOfEventPrioritiesBetweenFabricAndReact(jsi::Runtime& runtime);
|
|
bool fuseboxEnabledRelease(jsi::Runtime& runtime);
|
|
bool fuseboxNetworkInspectionEnabled(jsi::Runtime& runtime);
|
|
bool hideOffscreenVirtualViewsOnIOS(jsi::Runtime& runtime);
|
|
double preparedTextCacheSize(jsi::Runtime& runtime);
|
|
bool preventShadowTreeCommitExhaustionWithLocking(jsi::Runtime& runtime);
|
|
bool releaseImageDataWhenConsumed(jsi::Runtime& runtime);
|
|
bool skipActivityIdentityAssertionOnHostPause(jsi::Runtime& runtime);
|
|
bool traceTurboModulePromiseRejectionsOnAndroid(jsi::Runtime& runtime);
|
|
bool updateRuntimeShadowNodeReferencesOnCommit(jsi::Runtime& runtime);
|
|
bool useAlwaysAvailableJSErrorHandling(jsi::Runtime& runtime);
|
|
bool useFabricInterop(jsi::Runtime& runtime);
|
|
bool useNativeEqualsInNativeReadableArrayAndroid(jsi::Runtime& runtime);
|
|
bool useNativeTransformHelperAndroid(jsi::Runtime& runtime);
|
|
bool useNativeViewConfigsInBridgelessMode(jsi::Runtime& runtime);
|
|
bool useOptimizedEventBatchingOnAndroid(jsi::Runtime& runtime);
|
|
bool useRawPropsJsiValue(jsi::Runtime& runtime);
|
|
bool useShadowNodeStateOnClone(jsi::Runtime& runtime);
|
|
bool useTurboModuleInterop(jsi::Runtime& runtime);
|
|
bool useTurboModules(jsi::Runtime& runtime);
|
|
double virtualViewPrerenderRatio(jsi::Runtime& runtime);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/idlecallbacks/NativeIdleCallbacks.h}:
|
|
namespace facebook::react {
|
|
using CallbackHandle = jsi::Object;
|
|
using NativeRequestIdleCallbackOptions =
|
|
NativeIdleCallbacksRequestIdleCallbackOptions<
|
|
std::optional<HighResDuration>>;
|
|
template <>
|
|
struct Bridging<NativeRequestIdleCallbackOptions>
|
|
: NativeIdleCallbacksRequestIdleCallbackOptionsBridging<
|
|
NativeRequestIdleCallbackOptions> {};
|
|
class NativeIdleCallbacks
|
|
: public NativeIdleCallbacksCxxSpec<NativeIdleCallbacks> {
|
|
public:
|
|
NativeIdleCallbacks(std::shared_ptr<CallInvoker> jsInvoker);
|
|
CallbackHandle requestIdleCallback(
|
|
jsi::Runtime& runtime,
|
|
SyncCallback<void(jsi::Object)>&& callback,
|
|
std::optional<NativeRequestIdleCallbackOptions> options);
|
|
void cancelIdleCallback(jsi::Runtime& runtime, jsi::Object handle);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/intersectionobserver/NativeIntersectionObserver.h}:
|
|
namespace facebook::react {
|
|
using NativeIntersectionObserverIntersectionObserverId = int32_t;
|
|
using RectAsTuple = std::tuple<Float, Float, Float, Float>;
|
|
using NativeIntersectionObserverObserveOptions =
|
|
NativeIntersectionObserverNativeIntersectionObserverObserveOptions<
|
|
NativeIntersectionObserverIntersectionObserverId,
|
|
std::optional<std::shared_ptr<const ShadowNode>>,
|
|
std::shared_ptr<const ShadowNode>,
|
|
std::vector<Float>,
|
|
std::optional<std::vector<Float>>>;
|
|
template <>
|
|
struct Bridging<NativeIntersectionObserverObserveOptions>
|
|
: NativeIntersectionObserverNativeIntersectionObserverObserveOptionsBridging<
|
|
NativeIntersectionObserverObserveOptions> {};
|
|
using NativeIntersectionObserverEntry =
|
|
NativeIntersectionObserverNativeIntersectionObserverEntry<
|
|
NativeIntersectionObserverIntersectionObserverId,
|
|
jsi::Value,
|
|
RectAsTuple,
|
|
RectAsTuple,
|
|
RectAsTuple,
|
|
bool,
|
|
HighResTimeStamp>;
|
|
template <>
|
|
struct Bridging<NativeIntersectionObserverEntry>
|
|
: NativeIntersectionObserverNativeIntersectionObserverEntryBridging<
|
|
NativeIntersectionObserverEntry> {};
|
|
class NativeIntersectionObserver
|
|
: public NativeIntersectionObserverCxxSpec<NativeIntersectionObserver> {
|
|
public:
|
|
NativeIntersectionObserver(std::shared_ptr<CallInvoker> jsInvoker);
|
|
jsi::Object observeV2(
|
|
jsi::Runtime& runtime,
|
|
NativeIntersectionObserverObserveOptions options);
|
|
void unobserveV2(
|
|
jsi::Runtime& runtime,
|
|
IntersectionObserverObserverId intersectionObserverId,
|
|
jsi::Object targetToken);
|
|
void connect(
|
|
jsi::Runtime& runtime,
|
|
AsyncCallback<> notifyIntersectionObserversCallback);
|
|
void disconnect(jsi::Runtime& runtime);
|
|
std::vector<NativeIntersectionObserverEntry> takeRecords(
|
|
jsi::Runtime& runtime);
|
|
};
|
|
static UIManager& getUIManagerFromRuntime(jsi::Runtime& runtime);
|
|
static NativeIntersectionObserverEntry convertToNativeModuleEntry(
|
|
const IntersectionObserverEntry& entry,
|
|
jsi::Runtime& runtime);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/microtasks/NativeMicrotasks.h}:
|
|
namespace facebook::react {
|
|
class NativeMicrotasks : public NativeMicrotasksCxxSpec<NativeMicrotasks> {
|
|
public:
|
|
NativeMicrotasks(std::shared_ptr<CallInvoker> jsInvoker);
|
|
void queueMicrotask(jsi::Runtime& runtime, jsi::Function callback);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/mutationobserver/NativeMutationObserver.h}:
|
|
namespace facebook::react {
|
|
using NativeMutationObserverObserveOptions =
|
|
NativeMutationObserverNativeMutationObserverObserveOptions<
|
|
MutationObserverId,
|
|
std::shared_ptr<const ShadowNode>,
|
|
bool>;
|
|
template <>
|
|
struct Bridging<NativeMutationObserverObserveOptions>
|
|
: NativeMutationObserverNativeMutationObserverObserveOptionsBridging<
|
|
NativeMutationObserverObserveOptions> {};
|
|
using NativeMutationRecord = NativeMutationObserverNativeMutationRecord<
|
|
MutationObserverId,
|
|
jsi::Value,
|
|
std::vector<jsi::Value>,
|
|
std::vector<jsi::Value>>;
|
|
template <>
|
|
struct Bridging<NativeMutationRecord>
|
|
: NativeMutationObserverNativeMutationRecordBridging<NativeMutationRecord> {
|
|
};
|
|
class NativeMutationObserver
|
|
: public NativeMutationObserverCxxSpec<NativeMutationObserver> {
|
|
public:
|
|
NativeMutationObserver(std::shared_ptr<CallInvoker> jsInvoker);
|
|
void observe(
|
|
jsi::Runtime& runtime,
|
|
NativeMutationObserverObserveOptions options);
|
|
void unobserveAll(
|
|
jsi::Runtime& runtime,
|
|
MutationObserverId mutationObserverId);
|
|
void connect(
|
|
jsi::Runtime& runtime,
|
|
jsi::Function notifyMutationObservers,
|
|
SyncCallback<jsi::Value(jsi::Value)> getPublicInstanceFromInstanceHandle);
|
|
void disconnect(jsi::Runtime& runtime);
|
|
std::vector<NativeMutationRecord> takeRecords(jsi::Runtime& runtime);
|
|
};
|
|
std::vector<NativeMutationRecord> pendingRecords_;
|
|
jsi::Runtime* runtime_{};
|
|
bool notifiedMutationObservers_{};
|
|
std::optional<jsi::Function> notifyMutationObservers_;
|
|
std::optional<SyncCallback<jsi::Value(jsi::Value)>>
|
|
getPublicInstanceFromInstanceHandle_;
|
|
void onMutations(std::vector<MutationRecord>& records);
|
|
void notifyMutationObserversIfNecessary();
|
|
jsi::Value getPublicInstanceFromShadowNode(
|
|
const ShadowNode& shadowNode) const;
|
|
std::vector<jsi::Value> getPublicInstancesFromShadowNodes(
|
|
const std::vector<std::shared_ptr<const ShadowNode>>& shadowNodes) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleJSIBindings.h}:
|
|
namespace facebook::react {
|
|
class SampleTurboModuleJSIBindings
|
|
: public jni::JavaClass<SampleTurboModuleJSIBindings> {
|
|
public:
|
|
static constexpr const char* kJavaDescriptor =
|
|
"Lcom/facebook/fbreact/specs/SampleTurboModule;";
|
|
SampleTurboModuleJSIBindings() = default;
|
|
static void registerNatives();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/android/ReactCommon/SampleTurboModuleSpec.h}:
|
|
namespace facebook::react {
|
|
class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public JavaTurboModule {
|
|
public:
|
|
NativeSampleTurboModuleSpecJSI(const JavaTurboModule::InitParams& params);
|
|
};
|
|
JSI_EXPORT
|
|
std::shared_ptr<TurboModule> SampleTurboModuleSpec_ModuleProvider(
|
|
const std::string& moduleName,
|
|
const JavaTurboModule::InitParams& params);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTNativeSampleTurboModuleSpec.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleLegacyModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTSampleLegacyModule.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h}
|
|
@interface RCTSampleTurboModule : NativeSampleTurboModuleSpecBase <NativeSampleTurboModuleSpec>
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModulePlugin.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTSampleTurboModulePlugin.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTNativeSampleTurboModuleSpec.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTSampleLegacyModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleLegacyModule.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTSampleTurboModule.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTNativeSampleTurboModuleSpec.h}
|
|
@interface RCTSampleTurboModule : NativeSampleTurboModuleSpecBase <NativeSampleTurboModuleSpec>
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/samples/platform/macos/ReactCommon/RCTSampleTurboModulePlugin.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/nativemodule/samples/platform/ios/ReactCommon/RCTSampleTurboModulePlugin.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/nativemodule/webperformance/NativePerformance.h}:
|
|
namespace facebook::react {
|
|
using NativePerformancePerformanceObserverCallback = AsyncCallback<>;
|
|
using NativePerformancePerformanceObserverObserveOptions =
|
|
NativePerformancePerformanceObserverInit<
|
|
std::optional<std::vector<int>>,
|
|
std::optional<int>,
|
|
std::optional<bool>,
|
|
std::optional<HighResDuration>>;
|
|
template <>
|
|
struct Bridging<PerformanceEntryType> {
|
|
static PerformanceEntryType fromJs(jsi::Runtime&, const jsi::Value& value) {
|
|
return static_cast<PerformanceEntryType>(value.asNumber());
|
|
}
|
|
static int toJs(jsi::Runtime&, const PerformanceEntryType& value) {
|
|
return static_cast<int>(value);
|
|
}
|
|
};
|
|
struct NativePerformanceEntry {
|
|
std::string name;
|
|
PerformanceEntryType entryType;
|
|
HighResTimeStamp startTime;
|
|
HighResDuration duration;
|
|
std::optional<HighResTimeStamp> processingStart;
|
|
std::optional<HighResTimeStamp> processingEnd;
|
|
std::optional<PerformanceEntryInteractionId> interactionId;
|
|
std::optional<HighResTimeStamp> fetchStart;
|
|
std::optional<HighResTimeStamp> requestStart;
|
|
std::optional<HighResTimeStamp> connectStart;
|
|
std::optional<HighResTimeStamp> connectEnd;
|
|
std::optional<HighResTimeStamp> responseStart;
|
|
std::optional<HighResTimeStamp> responseEnd;
|
|
std::optional<int> responseStatus;
|
|
};
|
|
template <>
|
|
struct Bridging<NativePerformanceEntry>
|
|
: NativePerformanceRawPerformanceEntryBridging<NativePerformanceEntry> {};
|
|
template <>
|
|
struct Bridging<NativePerformancePerformanceObserverObserveOptions>
|
|
: NativePerformancePerformanceObserverInitBridging<
|
|
NativePerformancePerformanceObserverObserveOptions> {};
|
|
class NativePerformance : public NativePerformanceCxxSpec<NativePerformance> {
|
|
public:
|
|
NativePerformance(std::shared_ptr<CallInvoker> jsInvoker);
|
|
HighResTimeStamp now(jsi::Runtime& rt);
|
|
void reportMark(
|
|
jsi::Runtime& rt,
|
|
std::string name,
|
|
HighResTimeStamp time,
|
|
jsi::Value entry);
|
|
void reportMeasure(
|
|
jsi::Runtime& rt,
|
|
std::string name,
|
|
HighResTimeStamp startTime,
|
|
HighResDuration duration,
|
|
jsi::Value entry);
|
|
std::optional<double> getMarkTime(jsi::Runtime& rt, std::string name);
|
|
void clearMarks(
|
|
jsi::Runtime& rt,
|
|
std::optional<std::string> entryName = std::nullopt);
|
|
void clearMeasures(
|
|
jsi::Runtime& rt,
|
|
std::optional<std::string> entryName = std::nullopt);
|
|
std::vector<NativePerformanceEntry> getEntries(jsi::Runtime& rt);
|
|
std::vector<NativePerformanceEntry> getEntriesByType(
|
|
jsi::Runtime& rt,
|
|
PerformanceEntryType entryType);
|
|
std::vector<NativePerformanceEntry> getEntriesByName(
|
|
jsi::Runtime& rt,
|
|
std::string entryName,
|
|
std::optional<PerformanceEntryType> entryType = std::nullopt);
|
|
jsi::Object createObserver(
|
|
jsi::Runtime& rt,
|
|
NativePerformancePerformanceObserverCallback callback);
|
|
double getDroppedEntriesCount(jsi::Runtime& rt, jsi::Object observerObj);
|
|
void observe(
|
|
jsi::Runtime& rt,
|
|
jsi::Object observer,
|
|
NativePerformancePerformanceObserverObserveOptions options);
|
|
void disconnect(jsi::Runtime& rt, jsi::Object observer);
|
|
std::vector<NativePerformanceEntry>
|
|
takeRecords(jsi::Runtime& rt, jsi::Object observerObj, bool sort);
|
|
std::vector<PerformanceEntryType> getSupportedPerformanceEntryTypes(
|
|
jsi::Runtime& rt);
|
|
std::vector<std::pair<std::string, uint32_t>> getEventCounts(
|
|
jsi::Runtime& rt);
|
|
std::unordered_map<std::string, double> getSimpleMemoryInfo(jsi::Runtime& rt);
|
|
std::unordered_map<std::string, double> getReactNativeStartupTiming(
|
|
jsi::Runtime& rt);
|
|
void clearEventCountsForTesting(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/CircularBuffer.h}:
|
|
namespace facebook::react {
|
|
template <class T>
|
|
class CircularBuffer {
|
|
public:
|
|
explicit CircularBuffer(size_t maxSize) : maxSize_(maxSize) {
|
|
entries_.reserve(maxSize_);
|
|
}
|
|
bool add(const T& el) {
|
|
if (entries_.size() < maxSize_) {
|
|
entries_.emplace_back(el);
|
|
return false;
|
|
} else {
|
|
entries_[position_] = el;
|
|
position_ = (position_ + 1) % entries_.size();
|
|
return true;
|
|
}
|
|
}
|
|
T& operator[](size_t idx) {
|
|
return entries_[(position_ + idx) % entries_.size()];
|
|
}
|
|
size_t size() const {
|
|
return entries_.size();
|
|
}
|
|
void clear() {
|
|
entries_.clear();
|
|
position_ = 0;
|
|
}
|
|
void clear(std::function<bool(const T&)> predicate) {
|
|
std::vector<T> entries;
|
|
entries.reserve(maxSize_);
|
|
for (size_t i = 0; i < entries_.size(); i++) {
|
|
T& el = entries_[(i + position_) % entries_.size()];
|
|
if (predicate(el)) {
|
|
continue;
|
|
}
|
|
entries.push_back(std::move(el));
|
|
}
|
|
position_ = 0;
|
|
entries.swap(entries_);
|
|
}
|
|
std::vector<T> getEntries() const {
|
|
std::vector<T> res;
|
|
getEntries(res);
|
|
return res;
|
|
}
|
|
std::vector<T> getEntries(std::function<bool(const T&)> predicate) const {
|
|
std::vector<T> res;
|
|
getEntries(res, predicate);
|
|
return res;
|
|
}
|
|
void getEntries(std::vector<T>& res) const {
|
|
const size_t oldSize = res.size();
|
|
res.resize(oldSize + entries_.size());
|
|
std::copy(
|
|
entries_.begin() + position_, entries_.end(), res.begin() + oldSize);
|
|
std::copy(
|
|
entries_.begin(),
|
|
entries_.begin() + position_,
|
|
res.begin() + oldSize + entries_.size() - position_);
|
|
}
|
|
void getEntries(std::vector<T>& res, std::function<bool(const T&)> predicate)
|
|
const {
|
|
for (size_t i = 0; i < entries_.size(); i++) {
|
|
const T& el = entries_[(i + position_) % entries_.size()];
|
|
if (predicate(el)) {
|
|
res.push_back(el);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}:
|
|
namespace facebook::react {
|
|
using PerformanceEntryInteractionId = uint32_t;
|
|
enum class PerformanceEntryType {
|
|
MARK = 1,
|
|
MEASURE = 2,
|
|
EVENT = 3,
|
|
LONGTASK = 4,
|
|
RESOURCE = 5,
|
|
_NEXT = 6,
|
|
};
|
|
struct AbstractPerformanceEntry {
|
|
std::string name;
|
|
HighResTimeStamp startTime;
|
|
HighResDuration duration = HighResDuration::zero();
|
|
};
|
|
struct PerformanceMark : AbstractPerformanceEntry {
|
|
static constexpr PerformanceEntryType entryType = PerformanceEntryType::MARK;
|
|
};
|
|
struct PerformanceMeasure : AbstractPerformanceEntry {
|
|
static constexpr PerformanceEntryType entryType =
|
|
PerformanceEntryType::MEASURE;
|
|
};
|
|
struct PerformanceEventTiming : AbstractPerformanceEntry {
|
|
static constexpr PerformanceEntryType entryType = PerformanceEntryType::EVENT;
|
|
HighResTimeStamp processingStart;
|
|
HighResTimeStamp processingEnd;
|
|
PerformanceEntryInteractionId interactionId;
|
|
};
|
|
struct PerformanceLongTaskTiming : AbstractPerformanceEntry {
|
|
static constexpr PerformanceEntryType entryType =
|
|
PerformanceEntryType::LONGTASK;
|
|
};
|
|
struct PerformanceResourceTiming : AbstractPerformanceEntry {
|
|
static constexpr PerformanceEntryType entryType =
|
|
PerformanceEntryType::RESOURCE;
|
|
HighResTimeStamp fetchStart;
|
|
HighResTimeStamp requestStart;
|
|
std::optional<HighResTimeStamp> connectStart;
|
|
std::optional<HighResTimeStamp> connectEnd;
|
|
std::optional<HighResTimeStamp> responseStart;
|
|
std::optional<HighResTimeStamp> responseEnd;
|
|
std::optional<int> responseStatus;
|
|
};
|
|
using PerformanceEntry = std::variant<
|
|
PerformanceMark,
|
|
PerformanceMeasure,
|
|
PerformanceEventTiming,
|
|
PerformanceLongTaskTiming,
|
|
PerformanceResourceTiming>;
|
|
struct PerformanceEntrySorter {
|
|
bool operator()(const PerformanceEntry& lhs, const PerformanceEntry& rhs) {
|
|
return std::visit(
|
|
[](const auto& left, const auto& right) {
|
|
if (left.startTime != right.startTime) {
|
|
return left.startTime < right.startTime;
|
|
}
|
|
return left.duration < right.duration;
|
|
},
|
|
lhs,
|
|
rhs);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryBuffer.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}
|
|
|
|
namespace facebook::react {
|
|
constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
|
class PerformanceEntryBuffer {
|
|
public:
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
size_t droppedEntriesCount{0};
|
|
explicit PerformanceEntryBuffer() = default;
|
|
virtual ~PerformanceEntryBuffer() = default;
|
|
virtual void add(const PerformanceEntry& entry) = 0;
|
|
virtual void getEntries(std::vector<PerformanceEntry>& target) const = 0;
|
|
virtual void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const = 0;
|
|
virtual void clear() = 0;
|
|
virtual void clear(const std::string& name) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryCircularBuffer.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/CircularBuffer.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}
|
|
|
|
namespace facebook::react {
|
|
constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
|
class PerformanceEntryBuffer {
|
|
public:
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
size_t droppedEntriesCount{0};
|
|
explicit PerformanceEntryBuffer() = default;
|
|
virtual ~PerformanceEntryBuffer() = default;
|
|
virtual void add(const PerformanceEntry& entry) = 0;
|
|
virtual void getEntries(std::vector<PerformanceEntry>& target) const = 0;
|
|
virtual void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const = 0;
|
|
virtual void clear() = 0;
|
|
virtual void clear(const std::string& name) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class PerformanceEntryCircularBuffer : public PerformanceEntryBuffer {
|
|
public:
|
|
explicit PerformanceEntryCircularBuffer(size_t size) : buffer_(size) {}
|
|
~PerformanceEntryCircularBuffer() override = default;
|
|
void add(const PerformanceEntry& entry) override;
|
|
void getEntries(std::vector<PerformanceEntry>& target) const override;
|
|
void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const override;
|
|
void clear() override;
|
|
void clear(const std::string& name) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryKeyedBuffer.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}
|
|
|
|
namespace facebook::react {
|
|
constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
|
class PerformanceEntryBuffer {
|
|
public:
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
size_t droppedEntriesCount{0};
|
|
explicit PerformanceEntryBuffer() = default;
|
|
virtual ~PerformanceEntryBuffer() = default;
|
|
virtual void add(const PerformanceEntry& entry) = 0;
|
|
virtual void getEntries(std::vector<PerformanceEntry>& target) const = 0;
|
|
virtual void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const = 0;
|
|
virtual void clear() = 0;
|
|
virtual void clear(const std::string& name) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class PerformanceEntryKeyedBuffer : public PerformanceEntryBuffer {
|
|
public:
|
|
PerformanceEntryKeyedBuffer() = default;
|
|
void add(const PerformanceEntry& entry) override;
|
|
void getEntries(std::vector<PerformanceEntry>& target) const override;
|
|
void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const override;
|
|
void clear() override;
|
|
void clear(const std::string& name) override;
|
|
std::optional<PerformanceEntry> find(const std::string& name) const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntryReporter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/CircularBuffer.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}
|
|
|
|
namespace facebook::react {
|
|
constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
|
class PerformanceEntryBuffer {
|
|
public:
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
size_t droppedEntriesCount{0};
|
|
explicit PerformanceEntryBuffer() = default;
|
|
virtual ~PerformanceEntryBuffer() = default;
|
|
virtual void add(const PerformanceEntry& entry) = 0;
|
|
virtual void getEntries(std::vector<PerformanceEntry>& target) const = 0;
|
|
virtual void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const = 0;
|
|
virtual void clear() = 0;
|
|
virtual void clear(const std::string& name) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class PerformanceEntryCircularBuffer : public PerformanceEntryBuffer {
|
|
public:
|
|
explicit PerformanceEntryCircularBuffer(size_t size) : buffer_(size) {}
|
|
~PerformanceEntryCircularBuffer() override = default;
|
|
void add(const PerformanceEntry& entry) override;
|
|
void getEntries(std::vector<PerformanceEntry>& target) const override;
|
|
void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const override;
|
|
void clear() override;
|
|
void clear(const std::string& name) override;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class PerformanceEntryKeyedBuffer : public PerformanceEntryBuffer {
|
|
public:
|
|
PerformanceEntryKeyedBuffer() = default;
|
|
void add(const PerformanceEntry& entry) override;
|
|
void getEntries(std::vector<PerformanceEntry>& target) const override;
|
|
void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const override;
|
|
void clear() override;
|
|
void clear(const std::string& name) override;
|
|
std::optional<PerformanceEntry> find(const std::string& name) const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class PerformanceObserverRegistry {
|
|
public:
|
|
PerformanceObserverRegistry() = default;
|
|
void addObserver(std::shared_ptr<PerformanceObserver> observer);
|
|
void removeObserver(std::shared_ptr<PerformanceObserver> observer);
|
|
void queuePerformanceEntry(const PerformanceEntry& entry);
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
constexpr size_t EVENT_BUFFER_SIZE = 150;
|
|
constexpr size_t LONG_TASK_BUFFER_SIZE = 200;
|
|
constexpr size_t RESOURCE_TIMING_BUFFER_SIZE = 250;
|
|
constexpr HighResDuration LONG_TASK_DURATION_THRESHOLD =
|
|
HighResDuration::fromMilliseconds(50);
|
|
class PerformanceEntryReporter {
|
|
public:
|
|
PerformanceEntryReporter();
|
|
static std::shared_ptr<PerformanceEntryReporter>& getInstance();
|
|
PerformanceObserverRegistry& getObserverRegistry() {
|
|
return *observerRegistry_;
|
|
}
|
|
std::vector<PerformanceEntry> getEntries() const;
|
|
void getEntries(std::vector<PerformanceEntry>& dest) const;
|
|
std::vector<PerformanceEntry> getEntries(
|
|
PerformanceEntryType entryType) const;
|
|
void getEntries(
|
|
std::vector<PerformanceEntry>& dest,
|
|
PerformanceEntryType entryType) const;
|
|
std::vector<PerformanceEntry> getEntries(
|
|
PerformanceEntryType entryType,
|
|
const std::string& entryName) const;
|
|
void getEntries(
|
|
std::vector<PerformanceEntry>& dest,
|
|
PerformanceEntryType entryType,
|
|
const std::string& entryName) const;
|
|
void clearEntries();
|
|
void clearEntries(PerformanceEntryType entryType);
|
|
void clearEntries(
|
|
PerformanceEntryType entryType,
|
|
const std::string& entryName);
|
|
HighResTimeStamp getCurrentTimeStamp() const;
|
|
static std::vector<PerformanceEntryType> getSupportedEntryTypes();
|
|
uint32_t getDroppedEntriesCount(PerformanceEntryType type) const noexcept;
|
|
const std::unordered_map<std::string, uint32_t>& getEventCounts() const {
|
|
return eventCounts_;
|
|
}
|
|
void clearEventCounts();
|
|
std::optional<HighResTimeStamp> getMarkTime(
|
|
const std::string& markName) const;
|
|
using UserTimingDetailProvider = std::function<folly::dynamic()>;
|
|
void reportMark(
|
|
const std::string& name,
|
|
HighResTimeStamp startTime,
|
|
UserTimingDetailProvider&& detailProvider = nullptr);
|
|
void reportMeasure(
|
|
const std::string& name,
|
|
HighResTimeStamp startTime,
|
|
HighResDuration duration,
|
|
UserTimingDetailProvider&& detailProvider = nullptr);
|
|
void reportEvent(
|
|
std::string name,
|
|
HighResTimeStamp startTime,
|
|
HighResDuration duration,
|
|
HighResTimeStamp processingStart,
|
|
HighResTimeStamp processingEnd,
|
|
uint32_t interactionId);
|
|
void reportLongTask(HighResTimeStamp startTime, HighResDuration duration);
|
|
void reportResourceTiming(
|
|
const std::string& url,
|
|
HighResTimeStamp fetchStart,
|
|
HighResTimeStamp requestStart,
|
|
std::optional<HighResTimeStamp> connectStart,
|
|
std::optional<HighResTimeStamp> connectEnd,
|
|
HighResTimeStamp responseStart,
|
|
HighResTimeStamp responseEnd,
|
|
const std::optional<int>& responseStatus);
|
|
};
|
|
PerformanceEntryCircularBuffer longTaskBuffer_{LONG_TASK_BUFFER_SIZE};
|
|
PerformanceEntryCircularBuffer resourceTimingBuffer_{
|
|
RESOURCE_TIMING_BUFFER_SIZE};
|
|
PerformanceEntryKeyedBuffer markBuffer_;
|
|
PerformanceEntryKeyedBuffer measureBuffer_;
|
|
std::unordered_map<std::string, uint32_t> eventCounts_;
|
|
std::function<HighResTimeStamp()> timeStampProvider_ = nullptr;
|
|
const inline PerformanceEntryBuffer& getBuffer(
|
|
PerformanceEntryType entryType) const {
|
|
switch (entryType) {
|
|
case PerformanceEntryType::EVENT:
|
|
return eventBuffer_;
|
|
case PerformanceEntryType::MARK:
|
|
return markBuffer_;
|
|
case PerformanceEntryType::MEASURE:
|
|
return measureBuffer_;
|
|
case PerformanceEntryType::LONGTASK:
|
|
return longTaskBuffer_;
|
|
case PerformanceEntryType::RESOURCE:
|
|
return resourceTimingBuffer_;
|
|
case PerformanceEntryType::_NEXT:
|
|
throw std::logic_error("Cannot get buffer for _NEXT entry type");
|
|
}
|
|
throw std::logic_error("Unhandled PerformanceEntryType");
|
|
}
|
|
inline PerformanceEntryBuffer& getBufferRef(PerformanceEntryType entryType) {
|
|
switch (entryType) {
|
|
case PerformanceEntryType::EVENT:
|
|
return eventBuffer_;
|
|
case PerformanceEntryType::MARK:
|
|
return markBuffer_;
|
|
case PerformanceEntryType::MEASURE:
|
|
return measureBuffer_;
|
|
case PerformanceEntryType::LONGTASK:
|
|
return longTaskBuffer_;
|
|
case PerformanceEntryType::RESOURCE:
|
|
return resourceTimingBuffer_;
|
|
case PerformanceEntryType::_NEXT:
|
|
throw std::logic_error("Cannot get buffer for _NEXT entry type");
|
|
}
|
|
throw std::logic_error("Unhandled PerformanceEntryType");
|
|
}
|
|
void traceMark(
|
|
const PerformanceMark& entry,
|
|
UserTimingDetailProvider&& detailProvider) const;
|
|
void traceMeasure(
|
|
const PerformanceMeasure& entry,
|
|
UserTimingDetailProvider&& detailProvider) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceObserver.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}
|
|
|
|
namespace facebook::react {
|
|
constexpr HighResDuration DEFAULT_DURATION_THRESHOLD = HighResDuration::zero();
|
|
class PerformanceEntryBuffer {
|
|
public:
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
size_t droppedEntriesCount{0};
|
|
explicit PerformanceEntryBuffer() = default;
|
|
virtual ~PerformanceEntryBuffer() = default;
|
|
virtual void add(const PerformanceEntry& entry) = 0;
|
|
virtual void getEntries(std::vector<PerformanceEntry>& target) const = 0;
|
|
virtual void getEntries(
|
|
std::vector<PerformanceEntry>& target,
|
|
const std::string& name) const = 0;
|
|
virtual void clear() = 0;
|
|
virtual void clear(const std::string& name) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class PerformanceObserverRegistry {
|
|
public:
|
|
PerformanceObserverRegistry() = default;
|
|
void addObserver(std::shared_ptr<PerformanceObserver> observer);
|
|
void removeObserver(std::shared_ptr<PerformanceObserver> observer);
|
|
void queuePerformanceEntry(const PerformanceEntry& entry);
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
using PerformanceObserverEntryTypeFilter =
|
|
std::unordered_set<PerformanceEntryType>;
|
|
using PerformanceObserverCallback = std::function<void()>;
|
|
struct PerformanceObserverObserveMultipleOptions {
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
};
|
|
struct PerformanceObserverObserveSingleOptions {
|
|
bool buffered = false;
|
|
HighResDuration durationThreshold = DEFAULT_DURATION_THRESHOLD;
|
|
};
|
|
class PerformanceObserver
|
|
: public std::enable_shared_from_this<PerformanceObserver> {};
|
|
|
|
public:
|
|
explicit PerformanceObserver(
|
|
PrivateUseCreateMethod,
|
|
PerformanceObserverRegistry& registry,
|
|
PerformanceObserverCallback&& callback)
|
|
: registry_(registry), callback_(std::move(callback)) {}
|
|
static std::shared_ptr<PerformanceObserver> create(
|
|
PerformanceObserverRegistry& registry,
|
|
PerformanceObserverCallback&& callback) {
|
|
return std::make_shared<PerformanceObserver>(
|
|
PrivateUseCreateMethod(), registry, std::move(callback));
|
|
}
|
|
~PerformanceObserver() = default;
|
|
void handleEntry(const PerformanceEntry& entry);
|
|
[[nodiscard]] std::vector<PerformanceEntry> takeRecords();
|
|
void observe(
|
|
PerformanceEntryType type,
|
|
PerformanceObserverObserveSingleOptions options = {});
|
|
void observe(std::unordered_set<PerformanceEntryType> types);
|
|
void disconnect() noexcept;
|
|
uint32_t getDroppedEntriesCount() noexcept;
|
|
};
|
|
inline bool operator==(
|
|
const PerformanceObserver& lhs,
|
|
const PerformanceObserver& rhs) {
|
|
return &lhs == &rhs;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/performance/timeline/PerformanceObserverRegistry.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/performance/timeline/PerformanceEntry.h}
|
|
|
|
namespace facebook::react {
|
|
class PerformanceObserverRegistry {
|
|
public:
|
|
PerformanceObserverRegistry() = default;
|
|
void addObserver(std::shared_ptr<PerformanceObserver> observer);
|
|
void removeObserver(std::shared_ptr<PerformanceObserver> observer);
|
|
void queuePerformanceEntry(const PerformanceEntry& entry);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/animations/LayoutAnimationCallbackWrapper.h}:
|
|
namespace facebook::react {
|
|
class LayoutAnimationCallbackWrapper {
|
|
public:
|
|
LayoutAnimationCallbackWrapper(jsi::Function&& callback)
|
|
: callback_(std::make_shared<jsi::Function>(std::move(callback))) {}
|
|
LayoutAnimationCallbackWrapper() : callback_(nullptr) {}
|
|
void call(jsi::Runtime& runtime) const {
|
|
if (callback_) {
|
|
callback_->call(runtime);
|
|
callback_.reset();
|
|
}
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/animations/LayoutAnimationDriver.h}:
|
|
namespace facebook::react {
|
|
class LayoutAnimationDriver : public LayoutAnimationKeyFrameManager {
|
|
public:
|
|
LayoutAnimationDriver(
|
|
RuntimeExecutor runtimeExecutor,
|
|
std::shared_ptr<const ContextContainer>& contextContainer,
|
|
LayoutAnimationStatusDelegate* delegate)
|
|
: LayoutAnimationKeyFrameManager(
|
|
runtimeExecutor,
|
|
contextContainer,
|
|
delegate) {}
|
|
|
|
protected:
|
|
virtual void animationMutationsForFrame(
|
|
SurfaceId surfaceId,
|
|
ShadowViewMutation::List& mutationsList,
|
|
uint64_t now) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/animations/LayoutAnimationKeyFrameManager.h}:
|
|
namespace facebook::react {
|
|
class LayoutAnimationKeyFrameManager : public UIManagerAnimationDelegate,
|
|
public MountingOverrideDelegate {
|
|
public:
|
|
LayoutAnimationKeyFrameManager(
|
|
RuntimeExecutor runtimeExecutor,
|
|
std::shared_ptr<const ContextContainer>& contextContainer,
|
|
LayoutAnimationStatusDelegate* delegate);
|
|
void uiManagerDidConfigureNextLayoutAnimation(
|
|
jsi::Runtime& runtime,
|
|
const RawValue& config,
|
|
const jsi::Value& successCallbackValue,
|
|
const jsi::Value& failureCallbackValue) const override;
|
|
void setComponentDescriptorRegistry(const SharedComponentDescriptorRegistry&
|
|
componentDescriptorRegistry) override;
|
|
bool shouldAnimateFrame() const override;
|
|
void stopSurface(SurfaceId surfaceId) override;
|
|
bool shouldOverridePullTransaction() const override;
|
|
std::optional<MountingTransaction> pullTransaction(
|
|
SurfaceId surfaceId,
|
|
MountingTransaction::Number number,
|
|
const TransactionTelemetry& telemetry,
|
|
ShadowViewMutationList mutations) const override;
|
|
void uiManagerDidConfigureNextLayoutAnimation(
|
|
LayoutAnimation layoutAnimation) const;
|
|
void setLayoutAnimationStatusDelegate(
|
|
LayoutAnimationStatusDelegate* delegate) const;
|
|
void setClockNow(std::function<uint64_t()> now);
|
|
|
|
protected:
|
|
SharedComponentDescriptorRegistry componentDescriptorRegistry_;
|
|
mutable std::optional<LayoutAnimation> currentAnimation_{};
|
|
mutable std::mutex currentAnimationMutex_;
|
|
mutable std::vector<LayoutAnimation> inflightAnimations_{};
|
|
bool hasComponentDescriptorForShadowView(const ShadowView& shadowView) const;
|
|
const ComponentDescriptor& getComponentDescriptorForShadowView(
|
|
const ShadowView& shadowView) const;
|
|
ShadowView createInterpolatedShadowView(
|
|
Float progress,
|
|
const ShadowView& startingView,
|
|
const ShadowView& finalView) const;
|
|
void callCallback(const LayoutAnimationCallbackWrapper& callback) const;
|
|
virtual void animationMutationsForFrame(
|
|
SurfaceId surfaceId,
|
|
ShadowViewMutation::List& mutationsList,
|
|
uint64_t now) const = 0;
|
|
void queueFinalMutationsForCompletedKeyFrame(
|
|
const AnimationKeyFrame& keyframe,
|
|
ShadowViewMutation::List& mutationsList,
|
|
bool interrupted,
|
|
const std::string& logPrefix) const;
|
|
};
|
|
mutable std::mutex surfaceIdsToStopMutex_;
|
|
mutable std::unordered_set<SurfaceId> surfaceIdsToStop_{};
|
|
std::function<uint64_t()> now_;
|
|
void adjustImmediateMutationIndicesForDelayedMutations(
|
|
SurfaceId surfaceId,
|
|
ShadowViewMutation& mutation,
|
|
bool skipLastAnimation = false,
|
|
bool lastAnimationOnly = false) const;
|
|
void adjustDelayedMutationIndicesForMutation(
|
|
SurfaceId surfaceId,
|
|
const ShadowViewMutation& mutation,
|
|
bool skipLastAnimation = false) const;
|
|
void getAndEraseConflictingAnimations(
|
|
SurfaceId surfaceId,
|
|
const ShadowViewMutationList& mutations,
|
|
std::vector<AnimationKeyFrame>& conflictingAnimations) const;
|
|
void deleteAnimationsForStoppedSurfaces() const;
|
|
void simulateImagePropsMemoryAccess(
|
|
const ShadowViewMutationList& mutations) const;
|
|
Props::Shared interpolateProps(
|
|
const ComponentDescriptor& componentDescriptor,
|
|
const PropsParserContext& context,
|
|
Float animationProgress,
|
|
const Props::Shared& props,
|
|
const Props::Shared& newProps,
|
|
const Size& size) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/animations/conversions.h}:
|
|
namespace facebook::react {
|
|
static inline std::optional<AnimationType> parseAnimationType(
|
|
std::string param) {
|
|
if (param == "spring") {
|
|
return AnimationType::Spring;
|
|
}
|
|
if (param == "linear") {
|
|
return AnimationType::Linear;
|
|
}
|
|
if (param == "easeInEaseOut") {
|
|
return AnimationType::EaseInEaseOut;
|
|
}
|
|
if (param == "easeIn") {
|
|
return AnimationType::EaseIn;
|
|
}
|
|
if (param == "easeOut") {
|
|
return AnimationType::EaseOut;
|
|
}
|
|
if (param == "keyboard") {
|
|
return AnimationType::Keyboard;
|
|
}
|
|
LOG(ERROR) << "Error parsing animation type: " << param;
|
|
return {};
|
|
}
|
|
static inline std::optional<AnimationProperty> parseAnimationProperty(
|
|
std::string param) {
|
|
if (param == "opacity") {
|
|
return AnimationProperty::Opacity;
|
|
}
|
|
if (param == "scaleX") {
|
|
return AnimationProperty::ScaleX;
|
|
}
|
|
if (param == "scaleY") {
|
|
return AnimationProperty::ScaleY;
|
|
}
|
|
if (param == "scaleXY") {
|
|
return AnimationProperty::ScaleXY;
|
|
}
|
|
LOG(ERROR) << "Error parsing animation property: " << param;
|
|
return {};
|
|
}
|
|
static inline std::optional<AnimationConfig> parseAnimationConfig(
|
|
const folly::dynamic& config,
|
|
double defaultDuration,
|
|
bool parsePropertyType) {
|
|
if (config.empty() || !config.isObject()) {
|
|
return AnimationConfig{
|
|
AnimationType::Linear,
|
|
AnimationProperty::NotApplicable,
|
|
defaultDuration,
|
|
0,
|
|
0,
|
|
0};
|
|
}
|
|
const auto typeIt = config.find("type");
|
|
if (typeIt == config.items().end()) {
|
|
LOG(ERROR) << "Error parsing animation config: could not find field `type`";
|
|
return {};
|
|
}
|
|
const auto animationTypeParam = typeIt->second;
|
|
if (animationTypeParam.empty() || !animationTypeParam.isString()) {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: could not unwrap field `type`";
|
|
return {};
|
|
}
|
|
const auto animationType = parseAnimationType(animationTypeParam.asString());
|
|
if (!animationType) {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: could not parse field `type`";
|
|
return {};
|
|
}
|
|
AnimationProperty animationProperty = AnimationProperty::NotApplicable;
|
|
if (parsePropertyType) {
|
|
const auto propertyIt = config.find("property");
|
|
if (propertyIt == config.items().end()) {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: could not find field `property`";
|
|
return {};
|
|
}
|
|
const auto animationPropertyParam = propertyIt->second;
|
|
if (animationPropertyParam.empty() || !animationPropertyParam.isString()) {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: could not unwrap field `property`";
|
|
return {};
|
|
}
|
|
const auto animationPropertyParsed =
|
|
parseAnimationProperty(animationPropertyParam.asString());
|
|
if (!animationPropertyParsed) {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: could not parse field `property`";
|
|
return {};
|
|
}
|
|
animationProperty = *animationPropertyParsed;
|
|
}
|
|
double duration = defaultDuration;
|
|
double delay = 0;
|
|
Float springDamping = 0.5;
|
|
Float initialVelocity = 0;
|
|
const auto durationIt = config.find("duration");
|
|
if (durationIt != config.items().end()) {
|
|
if (durationIt->second.isDouble()) {
|
|
duration = durationIt->second.asDouble();
|
|
} else {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: field `duration` must be a number";
|
|
return {};
|
|
}
|
|
}
|
|
const auto delayIt = config.find("delay");
|
|
if (delayIt != config.items().end()) {
|
|
if (delayIt->second.isDouble()) {
|
|
delay = delayIt->second.asDouble();
|
|
} else {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: field `delay` must be a number";
|
|
return {};
|
|
}
|
|
}
|
|
const auto springDampingIt = config.find("springDamping");
|
|
if (springDampingIt != config.items().end() &&
|
|
springDampingIt->second.isDouble()) {
|
|
if (springDampingIt->second.isDouble()) {
|
|
springDamping = (Float)springDampingIt->second.asDouble();
|
|
} else {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: field `springDamping` must be a number";
|
|
return {};
|
|
}
|
|
}
|
|
const auto initialVelocityIt = config.find("initialVelocity");
|
|
if (initialVelocityIt != config.items().end()) {
|
|
if (initialVelocityIt->second.isDouble()) {
|
|
initialVelocity = (Float)initialVelocityIt->second.asDouble();
|
|
} else {
|
|
LOG(ERROR)
|
|
<< "Error parsing animation config: field `initialVelocity` must be a number";
|
|
return {};
|
|
}
|
|
}
|
|
return std::optional<AnimationConfig>(AnimationConfig{
|
|
*animationType,
|
|
animationProperty,
|
|
duration,
|
|
delay,
|
|
springDamping,
|
|
initialVelocity});
|
|
}
|
|
static inline std::optional<LayoutAnimationConfig> parseLayoutAnimationConfig(
|
|
const folly::dynamic& config) {
|
|
if (config.empty() || !config.isObject()) {
|
|
return {};
|
|
}
|
|
const auto durationIt = config.find("duration");
|
|
if (durationIt == config.items().end() || !durationIt->second.isDouble()) {
|
|
return {};
|
|
}
|
|
const double duration = durationIt->second.asDouble();
|
|
const auto createConfigIt = config.find("create");
|
|
const auto createConfig = createConfigIt == config.items().end()
|
|
? std::optional<AnimationConfig>(AnimationConfig{})
|
|
: parseAnimationConfig(createConfigIt->second, duration, true);
|
|
const auto updateConfigIt = config.find("update");
|
|
const auto updateConfig = updateConfigIt == config.items().end()
|
|
? std::optional<AnimationConfig>(AnimationConfig{})
|
|
: parseAnimationConfig(updateConfigIt->second, duration, false);
|
|
const auto deleteConfigIt = config.find("delete");
|
|
const auto deleteConfig = deleteConfigIt == config.items().end()
|
|
? std::optional<AnimationConfig>(AnimationConfig{})
|
|
: parseAnimationConfig(deleteConfigIt->second, duration, true);
|
|
if (!createConfig || !updateConfig || !deleteConfig) {
|
|
return {};
|
|
}
|
|
return LayoutAnimationConfig{
|
|
duration, *createConfig, *updateConfig, *deleteConfig};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/animations/primitives.h}:
|
|
namespace facebook::react {
|
|
enum class AnimationType {
|
|
None = 0,
|
|
Spring = 1,
|
|
Linear = 2,
|
|
EaseInEaseOut = 4,
|
|
EaseIn = 8,
|
|
EaseOut = 16,
|
|
Keyboard = 32
|
|
};
|
|
enum class AnimationProperty {
|
|
NotApplicable = 0,
|
|
Opacity = 1,
|
|
ScaleX = 2,
|
|
ScaleY = 4,
|
|
ScaleXY = 8
|
|
};
|
|
struct AnimationConfig {
|
|
AnimationType animationType = AnimationType::None;
|
|
AnimationProperty animationProperty = AnimationProperty::NotApplicable;
|
|
double duration = 0;
|
|
double delay = 0;
|
|
Float springDamping = 0;
|
|
Float initialVelocity = 0;
|
|
};
|
|
struct LayoutAnimationConfig {
|
|
double duration;
|
|
AnimationConfig createConfig;
|
|
AnimationConfig updateConfig;
|
|
AnimationConfig deleteConfig;
|
|
};
|
|
enum class AnimationConfigurationType { Create = 1, Update = 2, Delete = 4 };
|
|
struct AnimationKeyFrame {
|
|
std::vector<ShadowViewMutation> finalMutationsForKeyFrame;
|
|
AnimationConfigurationType type;
|
|
Tag tag;
|
|
Tag parentTag;
|
|
ShadowView viewStart;
|
|
ShadowView viewEnd;
|
|
ShadowView viewPrev;
|
|
double initialProgress;
|
|
bool invalidated{false};
|
|
bool generateFinalSyntheticMutations{true};
|
|
};
|
|
struct LayoutAnimation {
|
|
SurfaceId surfaceId;
|
|
uint64_t startTime;
|
|
bool completed = false;
|
|
LayoutAnimationConfig layoutAnimationConfig;
|
|
LayoutAnimationCallbackWrapper successCallback;
|
|
LayoutAnimationCallbackWrapper failureCallback;
|
|
std::vector<AnimationKeyFrame> keyFrames;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/animations/utils.h}:
|
|
namespace facebook::react {
|
|
static inline bool shouldFirstComeBeforeSecondRemovesOnly(
|
|
const ShadowViewMutation& lhs,
|
|
const ShadowViewMutation& rhs) noexcept {
|
|
return (lhs.type == ShadowViewMutation::Type::Remove &&
|
|
lhs.type == rhs.type) &&
|
|
(lhs.parentTag == rhs.parentTag) && (lhs.index > rhs.index);
|
|
}
|
|
static inline void handleShouldFirstComeBeforeSecondRemovesOnly(
|
|
ShadowViewMutation::List& list) noexcept {
|
|
std::unordered_map<std::string, std::vector<ShadowViewMutation>>
|
|
removeMutationsByTag;
|
|
ShadowViewMutation::List finalList;
|
|
for (auto& mutation : list) {
|
|
if (mutation.type == ShadowViewMutation::Type::Remove) {
|
|
auto key = std::to_string(mutation.parentTag);
|
|
removeMutationsByTag[key].push_back(mutation);
|
|
} else {
|
|
finalList.push_back(mutation);
|
|
}
|
|
}
|
|
if (removeMutationsByTag.size() == 0) {
|
|
return;
|
|
}
|
|
for (auto& mutationsPair : removeMutationsByTag) {
|
|
if (mutationsPair.second.size() > 1) {
|
|
std::stable_sort(
|
|
mutationsPair.second.begin(),
|
|
mutationsPair.second.end(),
|
|
&shouldFirstComeBeforeSecondRemovesOnly);
|
|
}
|
|
finalList.insert(
|
|
finalList.begin(),
|
|
mutationsPair.second.begin(),
|
|
mutationsPair.second.end());
|
|
}
|
|
list = finalList;
|
|
}
|
|
static inline bool shouldFirstComeBeforeSecondMutation(
|
|
const ShadowViewMutation& lhs,
|
|
const ShadowViewMutation& rhs) noexcept {
|
|
if (lhs.type != rhs.type) {
|
|
if (lhs.type == ShadowViewMutation::Type::Delete) {
|
|
return false;
|
|
}
|
|
if (rhs.type == ShadowViewMutation::Type::Delete) {
|
|
return true;
|
|
}
|
|
if (lhs.type == ShadowViewMutation::Type::Remove &&
|
|
rhs.type == ShadowViewMutation::Type::Insert) {
|
|
return true;
|
|
}
|
|
if (rhs.type == ShadowViewMutation::Type::Remove &&
|
|
lhs.type == ShadowViewMutation::Type::Insert) {
|
|
return false;
|
|
}
|
|
if (lhs.type == ShadowViewMutation::Type::Create &&
|
|
rhs.type == ShadowViewMutation::Type::Insert) {
|
|
return true;
|
|
}
|
|
if (rhs.type == ShadowViewMutation::Type::Create &&
|
|
lhs.type == ShadowViewMutation::Type::Insert) {
|
|
return false;
|
|
}
|
|
if (lhs.type == ShadowViewMutation::Type::Remove &&
|
|
rhs.type == ShadowViewMutation::Type::Update) {
|
|
return true;
|
|
}
|
|
if (rhs.type == ShadowViewMutation::Type::Remove &&
|
|
lhs.type == ShadowViewMutation::Type::Update) {
|
|
return false;
|
|
}
|
|
} else {
|
|
if (lhs.type == ShadowViewMutation::Type::Remove &&
|
|
lhs.parentTag == rhs.parentTag) {
|
|
return lhs.index > rhs.index;
|
|
}
|
|
}
|
|
return &lhs < &rhs;
|
|
}
|
|
std::pair<Float, Float> calculateAnimationProgress(
|
|
uint64_t now,
|
|
const LayoutAnimation& animation,
|
|
const AnimationConfig& mutationConfig);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedString.h}:
|
|
namespace facebook::react {
|
|
class AttributedString : public Sealable, public DebugStringConvertible {
|
|
public:
|
|
class Fragment {
|
|
public:
|
|
static std::string AttachmentCharacter();
|
|
std::string string;
|
|
TextAttributes textAttributes;
|
|
ShadowView parentShadowView;
|
|
bool isAttachment() const;
|
|
bool isContentEqual(const Fragment& rhs) const;
|
|
bool operator==(const Fragment& rhs) const;
|
|
};
|
|
class Range {
|
|
public:
|
|
int location{0};
|
|
int length{0};
|
|
};
|
|
using Fragments = std::vector<Fragment>;
|
|
void appendFragment(Fragment&& fragment);
|
|
void prependFragment(Fragment&& fragment);
|
|
void setBaseTextAttributes(const TextAttributes& defaultAttributes);
|
|
const Fragments& getFragments() const;
|
|
Fragments& getFragments();
|
|
std::string getString() const;
|
|
const TextAttributes& getBaseTextAttributes() const;
|
|
bool isEmpty() const;
|
|
bool compareTextAttributesWithoutFrame(const AttributedString& rhs) const;
|
|
bool isContentEqual(const AttributedString& rhs) const;
|
|
bool operator==(const AttributedString& rhs) const;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::AttributedString::Fragment> {
|
|
size_t operator()(
|
|
const facebook::react::AttributedString::Fragment& fragment) const {
|
|
return facebook::react::hash_combine(
|
|
fragment.string,
|
|
fragment.textAttributes,
|
|
fragment.parentShadowView.tag,
|
|
fragment.parentShadowView.layoutMetrics);
|
|
}
|
|
};
|
|
template <>
|
|
struct hash<facebook::react::AttributedString> {
|
|
size_t operator()(
|
|
const facebook::react::AttributedString& attributedString) const {
|
|
auto seed = size_t{0};
|
|
facebook::react::hash_combine(
|
|
seed, attributedString.getBaseTextAttributes());
|
|
for (const auto& fragment : attributedString.getFragments()) {
|
|
facebook::react::hash_combine(seed, fragment);
|
|
}
|
|
return seed;
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/AttributedStringBox.h}:
|
|
namespace facebook::react {
|
|
class AttributedStringBox final {
|
|
public:
|
|
enum class Mode { Value, OpaquePointer };
|
|
AttributedStringBox();
|
|
explicit AttributedStringBox(const AttributedString& value);
|
|
explicit AttributedStringBox(std::shared_ptr<void> opaquePointer);
|
|
AttributedStringBox(const AttributedStringBox& other) = default;
|
|
AttributedStringBox(AttributedStringBox&& other) noexcept;
|
|
AttributedStringBox& operator=(const AttributedStringBox& other) = default;
|
|
AttributedStringBox& operator=(AttributedStringBox&& other) noexcept;
|
|
Mode getMode() const;
|
|
const AttributedString& getValue() const;
|
|
std::shared_ptr<void> getOpaquePointer() const;
|
|
};
|
|
bool operator==(const AttributedStringBox& lhs, const AttributedStringBox& rhs);
|
|
bool operator!=(const AttributedStringBox& lhs, const AttributedStringBox& rhs);
|
|
} // namespace facebook::react
|
|
template <>
|
|
struct std::hash<facebook::react::AttributedStringBox> {
|
|
size_t operator()(
|
|
const facebook::react::AttributedStringBox& attributedStringBox) const {
|
|
switch (attributedStringBox.getMode()) {
|
|
case facebook::react::AttributedStringBox::Mode::Value:
|
|
return std::hash<facebook::react::AttributedString>()(
|
|
attributedStringBox.getValue());
|
|
case facebook::react::AttributedStringBox::Mode::OpaquePointer:
|
|
return std::hash<std::shared_ptr<void>>()(
|
|
attributedStringBox.getOpaquePointer());
|
|
}
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/ParagraphAttributes.h}:
|
|
namespace facebook::react {
|
|
using SharedParagraphAttributes = std::shared_ptr<const ParagraphAttributes>;
|
|
class ParagraphAttributes : public DebugStringConvertible {
|
|
public:
|
|
int maximumNumberOfLines{};
|
|
EllipsizeMode ellipsizeMode{};
|
|
TextBreakStrategy textBreakStrategy{TextBreakStrategy::HighQuality};
|
|
bool adjustsFontSizeToFit{};
|
|
bool includeFontPadding{true};
|
|
HyphenationFrequency android_hyphenationFrequency{};
|
|
Float minimumFontSize{std::numeric_limits<Float>::quiet_NaN()};
|
|
Float maximumFontSize{std::numeric_limits<Float>::quiet_NaN()};
|
|
Float minimumFontScale{std::numeric_limits<Float>::quiet_NaN()};
|
|
std::optional<TextAlignmentVertical> textAlignVertical{};
|
|
bool operator==(const ParagraphAttributes&) const;
|
|
bool operator!=(const ParagraphAttributes&) const;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::ParagraphAttributes> {
|
|
size_t operator()(
|
|
const facebook::react::ParagraphAttributes& attributes) const {
|
|
return facebook::react::hash_combine(
|
|
attributes.maximumNumberOfLines,
|
|
attributes.ellipsizeMode,
|
|
attributes.textBreakStrategy,
|
|
attributes.adjustsFontSizeToFit,
|
|
attributes.minimumFontSize,
|
|
attributes.maximumFontSize,
|
|
attributes.includeFontPadding,
|
|
attributes.android_hyphenationFrequency,
|
|
attributes.minimumFontScale,
|
|
attributes.textAlignVertical);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/PlaceholderAttributedString.h}:
|
|
namespace facebook::react {
|
|
inline AttributedString ensurePlaceholderIfEmpty_DO_NOT_USE(
|
|
const AttributedString& attributedString) {
|
|
if (attributedString.isEmpty()) {
|
|
AttributedString placeholder{attributedString};
|
|
placeholder.appendFragment(
|
|
{.string = "I",
|
|
.textAttributes = attributedString.getBaseTextAttributes(),
|
|
.parentShadowView = {}});
|
|
return placeholder;
|
|
}
|
|
return attributedString;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/TextAttributes.h}:
|
|
namespace facebook::react {
|
|
using SharedTextAttributes = std::shared_ptr<const TextAttributes>;
|
|
class TextAttributes : public DebugStringConvertible {
|
|
public:
|
|
static TextAttributes defaultTextAttributes();
|
|
SharedColor foregroundColor{};
|
|
SharedColor backgroundColor{};
|
|
Float opacity{std::numeric_limits<Float>::quiet_NaN()};
|
|
std::string fontFamily{""};
|
|
Float fontSize{std::numeric_limits<Float>::quiet_NaN()};
|
|
Float fontSizeMultiplier{std::numeric_limits<Float>::quiet_NaN()};
|
|
std::optional<FontWeight> fontWeight{};
|
|
std::optional<FontStyle> fontStyle{};
|
|
std::optional<FontVariant> fontVariant{};
|
|
std::optional<bool> allowFontScaling{};
|
|
Float maxFontSizeMultiplier{std::numeric_limits<Float>::quiet_NaN()};
|
|
std::optional<DynamicTypeRamp> dynamicTypeRamp{};
|
|
Float letterSpacing{std::numeric_limits<Float>::quiet_NaN()};
|
|
std::optional<TextTransform> textTransform{};
|
|
Float lineHeight{std::numeric_limits<Float>::quiet_NaN()};
|
|
std::optional<TextAlignment> alignment{};
|
|
std::optional<WritingDirection> baseWritingDirection{};
|
|
std::optional<LineBreakStrategy> lineBreakStrategy{};
|
|
std::optional<LineBreakMode> lineBreakMode{};
|
|
SharedColor textDecorationColor{};
|
|
std::optional<TextDecorationLineType> textDecorationLineType{};
|
|
std::optional<TextDecorationStyle> textDecorationStyle{};
|
|
std::optional<Size> textShadowOffset{};
|
|
Float textShadowRadius{std::numeric_limits<Float>::quiet_NaN()};
|
|
SharedColor textShadowColor{};
|
|
std::optional<bool> isHighlighted{};
|
|
std::optional<bool> isPressable{};
|
|
std::optional<LayoutDirection> layoutDirection{};
|
|
std::optional<AccessibilityRole> accessibilityRole{};
|
|
std::optional<Role> role{};
|
|
void apply(TextAttributes textAttributes);
|
|
bool operator==(const TextAttributes& rhs) const;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::TextAttributes> {
|
|
size_t operator()(
|
|
const facebook::react::TextAttributes& textAttributes) const {
|
|
return facebook::react::hash_combine(
|
|
textAttributes.foregroundColor,
|
|
textAttributes.backgroundColor,
|
|
textAttributes.opacity,
|
|
textAttributes.fontFamily,
|
|
textAttributes.fontSize,
|
|
textAttributes.maxFontSizeMultiplier,
|
|
textAttributes.fontSizeMultiplier,
|
|
textAttributes.fontWeight,
|
|
textAttributes.fontStyle,
|
|
textAttributes.fontVariant,
|
|
textAttributes.allowFontScaling,
|
|
textAttributes.letterSpacing,
|
|
textAttributes.textTransform,
|
|
textAttributes.lineHeight,
|
|
textAttributes.alignment,
|
|
textAttributes.baseWritingDirection,
|
|
textAttributes.lineBreakStrategy,
|
|
textAttributes.lineBreakMode,
|
|
textAttributes.textDecorationColor,
|
|
textAttributes.textDecorationLineType,
|
|
textAttributes.textDecorationStyle,
|
|
textAttributes.textShadowOffset,
|
|
textAttributes.textShadowRadius,
|
|
textAttributes.textShadowColor,
|
|
textAttributes.isHighlighted,
|
|
textAttributes.isPressable,
|
|
textAttributes.layoutDirection,
|
|
textAttributes.accessibilityRole,
|
|
textAttributes.role);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/conversions.h}:
|
|
namespace facebook::react {
|
|
inline std::string toString(const DynamicTypeRamp& dynamicTypeRamp) {
|
|
switch (dynamicTypeRamp) {
|
|
case DynamicTypeRamp::Caption2:
|
|
return "caption2";
|
|
case DynamicTypeRamp::Caption1:
|
|
return "caption1";
|
|
case DynamicTypeRamp::Footnote:
|
|
return "footnote";
|
|
case DynamicTypeRamp::Subheadline:
|
|
return "subheadline";
|
|
case DynamicTypeRamp::Callout:
|
|
return "callout";
|
|
case DynamicTypeRamp::Body:
|
|
return "body";
|
|
case DynamicTypeRamp::Headline:
|
|
return "headline";
|
|
case DynamicTypeRamp::Title3:
|
|
return "title3";
|
|
case DynamicTypeRamp::Title2:
|
|
return "title2";
|
|
case DynamicTypeRamp::Title1:
|
|
return "title1";
|
|
case DynamicTypeRamp::LargeTitle:
|
|
return "largeTitle";
|
|
}
|
|
LOG(ERROR) << "Unsupported DynamicTypeRamp value";
|
|
react_native_expect(false);
|
|
return "body";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
DynamicTypeRamp& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "caption2") {
|
|
result = DynamicTypeRamp::Caption2;
|
|
} else if (string == "caption1") {
|
|
result = DynamicTypeRamp::Caption1;
|
|
} else if (string == "footnote") {
|
|
result = DynamicTypeRamp::Footnote;
|
|
} else if (string == "subheadline") {
|
|
result = DynamicTypeRamp::Subheadline;
|
|
} else if (string == "callout") {
|
|
result = DynamicTypeRamp::Callout;
|
|
} else if (string == "body") {
|
|
result = DynamicTypeRamp::Body;
|
|
} else if (string == "headline") {
|
|
result = DynamicTypeRamp::Headline;
|
|
} else if (string == "title3") {
|
|
result = DynamicTypeRamp::Title3;
|
|
} else if (string == "title2") {
|
|
result = DynamicTypeRamp::Title2;
|
|
} else if (string == "title1") {
|
|
result = DynamicTypeRamp::Title1;
|
|
} else if (string == "largeTitle") {
|
|
result = DynamicTypeRamp::LargeTitle;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported DynamicTypeRamp value: " << string;
|
|
react_native_expect(false);
|
|
result = DynamicTypeRamp::Body;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported DynamicTypeRamp type";
|
|
react_native_expect(false);
|
|
result = DynamicTypeRamp::Body;
|
|
}
|
|
inline std::string toString(const EllipsizeMode& ellipsisMode) {
|
|
switch (ellipsisMode) {
|
|
case EllipsizeMode::Clip:
|
|
return "clip";
|
|
case EllipsizeMode::Head:
|
|
return "head";
|
|
case EllipsizeMode::Tail:
|
|
return "tail";
|
|
case EllipsizeMode::Middle:
|
|
return "middle";
|
|
}
|
|
LOG(ERROR) << "Unsupported EllipsizeMode value";
|
|
react_native_expect(false);
|
|
return "tail";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
EllipsizeMode& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "clip") {
|
|
result = EllipsizeMode::Clip;
|
|
} else if (string == "head") {
|
|
result = EllipsizeMode::Head;
|
|
} else if (string == "tail") {
|
|
result = EllipsizeMode::Tail;
|
|
} else if (string == "middle") {
|
|
result = EllipsizeMode::Middle;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported EllipsizeMode value: " << string;
|
|
react_native_expect(false);
|
|
result = EllipsizeMode::Tail;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported EllipsizeMode type";
|
|
react_native_expect(false);
|
|
result = EllipsizeMode::Tail;
|
|
}
|
|
inline std::string toString(const TextBreakStrategy& textBreakStrategy) {
|
|
switch (textBreakStrategy) {
|
|
case TextBreakStrategy::Simple:
|
|
return "simple";
|
|
case TextBreakStrategy::HighQuality:
|
|
return "highQuality";
|
|
case TextBreakStrategy::Balanced:
|
|
return "balanced";
|
|
}
|
|
LOG(ERROR) << "Unsupported TextBreakStrategy value";
|
|
react_native_expect(false);
|
|
return "highQuality";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextBreakStrategy& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "simple") {
|
|
result = TextBreakStrategy::Simple;
|
|
} else if (string == "highQuality") {
|
|
result = TextBreakStrategy::HighQuality;
|
|
} else if (string == "balanced") {
|
|
result = TextBreakStrategy::Balanced;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported TextBreakStrategy value: " << string;
|
|
react_native_expect(false);
|
|
result = TextBreakStrategy::HighQuality;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported TextBreakStrategy type";
|
|
react_native_expect(false);
|
|
result = TextBreakStrategy::HighQuality;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
FontWeight& result) {
|
|
react_native_expect(value.hasType<std::string>() || value.hasType<int>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "normal") {
|
|
result = FontWeight::Regular;
|
|
} else if (string == "regular") {
|
|
result = FontWeight::Regular;
|
|
} else if (string == "bold") {
|
|
result = FontWeight::Bold;
|
|
} else if (string == "100") {
|
|
result = FontWeight::Weight100;
|
|
} else if (string == "200") {
|
|
result = FontWeight::Weight200;
|
|
} else if (string == "300") {
|
|
result = FontWeight::Weight300;
|
|
} else if (string == "400") {
|
|
result = FontWeight::Weight400;
|
|
} else if (string == "500") {
|
|
result = FontWeight::Weight500;
|
|
} else if (string == "600") {
|
|
result = FontWeight::Weight600;
|
|
} else if (string == "700") {
|
|
result = FontWeight::Weight700;
|
|
} else if (string == "800") {
|
|
result = FontWeight::Weight800;
|
|
} else if (string == "900") {
|
|
result = FontWeight::Weight900;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported FontWeight value: " << string;
|
|
result = FontWeight::Regular;
|
|
}
|
|
return;
|
|
}
|
|
if (value.hasType<int>()) {
|
|
auto numeric = (int)value;
|
|
if (numeric == 100) {
|
|
result = FontWeight::Weight100;
|
|
} else if (numeric == 200) {
|
|
result = FontWeight::Weight200;
|
|
} else if (numeric == 300) {
|
|
result = FontWeight::Weight300;
|
|
} else if (numeric == 400) {
|
|
result = FontWeight::Weight400;
|
|
} else if (numeric == 500) {
|
|
result = FontWeight::Weight500;
|
|
} else if (numeric == 600) {
|
|
result = FontWeight::Weight600;
|
|
} else if (numeric == 700) {
|
|
result = FontWeight::Weight700;
|
|
} else if (numeric == 800) {
|
|
result = FontWeight::Weight800;
|
|
} else if (numeric == 900) {
|
|
result = FontWeight::Weight900;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported FontWeight value: " << numeric;
|
|
result = FontWeight::Regular;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported FontWeight type";
|
|
react_native_expect(false);
|
|
result = FontWeight::Regular;
|
|
}
|
|
inline std::string toString(const FontWeight& fontWeight) {
|
|
return std::to_string((int)fontWeight);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
FontStyle& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "normal") {
|
|
result = FontStyle::Normal;
|
|
} else if (string == "italic") {
|
|
result = FontStyle::Italic;
|
|
} else if (string == "oblique") {
|
|
result = FontStyle::Oblique;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported FontStyle value: " << string;
|
|
react_native_expect(false);
|
|
result = FontStyle::Normal;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported FontStyle type";
|
|
react_native_expect(false);
|
|
result = FontStyle::Normal;
|
|
}
|
|
inline std::string toString(const FontStyle& fontStyle) {
|
|
switch (fontStyle) {
|
|
case FontStyle::Normal:
|
|
return "normal";
|
|
case FontStyle::Italic:
|
|
return "italic";
|
|
case FontStyle::Oblique:
|
|
return "oblique";
|
|
}
|
|
LOG(ERROR) << "Unsupported FontStyle value";
|
|
react_native_expect(false);
|
|
return "normal";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
FontVariant& result) {
|
|
result = FontVariant::Default;
|
|
react_native_expect(value.hasType<std::vector<std::string>>());
|
|
if (value.hasType<std::vector<std::string>>()) {
|
|
auto items = std::vector<std::string>{value};
|
|
for (const auto& item : items) {
|
|
if (item == "small-caps") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::SmallCaps);
|
|
} else if (item == "oldstyle-nums") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::OldstyleNums);
|
|
} else if (item == "lining-nums") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::LiningNums);
|
|
} else if (item == "tabular-nums") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::TabularNums);
|
|
} else if (item == "proportional-nums") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::ProportionalNums);
|
|
} else if (item == "stylistic-one") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticOne);
|
|
} else if (item == "stylistic-two") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticTwo);
|
|
} else if (item == "stylistic-three") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticThree);
|
|
} else if (item == "stylistic-four") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticFour);
|
|
} else if (item == "stylistic-five") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticFive);
|
|
} else if (item == "stylistic-six") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticSix);
|
|
} else if (item == "stylistic-seven") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticSeven);
|
|
} else if (item == "stylistic-eight") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticEight);
|
|
} else if (item == "stylistic-nine") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticNine);
|
|
} else if (item == "stylistic-ten") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticTen);
|
|
} else if (item == "stylistic-eleven") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticEleven);
|
|
} else if (item == "stylistic-twelve") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticTwelve);
|
|
} else if (item == "stylistic-thirteen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticThirteen);
|
|
} else if (item == "stylistic-fourteen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticFourteen);
|
|
} else if (item == "stylistic-fifteen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticFifteen);
|
|
} else if (item == "stylistic-sixteen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticSixteen);
|
|
} else if (item == "stylistic-seventeen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticSeventeen);
|
|
} else if (item == "stylistic-eighteen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticEighteen);
|
|
} else if (item == "stylistic-nineteen") {
|
|
result =
|
|
(FontVariant)((int)result | (int)FontVariant::StylisticNineteen);
|
|
} else if (item == "stylistic-twenty") {
|
|
result = (FontVariant)((int)result | (int)FontVariant::StylisticTwenty);
|
|
} else {
|
|
LOG(ERROR) << "Unsupported FontVariant value: " << item;
|
|
react_native_expect(false);
|
|
}
|
|
continue;
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported FontVariant type";
|
|
}
|
|
}
|
|
inline std::string toString(const FontVariant& fontVariant) {
|
|
auto result = std::string{};
|
|
auto separator = std::string{", "};
|
|
if ((int)fontVariant & (int)FontVariant::SmallCaps) {
|
|
result += "small-caps" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::OldstyleNums) {
|
|
result += "oldstyle-nums" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::LiningNums) {
|
|
result += "lining-nums" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::TabularNums) {
|
|
result += "tabular-nums" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::ProportionalNums) {
|
|
result += "proportional-nums" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticOne) {
|
|
result += "stylistic-one" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticTwo) {
|
|
result += "stylistic-two" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticThree) {
|
|
result += "stylistic-three" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticFour) {
|
|
result += "stylistic-four" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticFive) {
|
|
result += "stylistic-five" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticSix) {
|
|
result += "stylistic-six" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticSeven) {
|
|
result += "stylistic-seven" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticEight) {
|
|
result += "stylistic-eight" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticNine) {
|
|
result += "stylistic-nine" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticTen) {
|
|
result += "stylistic-ten" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticEleven) {
|
|
result += "stylistic-eleven" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticTwelve) {
|
|
result += "stylistic-twelve" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticThirteen) {
|
|
result += "stylistic-thirteen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticFourteen) {
|
|
result += "stylistic-fourteen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticFifteen) {
|
|
result += "stylistic-fifteen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticSixteen) {
|
|
result += "stylistic-sixteen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticSeventeen) {
|
|
result += "stylistic-seventeen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticEighteen) {
|
|
result += "stylistic-eighteen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticNineteen) {
|
|
result += "stylistic-nineteen" + separator;
|
|
}
|
|
if ((int)fontVariant & (int)FontVariant::StylisticTwenty) {
|
|
result += "stylistic-twenty" + separator;
|
|
}
|
|
if (!result.empty()) {
|
|
result.erase(result.length() - separator.length());
|
|
}
|
|
return result;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextTransform& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = TextTransform::None;
|
|
} else if (string == "uppercase") {
|
|
result = TextTransform::Uppercase;
|
|
} else if (string == "lowercase") {
|
|
result = TextTransform::Lowercase;
|
|
} else if (string == "capitalize") {
|
|
result = TextTransform::Capitalize;
|
|
} else if (string == "unset") {
|
|
result = TextTransform::Unset;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported TextTransform value: " << string;
|
|
react_native_expect(false);
|
|
result = TextTransform::None;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported TextTransform type";
|
|
react_native_expect(false);
|
|
result = TextTransform::None;
|
|
}
|
|
inline std::string toString(const TextTransform& textTransform) {
|
|
switch (textTransform) {
|
|
case TextTransform::None:
|
|
return "none";
|
|
case TextTransform::Uppercase:
|
|
return "uppercase";
|
|
case TextTransform::Lowercase:
|
|
return "lowercase";
|
|
case TextTransform::Capitalize:
|
|
return "capitalize";
|
|
case TextTransform::Unset:
|
|
return "unset";
|
|
}
|
|
LOG(ERROR) << "Unsupported TextTransform value";
|
|
react_native_expect(false);
|
|
return "none";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextAlignment& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "auto" || string == "start") {
|
|
result = TextAlignment::Natural;
|
|
} else if (string == "left") {
|
|
result = TextAlignment::Left;
|
|
} else if (string == "center") {
|
|
result = TextAlignment::Center;
|
|
} else if (string == "right") {
|
|
result = TextAlignment::Right;
|
|
} else if (string == "justify") {
|
|
result = TextAlignment::Justified;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported TextAlignment value: " << string;
|
|
result = TextAlignment::Natural;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported TextAlignment type";
|
|
result = TextAlignment::Natural;
|
|
}
|
|
inline std::string toString(const TextAlignment& textAlignment) {
|
|
switch (textAlignment) {
|
|
case TextAlignment::Natural:
|
|
return "auto";
|
|
case TextAlignment::Left:
|
|
return "left";
|
|
case TextAlignment::Center:
|
|
return "center";
|
|
case TextAlignment::Right:
|
|
return "right";
|
|
case TextAlignment::Justified:
|
|
return "justified";
|
|
}
|
|
LOG(ERROR) << "Unsupported TextAlignment value";
|
|
return "auto";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
TextAlignmentVertical& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "auto") {
|
|
result = TextAlignmentVertical::Auto;
|
|
} else if (string == "top") {
|
|
result = TextAlignmentVertical::Top;
|
|
} else if (string == "bottom") {
|
|
result = TextAlignmentVertical::Bottom;
|
|
} else if (string == "center") {
|
|
result = TextAlignmentVertical::Center;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported TextAlignment value: " << string;
|
|
react_native_expect(false);
|
|
result = TextAlignmentVertical::Auto;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported TextAlignmentVertical type";
|
|
result = TextAlignmentVertical::Auto;
|
|
}
|
|
inline std::string toString(const TextAlignmentVertical& textAlignment) {
|
|
switch (textAlignment) {
|
|
case TextAlignmentVertical::Auto:
|
|
return "auto";
|
|
case TextAlignmentVertical::Top:
|
|
return "top";
|
|
case TextAlignmentVertical::Bottom:
|
|
return "bottom";
|
|
case TextAlignmentVertical::Center:
|
|
return "center";
|
|
}
|
|
LOG(ERROR) << "Unsupported TextAlignmentVertical value";
|
|
return "auto";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
WritingDirection& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "natural" || string == "auto") {
|
|
result = WritingDirection::Natural;
|
|
} else if (string == "ltr") {
|
|
result = WritingDirection::LeftToRight;
|
|
} else if (string == "rtl") {
|
|
result = WritingDirection::RightToLeft;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported WritingDirection value: " << string;
|
|
react_native_expect(false);
|
|
result = WritingDirection::Natural;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported WritingDirection type";
|
|
result = WritingDirection::Natural;
|
|
}
|
|
inline std::string toString(const WritingDirection& writingDirection) {
|
|
switch (writingDirection) {
|
|
case WritingDirection::Natural:
|
|
return "auto";
|
|
case WritingDirection::LeftToRight:
|
|
return "ltr";
|
|
case WritingDirection::RightToLeft:
|
|
return "rtl";
|
|
}
|
|
LOG(ERROR) << "Unsupported WritingDirection value";
|
|
return "auto";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
LineBreakStrategy& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = LineBreakStrategy::None;
|
|
} else if (string == "push-out") {
|
|
result = LineBreakStrategy::PushOut;
|
|
} else if (string == "hangul-word") {
|
|
result = LineBreakStrategy::HangulWordPriority;
|
|
} else if (string == "standard") {
|
|
result = LineBreakStrategy::Standard;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported LineBreakStrategy value: " << string;
|
|
react_native_expect(false);
|
|
result = LineBreakStrategy::None;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported LineBreakStrategy type";
|
|
result = LineBreakStrategy::None;
|
|
}
|
|
inline std::string toString(const LineBreakStrategy& lineBreakStrategy) {
|
|
switch (lineBreakStrategy) {
|
|
case LineBreakStrategy::None:
|
|
return "none";
|
|
case LineBreakStrategy::PushOut:
|
|
return "push-out";
|
|
case LineBreakStrategy::HangulWordPriority:
|
|
return "hangul-word";
|
|
case LineBreakStrategy::Standard:
|
|
return "standard";
|
|
}
|
|
LOG(ERROR) << "Unsupported LineBreakStrategy value";
|
|
return "none";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
LineBreakMode& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "wordWrapping") {
|
|
result = LineBreakMode::Word;
|
|
} else if (string == "char") {
|
|
result = LineBreakMode::Char;
|
|
} else if (string == "clip") {
|
|
result = LineBreakMode::Clip;
|
|
} else if (string == "head") {
|
|
result = LineBreakMode::Head;
|
|
} else if (string == "middle") {
|
|
result = LineBreakMode::Middle;
|
|
} else if (string == "tail") {
|
|
result = LineBreakMode::Tail;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported LineBreakStrategy value: " << string;
|
|
react_native_expect(false);
|
|
result = LineBreakMode::Word;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported LineBreakStrategy type";
|
|
result = LineBreakMode::Word;
|
|
}
|
|
inline std::string toString(const LineBreakMode& lineBreakMode) {
|
|
switch (lineBreakMode) {
|
|
case LineBreakMode::Word:
|
|
return "wordWrapping";
|
|
case LineBreakMode::Char:
|
|
return "char";
|
|
case LineBreakMode::Clip:
|
|
return "clip";
|
|
case LineBreakMode::Head:
|
|
return "head";
|
|
case LineBreakMode::Middle:
|
|
return "middle";
|
|
case LineBreakMode::Tail:
|
|
return "tail";
|
|
}
|
|
LOG(ERROR) << "Unsupported LineBreakStrategy value";
|
|
return "wordWrapping";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextDecorationLineType& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = TextDecorationLineType::None;
|
|
} else if (string == "underline") {
|
|
result = TextDecorationLineType::Underline;
|
|
} else if (string == "strikethrough" || string == "line-through") {
|
|
result = TextDecorationLineType::Strikethrough;
|
|
} else if (
|
|
string == "underline-strikethrough" ||
|
|
string == "underline line-through") {
|
|
result = TextDecorationLineType::UnderlineStrikethrough;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported TextDecorationLineType value: " << string;
|
|
react_native_expect(false);
|
|
result = TextDecorationLineType::None;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported TextDecorationLineType type";
|
|
result = TextDecorationLineType::None;
|
|
}
|
|
inline std::string toString(
|
|
const TextDecorationLineType& textDecorationLineType) {
|
|
switch (textDecorationLineType) {
|
|
case TextDecorationLineType::None:
|
|
return "none";
|
|
case TextDecorationLineType::Underline:
|
|
return "underline";
|
|
case TextDecorationLineType::Strikethrough:
|
|
return "strikethrough";
|
|
case TextDecorationLineType::UnderlineStrikethrough:
|
|
return "underline-strikethrough";
|
|
}
|
|
LOG(ERROR) << "Unsupported TextDecorationLineType value";
|
|
react_native_expect(false);
|
|
return "none";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextDecorationStyle& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "solid") {
|
|
result = TextDecorationStyle::Solid;
|
|
} else if (string == "double") {
|
|
result = TextDecorationStyle::Double;
|
|
} else if (string == "dotted") {
|
|
result = TextDecorationStyle::Dotted;
|
|
} else if (string == "dashed") {
|
|
result = TextDecorationStyle::Dashed;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported TextDecorationStyle value: " << string;
|
|
react_native_expect(false);
|
|
result = TextDecorationStyle::Solid;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported TextDecorationStyle type";
|
|
result = TextDecorationStyle::Solid;
|
|
}
|
|
inline std::string toString(const TextDecorationStyle& textDecorationStyle) {
|
|
switch (textDecorationStyle) {
|
|
case TextDecorationStyle::Solid:
|
|
return "solid";
|
|
case TextDecorationStyle::Double:
|
|
return "double";
|
|
case TextDecorationStyle::Dotted:
|
|
return "dotted";
|
|
case TextDecorationStyle::Dashed:
|
|
return "dashed";
|
|
}
|
|
LOG(ERROR) << "Unsupported TextDecorationStyle value";
|
|
react_native_expect(false);
|
|
return "solid";
|
|
}
|
|
inline std::string toString(const HyphenationFrequency& hyphenationFrequency) {
|
|
switch (hyphenationFrequency) {
|
|
case HyphenationFrequency::None:
|
|
return "none";
|
|
case HyphenationFrequency::Normal:
|
|
return "normal";
|
|
case HyphenationFrequency::Full:
|
|
return "full";
|
|
}
|
|
LOG(ERROR) << "Unsupported HyphenationFrequency value";
|
|
react_native_expect(false);
|
|
return "none";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
HyphenationFrequency& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = HyphenationFrequency::None;
|
|
} else if (string == "normal") {
|
|
result = HyphenationFrequency::Normal;
|
|
} else if (string == "full") {
|
|
result = HyphenationFrequency::Full;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported HyphenationFrequency value: " << string;
|
|
react_native_expect(false);
|
|
result = HyphenationFrequency::None;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported HyphenationFrequency type";
|
|
react_native_expect(false);
|
|
result = HyphenationFrequency::None;
|
|
}
|
|
inline ParagraphAttributes convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const ParagraphAttributes& sourceParagraphAttributes,
|
|
const ParagraphAttributes& defaultParagraphAttributes) {
|
|
auto paragraphAttributes = ParagraphAttributes{};
|
|
paragraphAttributes.maximumNumberOfLines = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"numberOfLines",
|
|
sourceParagraphAttributes.maximumNumberOfLines,
|
|
defaultParagraphAttributes.maximumNumberOfLines);
|
|
paragraphAttributes.ellipsizeMode = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"ellipsizeMode",
|
|
sourceParagraphAttributes.ellipsizeMode,
|
|
defaultParagraphAttributes.ellipsizeMode);
|
|
paragraphAttributes.textBreakStrategy = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"textBreakStrategy",
|
|
sourceParagraphAttributes.textBreakStrategy,
|
|
defaultParagraphAttributes.textBreakStrategy);
|
|
paragraphAttributes.adjustsFontSizeToFit = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"adjustsFontSizeToFit",
|
|
sourceParagraphAttributes.adjustsFontSizeToFit,
|
|
defaultParagraphAttributes.adjustsFontSizeToFit);
|
|
paragraphAttributes.minimumFontScale = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"minimumFontScale",
|
|
sourceParagraphAttributes.minimumFontScale,
|
|
defaultParagraphAttributes.minimumFontScale);
|
|
paragraphAttributes.minimumFontSize = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"minimumFontSize",
|
|
sourceParagraphAttributes.minimumFontSize,
|
|
defaultParagraphAttributes.minimumFontSize);
|
|
paragraphAttributes.maximumFontSize = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"maximumFontSize",
|
|
sourceParagraphAttributes.maximumFontSize,
|
|
defaultParagraphAttributes.maximumFontSize);
|
|
paragraphAttributes.includeFontPadding = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"includeFontPadding",
|
|
sourceParagraphAttributes.includeFontPadding,
|
|
defaultParagraphAttributes.includeFontPadding);
|
|
paragraphAttributes.android_hyphenationFrequency = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"android_hyphenationFrequency",
|
|
sourceParagraphAttributes.android_hyphenationFrequency,
|
|
defaultParagraphAttributes.android_hyphenationFrequency);
|
|
paragraphAttributes.textAlignVertical = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"textAlignVertical",
|
|
sourceParagraphAttributes.textAlignVertical,
|
|
defaultParagraphAttributes.textAlignVertical);
|
|
return paragraphAttributes;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AttributedString::Range& result) {
|
|
auto map = (std::unordered_map<std::string, int>)value;
|
|
auto start = map.find("start");
|
|
if (start != map.end()) {
|
|
result.location = start->second;
|
|
}
|
|
auto end = map.find("end");
|
|
if (end != map.end()) {
|
|
result.length = start->second - result.location;
|
|
}
|
|
}
|
|
inline std::string toString(const AttributedString::Range& range) {
|
|
return "{location: " + std::to_string(range.location) +
|
|
", length: " + std::to_string(range.length) + "}";
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/attributedstring/primitives.h}:
|
|
namespace facebook::react {
|
|
enum class FontStyle { Normal, Italic, Oblique };
|
|
enum class FontWeight : int {
|
|
Weight100 = 100,
|
|
UltraLight = 100,
|
|
Weight200 = 200,
|
|
Thin = 200,
|
|
Weight300 = 300,
|
|
Light = 300,
|
|
Weight400 = 400,
|
|
Regular = 400,
|
|
Weight500 = 500,
|
|
Medium = 500,
|
|
Weight600 = 600,
|
|
Semibold = 600,
|
|
Demibold = 600,
|
|
Weight700 = 700,
|
|
Bold = 700,
|
|
Weight800 = 800,
|
|
Heavy = 800,
|
|
Weight900 = 900,
|
|
Black = 900
|
|
};
|
|
enum class FontVariant : int {
|
|
Default = 0,
|
|
SmallCaps = 1 << 1,
|
|
OldstyleNums = 1 << 2,
|
|
LiningNums = 1 << 3,
|
|
TabularNums = 1 << 4,
|
|
ProportionalNums = 1 << 5,
|
|
StylisticOne = 1 << 6,
|
|
StylisticTwo = 1 << 7,
|
|
StylisticThree = 1 << 8,
|
|
StylisticFour = 1 << 9,
|
|
StylisticFive = 1 << 10,
|
|
StylisticSix = 1 << 11,
|
|
StylisticSeven = 1 << 12,
|
|
StylisticEight = 1 << 13,
|
|
StylisticNine = 1 << 14,
|
|
StylisticTen = 1 << 15,
|
|
StylisticEleven = 1 << 16,
|
|
StylisticTwelve = 1 << 17,
|
|
StylisticThirteen = 1 << 18,
|
|
StylisticFourteen = 1 << 19,
|
|
StylisticFifteen = 1 << 20,
|
|
StylisticSixteen = 1 << 21,
|
|
StylisticSeventeen = 1 << 22,
|
|
StylisticEighteen = 1 << 23,
|
|
StylisticNineteen = 1 << 24,
|
|
StylisticTwenty = 1 << 25
|
|
};
|
|
enum class DynamicTypeRamp {
|
|
Caption2,
|
|
Caption1,
|
|
Footnote,
|
|
Subheadline,
|
|
Callout,
|
|
Body,
|
|
Headline,
|
|
Title3,
|
|
Title2,
|
|
Title1,
|
|
LargeTitle
|
|
};
|
|
enum class EllipsizeMode { Clip, Head, Tail, Middle };
|
|
enum class TextBreakStrategy { Simple, HighQuality, Balanced };
|
|
enum class TextAlignment { Natural, Left, Center, Right, Justified };
|
|
enum class TextAlignmentVertical {
|
|
Auto,
|
|
Top,
|
|
Bottom,
|
|
Center,
|
|
};
|
|
enum class WritingDirection { Natural, LeftToRight, RightToLeft };
|
|
enum class LineBreakStrategy { None, PushOut, HangulWordPriority, Standard };
|
|
enum class LineBreakMode { Word, Char, Clip, Head, Middle, Tail };
|
|
enum class TextDecorationLineType {
|
|
None,
|
|
Underline,
|
|
Strikethrough,
|
|
UnderlineStrikethrough
|
|
};
|
|
enum class TextDecorationStyle { Solid, Double, Dotted, Dashed };
|
|
enum class TextTransform {
|
|
None,
|
|
Uppercase,
|
|
Lowercase,
|
|
Capitalize,
|
|
Unset,
|
|
};
|
|
enum class HyphenationFrequency { None, Normal, Full };
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/bridging/bridging.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<std::shared_ptr<const ShadowNode>> {
|
|
static std::shared_ptr<const ShadowNode> fromJs(
|
|
jsi::Runtime& rt,
|
|
const jsi::Value& jsiValue) {
|
|
auto object = jsiValue.asObject(rt);
|
|
if (!object.hasNativeState<jsi::NativeState>(rt)) {
|
|
throw jsi::JSINativeException("Value is not a ShadowNode reference");
|
|
}
|
|
auto nativeState = object.getNativeState<jsi::NativeState>(rt);
|
|
auto shadowNodeWrapper =
|
|
std::dynamic_pointer_cast<ShadowNodeWrapper>(nativeState);
|
|
if (shadowNodeWrapper == nullptr ||
|
|
shadowNodeWrapper->shadowNode == nullptr) {
|
|
throw jsi::JSINativeException(
|
|
"Value state is nullptr, expected a ShadowNode reference");
|
|
}
|
|
return shadowNodeWrapper->shadowNode;
|
|
}
|
|
static jsi::Value toJs(
|
|
jsi::Runtime& rt,
|
|
const std::shared_ptr<const ShadowNode>& value) {
|
|
jsi::Object obj(rt);
|
|
obj.setNativeState(rt, std::make_shared<ShadowNodeWrapper>(value));
|
|
return obj;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorFactory.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h}
|
|
|
|
namespace facebook::react {
|
|
using ComponentRegistryFactory =
|
|
std::function<SharedComponentDescriptorRegistry(
|
|
const EventDispatcher::Weak& eventDispatcher,
|
|
const std::shared_ptr<const ContextContainer>& contextContainer)>;
|
|
ComponentRegistryFactory getDefaultComponentRegistryFactory();
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProvider.h}:
|
|
namespace facebook::react {
|
|
using ComponentDescriptorConstructor = ComponentDescriptor::Unique(
|
|
const ComponentDescriptorParameters& parameters);
|
|
class ComponentDescriptorProvider final {
|
|
public:
|
|
ComponentHandle handle;
|
|
ComponentName name;
|
|
ComponentDescriptor::Flavor flavor;
|
|
ComponentDescriptorConstructor* constructor;
|
|
};
|
|
template <typename ComponentDescriptorT>
|
|
ComponentDescriptor::Unique concreteComponentDescriptorConstructor(
|
|
const ComponentDescriptorParameters& parameters) {
|
|
static_assert(
|
|
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
|
|
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
|
|
return std::make_unique<const ComponentDescriptorT>(parameters);
|
|
}
|
|
template <typename ComponentDescriptorT>
|
|
ComponentDescriptorProvider concreteComponentDescriptorProvider() {
|
|
static_assert(
|
|
std::is_base_of<ComponentDescriptor, ComponentDescriptorT>::value,
|
|
"ComponentDescriptorT must be a descendant of ComponentDescriptor");
|
|
return {
|
|
ComponentDescriptorT::ConcreteShadowNode::Handle(),
|
|
ComponentDescriptorT::ConcreteShadowNode::Name(),
|
|
nullptr,
|
|
&concreteComponentDescriptorConstructor<ComponentDescriptorT>};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorProviderRegistry.h}:
|
|
namespace facebook::react {
|
|
using ComponentDescriptorProviderRequest =
|
|
std::function<void(ComponentName componentName)>;
|
|
class ComponentDescriptorProviderRegistry final {
|
|
public:
|
|
void add(const ComponentDescriptorProvider& provider) const;
|
|
void setComponentDescriptorProviderRequest(
|
|
ComponentDescriptorProviderRequest request) const;
|
|
ComponentDescriptorRegistry::Shared createComponentDescriptorRegistry(
|
|
const ComponentDescriptorParameters& parameters) const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/componentregistry/ComponentDescriptorRegistry.h}:
|
|
namespace facebook::react {
|
|
using SharedComponentDescriptorRegistry =
|
|
std::shared_ptr<const ComponentDescriptorRegistry>;
|
|
class ComponentDescriptorRegistry {
|
|
public:
|
|
using Shared = std::shared_ptr<const ComponentDescriptorRegistry>;
|
|
ComponentDescriptorRegistry(
|
|
ComponentDescriptorParameters parameters,
|
|
const ComponentDescriptorProviderRegistry& providerRegistry,
|
|
std::shared_ptr<const ContextContainer> contextContainer);
|
|
const ComponentDescriptor*
|
|
findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
|
|
ComponentHandle componentHandle) const;
|
|
const ComponentDescriptor& at(const std::string& componentName) const;
|
|
const ComponentDescriptor& at(ComponentHandle componentHandle) const;
|
|
bool hasComponentDescriptorAt(ComponentHandle componentHandle) const;
|
|
void setFallbackComponentDescriptor(
|
|
const SharedComponentDescriptor& descriptor);
|
|
ComponentDescriptor::Shared getFallbackComponentDescriptor() const;
|
|
};
|
|
const ComponentDescriptorProviderRegistry& providerRegistry_;
|
|
std::shared_ptr<const ContextContainer> contextContainer_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/componentregistry/componentNameByReactViewName.h}:
|
|
namespace facebook::react {
|
|
std::string componentNameByReactViewName(std::string viewName);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/componentregistry/native/NativeComponentRegistryBinding.h}:
|
|
namespace facebook::react {
|
|
using HasComponentProviderFunctionType =
|
|
std::function<bool(const std::string& name)>;
|
|
void bindHasComponentProvider(
|
|
jsi::Runtime& runtime,
|
|
HasComponentProviderFunctionType&& provider);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/image/ImageComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
extern const char ImageManagerKey[];
|
|
class ImageComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<ImageShadowNode> {
|
|
public:
|
|
explicit ImageComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters);
|
|
void adopt(ShadowNode& shadowNode) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/image/ImageEventEmitter.h}:
|
|
namespace facebook::react {
|
|
class ImageEventEmitter : public ViewEventEmitter {
|
|
public:
|
|
using ViewEventEmitter::ViewEventEmitter;
|
|
void onLoadStart() const;
|
|
void onLoad(const ImageSource& source) const;
|
|
void onLoadEnd() const;
|
|
void onProgress(double progress, int64_t loaded, int64_t total) const;
|
|
void onError(const ImageErrorInfo& error) const;
|
|
void onPartialLoad() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/image/ImageProps.h}:
|
|
namespace facebook::react {
|
|
class ImageProps final : public ViewProps {
|
|
public:
|
|
ImageProps() = default;
|
|
ImageProps(
|
|
const PropsParserContext& context,
|
|
const ImageProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
ImageSources sources{};
|
|
ImageSource defaultSource{};
|
|
ImageSource loadingIndicatorSource{};
|
|
ImageResizeMode resizeMode{ImageResizeMode::Stretch};
|
|
Float blurRadius{};
|
|
EdgeInsets capInsets{};
|
|
SharedColor tintColor{};
|
|
std::string internal_analyticTag{};
|
|
std::string resizeMethod{};
|
|
Float resizeMultiplier{};
|
|
bool shouldNotifyLoadEvents{};
|
|
SharedColor overlayColor{};
|
|
Float fadeDuration{};
|
|
bool progressiveRenderingEnabled{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/image/ImageShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char ImageComponentName[];
|
|
class ImageShadowNode final : public ConcreteViewShadowNode<
|
|
ImageComponentName,
|
|
ImageProps,
|
|
ImageEventEmitter,
|
|
ImageState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
return traits;
|
|
}
|
|
void setImageManager(const std::shared_ptr<ImageManager>& imageManager);
|
|
static ImageState initialStateData(
|
|
const Props::Shared& props,
|
|
const ShadowNodeFamily::Shared&,
|
|
const ComponentDescriptor& componentDescriptor) {
|
|
auto imageSource = ImageSource{ImageSource::Type::Invalid};
|
|
return {imageSource, {imageSource, nullptr}, {}};
|
|
}
|
|
void layout(LayoutContext layoutContext) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/image/ImageState.h}:
|
|
namespace facebook::react {
|
|
class ImageState final {
|
|
public:
|
|
ImageState(
|
|
const ImageSource& imageSource,
|
|
ImageRequest imageRequest,
|
|
const ImageRequestParams& imageRequestParams)
|
|
: imageSource_(imageSource),
|
|
imageRequest_(std::make_shared<ImageRequest>(std::move(imageRequest))),
|
|
imageRequestParams_(imageRequestParams) {}
|
|
ImageSource getImageSource() const;
|
|
const ImageRequest& getImageRequest() const;
|
|
const ImageRequestParams& getImageRequestParams() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/image/conversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ImageSource& result) {
|
|
if (value.hasType<std::string>()) {
|
|
result = {
|
|
ImageSource::Type::Remote,
|
|
(std::string)value,
|
|
};
|
|
return;
|
|
}
|
|
if (value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto items = (std::unordered_map<std::string, RawValue>)value;
|
|
result = {};
|
|
result.type = ImageSource::Type::Remote;
|
|
if (items.find("__packager_asset") != items.end()) {
|
|
result.type = ImageSource::Type::Local;
|
|
}
|
|
if (items.find("width") != items.end() &&
|
|
items.find("height") != items.end() &&
|
|
items.at("width").hasType<Float>() &&
|
|
items.at("height").hasType<Float>()) {
|
|
result.size = {(Float)items.at("width"), (Float)items.at("height")};
|
|
}
|
|
if (items.find("scale") != items.end() &&
|
|
items.at("scale").hasType<Float>()) {
|
|
result.scale = (Float)items.at("scale");
|
|
} else {
|
|
result.scale = items.find("deprecated") != items.end() ? 0.0f : 1.0f;
|
|
}
|
|
if (items.find("url") != items.end() &&
|
|
items.at("url").hasType<std::string>()) {
|
|
result.uri = (std::string)items.at("url");
|
|
}
|
|
if (items.find("uri") != items.end() &&
|
|
items.at("uri").hasType<std::string>()) {
|
|
result.uri = (std::string)items.at("uri");
|
|
}
|
|
if (items.find("bundle") != items.end() &&
|
|
items.at("bundle").hasType<std::string>()) {
|
|
result.bundle = (std::string)items.at("bundle");
|
|
result.type = ImageSource::Type::Local;
|
|
}
|
|
if (items.find("headers") != items.end() &&
|
|
items.at("headers")
|
|
.hasType<std::unordered_map<std::string, std::string>>()) {
|
|
auto headers =
|
|
(std::unordered_map<std::string, std::string>)items.at("headers");
|
|
for (const auto& header : headers) {
|
|
result.headers.push_back(header);
|
|
}
|
|
}
|
|
if (items.find("body") != items.end() &&
|
|
items.at("body").hasType<std::string>()) {
|
|
result.body = (std::string)items.at("body");
|
|
}
|
|
if (items.find("method") != items.end() &&
|
|
items.at("method").hasType<std::string>()) {
|
|
result.method = (std::string)items.at("method");
|
|
}
|
|
if (items.find("cache") != items.end() &&
|
|
items.at("cache").hasType<std::string>()) {
|
|
auto cache = (std::string)items.at("cache");
|
|
if (cache == "reload") {
|
|
result.cache = ImageSource::CacheStategy::Reload;
|
|
} else if (cache == "force-cache") {
|
|
result.cache = ImageSource::CacheStategy::ForceCache;
|
|
} else if (cache == "only-if-cached") {
|
|
result.cache = ImageSource::CacheStategy::OnlyIfCached;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
result = {};
|
|
result.type = ImageSource::Type::Invalid;
|
|
}
|
|
inline std::string toString(const ImageSource& value) {
|
|
return "{uri: " + value.uri + "}";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ImageResizeMode& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
LOG(ERROR) << "Unsupported ImageResizeMode type";
|
|
result = ImageResizeMode::Cover;
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "cover") {
|
|
result = ImageResizeMode::Cover;
|
|
} else if (stringValue == "contain") {
|
|
result = ImageResizeMode::Contain;
|
|
} else if (stringValue == "stretch") {
|
|
result = ImageResizeMode::Stretch;
|
|
} else if (stringValue == "center") {
|
|
result = ImageResizeMode::Center;
|
|
} else if (stringValue == "repeat") {
|
|
result = ImageResizeMode::Repeat;
|
|
} else if (stringValue == "none") {
|
|
result = ImageResizeMode::None;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported ImageResizeMode value: " << stringValue;
|
|
react_native_expect(false);
|
|
result = ImageResizeMode::Cover;
|
|
}
|
|
}
|
|
inline std::string toString(const ImageResizeMode& value) {
|
|
switch (value) {
|
|
case ImageResizeMode::Cover:
|
|
return "cover";
|
|
case ImageResizeMode::Contain:
|
|
return "contain";
|
|
case ImageResizeMode::Stretch:
|
|
return "stretch";
|
|
case ImageResizeMode::Center:
|
|
return "center";
|
|
case ImageResizeMode::Repeat:
|
|
return "repeat";
|
|
case ImageResizeMode::None:
|
|
return "none";
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class InputAccessoryComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<InputAccessoryShadowNode> {
|
|
public:
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
auto& layoutableShadowNode =
|
|
static_cast<YogaLayoutableShadowNode&>(shadowNode);
|
|
auto& stateData =
|
|
static_cast<const InputAccessoryShadowNode::ConcreteState&>(
|
|
*shadowNode.getState())
|
|
.getData();
|
|
layoutableShadowNode.setSize(
|
|
Size{stateData.viewportSize.width, stateData.viewportSize.height});
|
|
layoutableShadowNode.setPositionType(YGPositionTypeAbsolute);
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char InputAccessoryComponentName[];
|
|
class InputAccessoryShadowNode final : public ConcreteViewShadowNode<
|
|
InputAccessoryComponentName,
|
|
InputAccessoryProps,
|
|
InputAccessoryEventEmitter,
|
|
InputAccessoryState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
|
|
return traits;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/inputaccessory/InputAccessoryState.h}:
|
|
namespace facebook::react {
|
|
class InputAccessoryState final {
|
|
public:
|
|
InputAccessoryState() {};
|
|
InputAccessoryState(Size viewportSize_) : viewportSize(viewportSize_) {};
|
|
const Size viewportSize{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class LegacyViewManagerInteropComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<LegacyViewManagerInteropShadowNode> {
|
|
public:
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
LegacyViewManagerInteropComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters);
|
|
ComponentHandle getComponentHandle() const override;
|
|
ComponentName getComponentName() const override;
|
|
|
|
protected:
|
|
void adopt(ShadowNode& shadowNode) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char LegacyViewManagerInteropComponentName[];
|
|
using LegacyViewManagerInteropShadowNode = ConcreteViewShadowNode<
|
|
LegacyViewManagerInteropComponentName,
|
|
LegacyViewManagerInteropViewProps,
|
|
ViewEventEmitter,
|
|
LegacyViewManagerInteropState>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropState.h}:
|
|
namespace facebook::react {
|
|
class LegacyViewManagerInteropState final {
|
|
public:
|
|
std::shared_ptr<void> coordinator;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/LegacyViewManagerInteropViewProps.h}:
|
|
namespace facebook::react {
|
|
class LegacyViewManagerInteropViewProps final : public ViewProps {
|
|
public:
|
|
LegacyViewManagerInteropViewProps() = default;
|
|
LegacyViewManagerInteropViewProps(
|
|
const PropsParserContext& context,
|
|
const LegacyViewManagerInteropViewProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
const folly::dynamic otherProps;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/RCTLegacyViewManagerInteropCoordinator.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef void (^InterceptorBlock)(std::string eventName, folly::dynamic &&event);
|
|
@interface RCTLegacyViewManagerInteropCoordinator : NSObject
|
|
- (instancetype)initWithComponentData:(RCTComponentData *)componentData
|
|
bridge:(nullable RCTBridge *)bridge
|
|
bridgeProxy:(nullable RCTBridgeProxy *)bridgeProxy
|
|
bridgelessInteropData:(RCTBridgeModuleDecorator *)bridgelessInteropData;
|
|
- (UIView *)createPaperViewWithTag:(NSInteger)tag;
|
|
- (void)addObserveForTag:(NSInteger)tag usingBlock:(InterceptorBlock)block;
|
|
- (void)removeObserveForTag:(NSInteger)tag;
|
|
- (void)setProps:(NSDictionary<NSString *, id> *)props forView:(UIView *)view;
|
|
- (NSString *)componentViewName;
|
|
- (void)handleCommand:(NSString *)commandName
|
|
args:(NSArray *)args
|
|
reactTag:(NSInteger)tag
|
|
paperView:(UIView *)paperView;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/UnstableLegacyViewManagerAutomaticComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class UnstableLegacyViewManagerAutomaticComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<
|
|
LegacyViewManagerAndroidInteropShadowNode> {
|
|
public:
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
UnstableLegacyViewManagerAutomaticComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters,
|
|
std::string legacyComponentName)
|
|
: ConcreteComponentDescriptor(parameters),
|
|
legacyComponentName_(std::move(legacyComponentName)) {}
|
|
ComponentHandle getComponentHandle() const override;
|
|
ComponentName getComponentName() const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/UnstableLegacyViewManagerAutomaticShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char LegacyViewManagerAndroidInteropComponentName[];
|
|
using LegacyViewManagerAndroidInteropShadowNode = ConcreteViewShadowNode<
|
|
LegacyViewManagerAndroidInteropComponentName,
|
|
LegacyViewManagerInteropViewProps>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/legacyviewmanagerinterop/UnstableLegacyViewManagerInteropComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
template <const char* concreteComponentName>
|
|
class UnstableLegacyViewManagerInteropComponentDescriptor
|
|
: public ConcreteComponentDescriptor<
|
|
ConcreteViewShadowNode<concreteComponentName, ViewProps>> {
|
|
public:
|
|
UnstableLegacyViewManagerInteropComponentDescriptor<concreteComponentName>(
|
|
const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor<
|
|
ConcreteViewShadowNode<concreteComponentName, ViewProps>>(
|
|
parameters) {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class ModalHostViewComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<ModalHostViewShadowNode> {
|
|
public:
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
auto& layoutableShadowNode =
|
|
static_cast<YogaLayoutableShadowNode&>(shadowNode);
|
|
auto& stateData =
|
|
static_cast<const ModalHostViewShadowNode::ConcreteState&>(
|
|
*shadowNode.getState())
|
|
.getData();
|
|
layoutableShadowNode.setSize(Size{
|
|
.width = stateData.screenSize.width,
|
|
.height = stateData.screenSize.height});
|
|
layoutableShadowNode.setPositionType(YGPositionTypeAbsolute);
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char ModalHostViewComponentName[];
|
|
class ModalHostViewShadowNode final : public ConcreteViewShadowNode<
|
|
ModalHostViewComponentName,
|
|
ModalHostViewProps,
|
|
ModalHostViewEventEmitter,
|
|
ModalHostViewState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
|
|
traits.set(ShadowNodeTraits::Trait::Unstable_uncullableView);
|
|
return traits;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewState.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.h}
|
|
namespace facebook::react {
|
|
class ModalHostViewState final {
|
|
public:
|
|
using Shared = std::shared_ptr<const ModalHostViewState>;
|
|
ModalHostViewState() : screenSize(ModalHostViewScreenSize()) {}
|
|
ModalHostViewState(Size screenSize_) : screenSize(screenSize_) {};
|
|
const Size screenSize{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/modal/ModalHostViewUtils.h}:
|
|
namespace facebook::react {
|
|
Size ModalHostViewScreenSize(void);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/modal/platform/android/JReactModalHostView.h}:
|
|
namespace facebook::react {
|
|
class JReactModalHostView
|
|
: public facebook::jni::JavaClass<JReactModalHostView> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/views/modal/ReactModalHostView;";
|
|
static Size getDisplayMetrics() {
|
|
static auto method =
|
|
JReactModalHostView::javaClassStatic()->getStaticMethod<jlong()>(
|
|
"getScreenDisplayMetricsWithoutInsets");
|
|
auto result = method(javaClassStatic());
|
|
int32_t wBits = 0xFFFFFFFF & (result >> 32);
|
|
int32_t hBits = 0xFFFFFFFF & result;
|
|
auto* measuredWidth = reinterpret_cast<float*>(&wBits);
|
|
auto* measuredHeight = reinterpret_cast<float*>(&hBits);
|
|
return Size{.width = *measuredWidth, .height = *measuredHeight};
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/AndroidProgressBarComponentDescriptor.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/AndroidProgressBarMeasurementsManager.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/AndroidProgressBarShadowNode.h}
|
|
|
|
namespace facebook::react {
|
|
class AndroidProgressBarComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<AndroidProgressBarShadowNode> {
|
|
public:
|
|
AndroidProgressBarComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor(parameters),
|
|
measurementsManager_(
|
|
std::make_shared<AndroidProgressBarMeasurementsManager>(
|
|
contextContainer_)) {}
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
auto& androidProgressBarShadowNode =
|
|
static_cast<AndroidProgressBarShadowNode&>(shadowNode);
|
|
androidProgressBarShadowNode.setAndroidProgressBarMeasurementsManager(
|
|
measurementsManager_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/AndroidProgressBarMeasurementsManager.h}:
|
|
namespace facebook::react {
|
|
class AndroidProgressBarMeasurementsManager {
|
|
public:
|
|
AndroidProgressBarMeasurementsManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer)
|
|
: contextContainer_(contextContainer) {}
|
|
Size measure(
|
|
SurfaceId surfaceId,
|
|
const AndroidProgressBarProps& props,
|
|
LayoutConstraints layoutConstraints) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/AndroidProgressBarShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char AndroidProgressBarComponentName[];
|
|
class AndroidProgressBarShadowNode final : public ConcreteViewShadowNode<
|
|
AndroidProgressBarComponentName,
|
|
AndroidProgressBarProps,
|
|
AndroidProgressBarEventEmitter> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
return traits;
|
|
}
|
|
void setAndroidProgressBarMeasurementsManager(
|
|
const std::shared_ptr<AndroidProgressBarMeasurementsManager>&
|
|
measurementsManager);
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/conversions.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/text/conversions.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/rncore/ComponentDescriptors.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/rncore/EventEmitters.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/rncore/Props.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/rncore/ShadowNodes.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/rncore/States.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/root/RootComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using RootComponentDescriptor = ConcreteComponentDescriptor<RootShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/root/RootProps.h}:
|
|
namespace facebook::react {
|
|
class RootProps final : public ViewProps {
|
|
public:
|
|
RootProps() = default;
|
|
RootProps(
|
|
const PropsParserContext& context,
|
|
const RootProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
RootProps(
|
|
const PropsParserContext& context,
|
|
const RootProps& sourceProps,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext);
|
|
LayoutConstraints layoutConstraints{};
|
|
LayoutContext layoutContext{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/root/RootShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char RootComponentName[];
|
|
class RootShadowNode final
|
|
: public ConcreteViewShadowNode<RootComponentName, RootProps> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
using Shared = std::shared_ptr<const RootShadowNode>;
|
|
using Unshared = std::shared_ptr<RootShadowNode>;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::RootNodeKind);
|
|
return traits;
|
|
}
|
|
bool layoutIfNeeded(
|
|
std::vector<const LayoutableShadowNode*>* affectedNodes = {});
|
|
RootShadowNode::Unshared clone(
|
|
const PropsParserContext& propsParserContext,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext) const;
|
|
Transform getTransform() const override;
|
|
void setInstanceHandle(InstanceHandle::Shared instanceHandle) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/safeareaview/SafeAreaViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class SafeAreaViewComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<SafeAreaViewShadowNode> {
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
auto& layoutableShadowNode =
|
|
static_cast<YogaLayoutableShadowNode&>(shadowNode);
|
|
auto& stateData = static_cast<const SafeAreaViewShadowNode::ConcreteState&>(
|
|
*shadowNode.getState())
|
|
.getData();
|
|
layoutableShadowNode.setPadding(stateData.padding);
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/safeareaview/SafeAreaViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char SafeAreaViewComponentName[];
|
|
class SafeAreaViewShadowNode final : public ConcreteViewShadowNode<
|
|
SafeAreaViewComponentName,
|
|
SafeAreaViewProps,
|
|
ViewEventEmitter,
|
|
SafeAreaViewState> {
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/safeareaview/SafeAreaViewState.h}:
|
|
namespace facebook::react {
|
|
class SafeAreaViewState final {
|
|
public:
|
|
EdgeInsets padding{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/BaseScrollViewProps.h}:
|
|
namespace facebook::react {
|
|
class BaseScrollViewProps : public ViewProps {
|
|
public:
|
|
BaseScrollViewProps() = default;
|
|
BaseScrollViewProps(
|
|
const PropsParserContext& context,
|
|
const BaseScrollViewProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
bool alwaysBounceHorizontal{};
|
|
bool alwaysBounceVertical{};
|
|
bool bounces{true};
|
|
bool bouncesZoom{true};
|
|
bool canCancelContentTouches{true};
|
|
bool centerContent{};
|
|
bool automaticallyAdjustContentInsets{};
|
|
bool automaticallyAdjustsScrollIndicatorInsets{true};
|
|
bool automaticallyAdjustKeyboardInsets{false};
|
|
Float decelerationRate{0.998f};
|
|
Float endDraggingSensitivityMultiplier{1};
|
|
bool directionalLockEnabled{};
|
|
ScrollViewIndicatorStyle indicatorStyle{};
|
|
ScrollViewKeyboardDismissMode keyboardDismissMode{};
|
|
std::optional<ScrollViewMaintainVisibleContentPosition>
|
|
maintainVisibleContentPosition{};
|
|
Float maximumZoomScale{1.0f};
|
|
Float minimumZoomScale{1.0f};
|
|
bool scrollEnabled{true};
|
|
bool pagingEnabled{};
|
|
bool pinchGestureEnabled{true};
|
|
bool scrollsToTop{true};
|
|
bool showsHorizontalScrollIndicator{true};
|
|
bool showsVerticalScrollIndicator{true};
|
|
bool persistentScrollbar{false};
|
|
bool horizontal{false};
|
|
Float scrollEventThrottle{};
|
|
Float zoomScale{1.0f};
|
|
EdgeInsets contentInset{};
|
|
Point contentOffset{};
|
|
EdgeInsets scrollIndicatorInsets{};
|
|
Float snapToInterval{};
|
|
ScrollViewSnapToAlignment snapToAlignment{};
|
|
bool disableIntervalMomentum{false};
|
|
std::vector<Float> snapToOffsets{};
|
|
bool snapToStart{true};
|
|
bool snapToEnd{true};
|
|
ContentInsetAdjustmentBehavior contentInsetAdjustmentBehavior{
|
|
ContentInsetAdjustmentBehavior::Never};
|
|
bool scrollToOverflowEnabled{false};
|
|
bool isInvertedVirtualizedList{false};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/RCTComponentViewHelpers.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@protocol RCTScrollViewProtocol <NSObject>
|
|
- (void)flashScrollIndicators;
|
|
- (void)scrollTo:(double)x y:(double)y animated:(BOOL)animated;
|
|
- (void)scrollToEnd:(BOOL)animated;
|
|
- (void)zoomToRect:(CGRect)rect animated:(BOOL)animated;
|
|
@end
|
|
RCT_EXTERN inline void
|
|
RCTScrollViewHandleCommand(id<RCTScrollViewProtocol> componentView, const NSString *commandName, const NSArray *args)
|
|
{
|
|
if ([commandName isEqualToString:@"flashScrollIndicators"]) {
|
|
[componentView flashScrollIndicators];
|
|
return;
|
|
}
|
|
if ([commandName isEqualToString:@"scrollTo"]) {
|
|
NSObject *arg0 = args[0];
|
|
NSObject *arg1 = args[1];
|
|
NSObject *arg2 = args[2];
|
|
double x = [(NSNumber *)arg0 doubleValue];
|
|
double y = [(NSNumber *)arg1 doubleValue];
|
|
BOOL animated = [(NSNumber *)arg2 boolValue];
|
|
[componentView scrollTo:x y:y animated:animated];
|
|
return;
|
|
}
|
|
if ([commandName isEqualToString:@"scrollToEnd"]) {
|
|
NSObject *arg0 = args[0];
|
|
BOOL animated = [(NSNumber *)arg0 boolValue];
|
|
[componentView scrollToEnd:animated];
|
|
return;
|
|
}
|
|
if ([commandName isEqualToString:@"zoomToRect"]) {
|
|
NSObject *arg0 = args[0];
|
|
NSDictionary *rectDict = (NSDictionary *)arg0;
|
|
NSNumber *x = rectDict[@"x"];
|
|
NSNumber *y = rectDict[@"y"];
|
|
NSNumber *width = rectDict[@"width"];
|
|
NSNumber *height = rectDict[@"height"];
|
|
CGRect rect = CGRectMake(x.doubleValue, y.doubleValue, width.doubleValue, height.doubleValue);
|
|
NSObject *arg1 = args[1];
|
|
BOOL animated = [(NSNumber *)arg1 boolValue];
|
|
[componentView zoomToRect:rect animated:animated];
|
|
return;
|
|
}
|
|
}
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollEvent.h}:
|
|
namespace facebook::react {
|
|
struct ScrollEvent : public EventPayload {
|
|
Size contentSize;
|
|
Point contentOffset;
|
|
EdgeInsets contentInset;
|
|
Size containerSize;
|
|
Float zoomScale{};
|
|
Float timestamp{};
|
|
ScrollEvent() = default;
|
|
folly::dynamic asDynamic() const;
|
|
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
|
|
EventPayloadType getType() const override;
|
|
std::optional<double> extractValue(
|
|
const std::vector<std::string>& path) const override;
|
|
};
|
|
struct ScrollEndDragEvent : public ScrollEvent {
|
|
Point targetContentOffset;
|
|
Point velocity;
|
|
ScrollEndDragEvent() = default;
|
|
ScrollEndDragEvent(const ScrollEvent& scrollEvent)
|
|
: ScrollEvent(scrollEvent), targetContentOffset({}), velocity({}) {}
|
|
folly::dynamic asDynamic() const;
|
|
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using ScrollViewComponentDescriptor =
|
|
ConcreteComponentDescriptor<ScrollViewShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewEventEmitter.h}:
|
|
namespace facebook::react {
|
|
class ScrollViewEventEmitter : public ViewEventEmitter {
|
|
public:
|
|
using ViewEventEmitter::ViewEventEmitter;
|
|
using Metrics = ScrollEvent;
|
|
using EndDragMetrics = ScrollEndDragEvent;
|
|
void onScroll(const ScrollEvent& scrollEvent) const;
|
|
void onScrollBeginDrag(const ScrollEvent& scrollEvent) const;
|
|
void onScrollEndDrag(const ScrollEndDragEvent& scrollEvent) const;
|
|
void onMomentumScrollBegin(const ScrollEvent& scrollEvent) const;
|
|
void onMomentumScrollEnd(const ScrollEvent& scrollEvent) const;
|
|
void onScrollToTop(const ScrollEvent& scrollEvent) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewProps.h}:
|
|
namespace facebook::react {
|
|
using ScrollViewProps = HostPlatformScrollViewProps;
|
|
using SharedScrollViewProps = std::shared_ptr<const ScrollViewProps>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char ScrollViewComponentName[];
|
|
class ScrollViewShadowNode final : public ConcreteViewShadowNode<
|
|
ScrollViewComponentName,
|
|
ScrollViewProps,
|
|
ScrollViewEventEmitter,
|
|
ScrollViewState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ScrollViewState initialStateData(
|
|
const Props::Shared& props,
|
|
const ShadowNodeFamily::Shared& family,
|
|
const ComponentDescriptor& componentDescriptor);
|
|
void layout(LayoutContext layoutContext) override;
|
|
Point getContentOriginOffset(bool includeTransform) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/ScrollViewState.h}:
|
|
namespace facebook::react {
|
|
class ScrollViewState final {
|
|
public:
|
|
ScrollViewState(
|
|
Point contentOffset,
|
|
Rect contentBoundingRect,
|
|
int scrollAwayPaddingTop);
|
|
ScrollViewState() = default;
|
|
Point contentOffset;
|
|
Rect contentBoundingRect;
|
|
int scrollAwayPaddingTop;
|
|
bool disableViewCulling{false};
|
|
Size getContentSize() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/conversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ScrollViewSnapToAlignment& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "start") {
|
|
result = ScrollViewSnapToAlignment::Start;
|
|
return;
|
|
}
|
|
if (string == "center") {
|
|
result = ScrollViewSnapToAlignment::Center;
|
|
return;
|
|
}
|
|
if (string == "end") {
|
|
result = ScrollViewSnapToAlignment::End;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ScrollViewIndicatorStyle& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = ScrollViewIndicatorStyle::Default;
|
|
return;
|
|
}
|
|
if (string == "black") {
|
|
result = ScrollViewIndicatorStyle::Black;
|
|
return;
|
|
}
|
|
if (string == "white") {
|
|
result = ScrollViewIndicatorStyle::White;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ScrollViewKeyboardDismissMode& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = ScrollViewKeyboardDismissMode::None;
|
|
return;
|
|
}
|
|
if (string == "on-drag") {
|
|
result = ScrollViewKeyboardDismissMode::OnDrag;
|
|
return;
|
|
}
|
|
if (string == "interactive") {
|
|
result = ScrollViewKeyboardDismissMode::Interactive;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ContentInsetAdjustmentBehavior& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "never") {
|
|
result = ContentInsetAdjustmentBehavior::Never;
|
|
return;
|
|
}
|
|
if (string == "automatic") {
|
|
result = ContentInsetAdjustmentBehavior::Automatic;
|
|
return;
|
|
}
|
|
if (string == "scrollableAxes") {
|
|
result = ContentInsetAdjustmentBehavior::ScrollableAxes;
|
|
return;
|
|
}
|
|
if (string == "always") {
|
|
result = ContentInsetAdjustmentBehavior::Always;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ScrollViewMaintainVisibleContentPosition& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto minIndexForVisible = map.find("minIndexForVisible");
|
|
if (minIndexForVisible != map.end()) {
|
|
fromRawValue(
|
|
context, minIndexForVisible->second, result.minIndexForVisible);
|
|
}
|
|
auto autoscrollToTopThreshold = map.find("autoscrollToTopThreshold");
|
|
if (autoscrollToTopThreshold != map.end()) {
|
|
fromRawValue(
|
|
context,
|
|
autoscrollToTopThreshold->second,
|
|
result.autoscrollToTopThreshold);
|
|
}
|
|
}
|
|
inline std::string toString(const ScrollViewSnapToAlignment& value) {
|
|
switch (value) {
|
|
case ScrollViewSnapToAlignment::Start:
|
|
return "start";
|
|
case ScrollViewSnapToAlignment::Center:
|
|
return "center";
|
|
case ScrollViewSnapToAlignment::End:
|
|
return "end";
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/platform/android/react/renderer/components/scrollview/AndroidHorizontalScrollContentViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using AndroidHorizontalScrollContentViewComponentDescriptor =
|
|
ConcreteComponentDescriptor<AndroidHorizontalScrollContentViewShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/platform/android/react/renderer/components/scrollview/AndroidHorizontalScrollContentViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char AndroidHorizontalScrollContentViewShadowNodeComponentName[];
|
|
class AndroidHorizontalScrollContentViewShadowNode final
|
|
: public ConcreteViewShadowNode<
|
|
AndroidHorizontalScrollContentViewShadowNodeComponentName,
|
|
ViewProps> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
void layout(LayoutContext layoutContext) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/platform/android/react/renderer/components/scrollview/HostPlatformScrollViewProps.h}:
|
|
namespace facebook::react {
|
|
class HostPlatformScrollViewProps final : public BaseScrollViewProps {
|
|
public:
|
|
HostPlatformScrollViewProps() = default;
|
|
HostPlatformScrollViewProps(
|
|
const PropsParserContext& context,
|
|
const HostPlatformScrollViewProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
bool sendMomentumEvents{};
|
|
bool nestedScrollEnabled{};
|
|
ComponentName getDiffPropsImplementationTarget() const override;
|
|
folly::dynamic getDiffProps(const Props* prevProps) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/platform/cxx/react/renderer/components/scrollview/HostPlatformScrollViewProps.h}:
|
|
namespace facebook::react {
|
|
using HostPlatformScrollViewProps = BaseScrollViewProps;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/scrollview/primitives.h}:
|
|
namespace facebook::react {
|
|
enum class ScrollViewSnapToAlignment { Start, Center, End };
|
|
enum class ScrollViewIndicatorStyle { Default, Black, White };
|
|
enum class ScrollViewKeyboardDismissMode { None, OnDrag, Interactive };
|
|
enum class ContentInsetAdjustmentBehavior {
|
|
Never,
|
|
Automatic,
|
|
ScrollableAxes,
|
|
Always
|
|
};
|
|
class ScrollViewMaintainVisibleContentPosition final {
|
|
public:
|
|
int minIndexForVisible{0};
|
|
std::optional<int> autoscrollToTopThreshold{};
|
|
bool operator==(const ScrollViewMaintainVisibleContentPosition& rhs) const {
|
|
return std::tie(this->minIndexForVisible, this->autoscrollToTopThreshold) ==
|
|
std::tie(rhs.minIndexForVisible, rhs.autoscrollToTopThreshold);
|
|
}
|
|
bool operator!=(const ScrollViewMaintainVisibleContentPosition& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/switch/androidswitch/react/renderer/components/androidswitch/AndroidSwitchComponentDescriptor.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/switch/androidswitch/react/renderer/components/androidswitch/AndroidSwitchMeasurementsManager.h}
|
|
namespace facebook::react {
|
|
extern const char AndroidSwitchComponentName[];
|
|
class AndroidSwitchShadowNode final : public ConcreteViewShadowNode<
|
|
AndroidSwitchComponentName,
|
|
AndroidSwitchProps,
|
|
AndroidSwitchEventEmitter> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
return traits;
|
|
}
|
|
void setAndroidSwitchMeasurementsManager(
|
|
const std::shared_ptr<AndroidSwitchMeasurementsManager>&
|
|
measurementsManager);
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class AndroidSwitchComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<AndroidSwitchShadowNode> {
|
|
public:
|
|
AndroidSwitchComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor(parameters),
|
|
measurementsManager_(std::make_shared<AndroidSwitchMeasurementsManager>(
|
|
contextContainer_)) {}
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
auto& androidSwitchShadowNode =
|
|
static_cast<AndroidSwitchShadowNode&>(shadowNode);
|
|
androidSwitchShadowNode.setAndroidSwitchMeasurementsManager(
|
|
measurementsManager_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/switch/androidswitch/react/renderer/components/androidswitch/AndroidSwitchMeasurementsManager.h}:
|
|
namespace facebook::react {
|
|
class AndroidSwitchMeasurementsManager {
|
|
public:
|
|
AndroidSwitchMeasurementsManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer)
|
|
: contextContainer_(contextContainer) {}
|
|
Size measure(SurfaceId surfaceId, LayoutConstraints layoutConstraints) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/switch/androidswitch/react/renderer/components/androidswitch/AndroidSwitchShadowNode.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/switch/androidswitch/react/renderer/components/androidswitch/AndroidSwitchMeasurementsManager.h}
|
|
namespace facebook::react {
|
|
extern const char AndroidSwitchComponentName[];
|
|
class AndroidSwitchShadowNode final : public ConcreteViewShadowNode<
|
|
AndroidSwitchComponentName,
|
|
AndroidSwitchProps,
|
|
AndroidSwitchEventEmitter> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
return traits;
|
|
}
|
|
void setAndroidSwitchMeasurementsManager(
|
|
const std::shared_ptr<AndroidSwitchMeasurementsManager>&
|
|
measurementsManager);
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/BaseTextProps.h}:
|
|
namespace facebook::react {
|
|
class BaseTextProps {
|
|
public:
|
|
BaseTextProps() = default;
|
|
BaseTextProps(
|
|
const PropsParserContext& context,
|
|
const BaseTextProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
TextAttributes textAttributes{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/BaseTextShadowNode.h}:
|
|
namespace facebook::react {
|
|
class BaseTextShadowNode {
|
|
public:
|
|
class Attachment final {
|
|
public:
|
|
const ShadowNode* shadowNode;
|
|
size_t fragmentIndex;
|
|
};
|
|
using Attachments = std::vector<Attachment>;
|
|
static void buildAttributedString(
|
|
const TextAttributes& baseTextAttributes,
|
|
const ShadowNode& parentNode,
|
|
AttributedString& outAttributedString,
|
|
Attachments& outAttachments);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/ParagraphComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
extern const char TextLayoutManagerKey[];
|
|
class ParagraphComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<ParagraphShadowNode> {
|
|
public:
|
|
explicit ParagraphComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor<ParagraphShadowNode>(parameters),
|
|
textLayoutManager_(getManagerByName<TextLayoutManager>(
|
|
contextContainer_,
|
|
TextLayoutManagerKey)) {}
|
|
|
|
protected:
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
auto& paragraphShadowNode = static_cast<ParagraphShadowNode&>(shadowNode);
|
|
paragraphShadowNode.setTextLayoutManager(textLayoutManager_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/ParagraphEventEmitter.h}:
|
|
namespace facebook::react {
|
|
class ParagraphEventEmitter : public ViewEventEmitter {
|
|
public:
|
|
using ViewEventEmitter::ViewEventEmitter;
|
|
void onTextLayout(const LinesMeasurements& linesMeasurements) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/ParagraphProps.h}:
|
|
namespace facebook::react {
|
|
class ParagraphProps : public ViewProps, public BaseTextProps {
|
|
public:
|
|
ParagraphProps() = default;
|
|
ParagraphProps(
|
|
const PropsParserContext& context,
|
|
const ParagraphProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
ParagraphAttributes paragraphAttributes{};
|
|
bool isSelectable{};
|
|
bool onTextLayout{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/ParagraphShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char ParagraphComponentName[];
|
|
class ParagraphShadowNode final : public ConcreteViewShadowNode<
|
|
ParagraphComponentName,
|
|
ParagraphProps,
|
|
ParagraphEventEmitter,
|
|
ParagraphState>,
|
|
public BaseTextShadowNode {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
ParagraphShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family,
|
|
ShadowNodeTraits traits);
|
|
ParagraphShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment);
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::BaselineYogaNode);
|
|
return traits;
|
|
}
|
|
void setTextLayoutManager(
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager);
|
|
void layout(LayoutContext layoutContext) override;
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override;
|
|
Float baseline(const LayoutContext& layoutContext, Size size) const override;
|
|
class Content final {
|
|
public:
|
|
AttributedString attributedString;
|
|
ParagraphAttributes paragraphAttributes;
|
|
Attachments attachments;
|
|
};
|
|
|
|
protected:
|
|
bool shouldNewRevisionDirtyMeasurement(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment) const override;
|
|
};
|
|
mutable std::vector<MeasuredPreparedLayout> measuredLayouts_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/RawTextComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using RawTextComponentDescriptor =
|
|
ConcreteComponentDescriptor<RawTextShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/RawTextProps.h}:
|
|
namespace facebook::react {
|
|
using SharedRawTextProps = std::shared_ptr<const RawTextProps>;
|
|
class RawTextProps : public Props {
|
|
public:
|
|
RawTextProps() = default;
|
|
RawTextProps(
|
|
const PropsParserContext& context,
|
|
const RawTextProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
std::string text{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/RawTextShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char RawTextComponentName[];
|
|
class RawTextShadowNode : public ConcreteShadowNode<
|
|
RawTextComponentName,
|
|
ShadowNode,
|
|
RawTextProps> {
|
|
public:
|
|
using ConcreteShadowNode::ConcreteShadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/TextComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using TextComponentDescriptor = ConcreteComponentDescriptor<TextShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/TextProps.h}:
|
|
namespace facebook::react {
|
|
class TextProps : public Props, public BaseTextProps {
|
|
public:
|
|
TextProps() = default;
|
|
TextProps(
|
|
const PropsParserContext& context,
|
|
const TextProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/TextShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char TextComponentName[];
|
|
using TextEventEmitter = TouchEventEmitter;
|
|
class TextShadowNode : public ConcreteShadowNode<
|
|
TextComponentName,
|
|
ShadowNode,
|
|
TextProps,
|
|
TextEventEmitter>,
|
|
public BaseTextShadowNode {
|
|
public:
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteShadowNode::BaseTraits();
|
|
return traits;
|
|
}
|
|
using ConcreteShadowNode::ConcreteShadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/conversions.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/conversions.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/platform/android/react/renderer/components/text/ParagraphState.h}:
|
|
namespace facebook::react {
|
|
constexpr static MapBuffer::Key TX_STATE_KEY_ATTRIBUTED_STRING = 0;
|
|
constexpr static MapBuffer::Key TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
|
|
constexpr static MapBuffer::Key TX_STATE_KEY_HASH = 2;
|
|
constexpr static MapBuffer::Key TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
|
|
class ParagraphState final {
|
|
public:
|
|
AttributedString attributedString;
|
|
ParagraphAttributes paragraphAttributes;
|
|
std::weak_ptr<const TextLayoutManager> layoutManager;
|
|
MeasuredPreparedLayout measuredLayout;
|
|
ParagraphState(
|
|
AttributedString attributedString,
|
|
ParagraphAttributes paragraphAttributes,
|
|
std::weak_ptr<const TextLayoutManager> layoutManager,
|
|
MeasuredPreparedLayout measuredLayout)
|
|
: attributedString(std::move(attributedString)),
|
|
paragraphAttributes(std::move(paragraphAttributes)),
|
|
layoutManager(std::move(layoutManager)),
|
|
measuredLayout(std::move(measuredLayout)) {}
|
|
ParagraphState(
|
|
AttributedString attributedString,
|
|
ParagraphAttributes paragraphAttributes,
|
|
std::weak_ptr<const TextLayoutManager> layoutManager)
|
|
: ParagraphState(
|
|
std::move(attributedString),
|
|
std::move(paragraphAttributes),
|
|
std::move(layoutManager),
|
|
{}) {}
|
|
ParagraphState() = default;
|
|
ParagraphState(const ParagraphState&, const folly::dynamic&) {
|
|
react_native_assert(false && "Not supported");
|
|
};
|
|
folly::dynamic getDynamic() const;
|
|
MapBuffer getMapBuffer() const;
|
|
jni::local_ref<jobject> getJNIReference() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/text/platform/cxx/react/renderer/components/text/ParagraphState.h}:
|
|
namespace facebook::react {
|
|
class ParagraphState final {
|
|
public:
|
|
AttributedString attributedString;
|
|
ParagraphAttributes paragraphAttributes;
|
|
std::weak_ptr<const TextLayoutManager> layoutManager;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputProps.h}:
|
|
namespace facebook::react {
|
|
class BaseTextInputProps : public ViewProps, public BaseTextProps {
|
|
public:
|
|
BaseTextInputProps() = default;
|
|
BaseTextInputProps(
|
|
const PropsParserContext& context,
|
|
const BaseTextInputProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
SubmitBehavior getNonDefaultSubmitBehavior() const;
|
|
TextAttributes getEffectiveTextAttributes(Float fontSizeMultiplier) const;
|
|
ParagraphAttributes paragraphAttributes{};
|
|
std::string defaultValue{};
|
|
std::string placeholder{};
|
|
SharedColor placeholderTextColor{};
|
|
SharedColor cursorColor{};
|
|
SharedColor selectionColor{};
|
|
SharedColor selectionHandleColor{};
|
|
SharedColor underlineColorAndroid{};
|
|
int maxLength{};
|
|
std::string text{};
|
|
int mostRecentEventCount{0};
|
|
bool autoFocus{false};
|
|
std::string autoCapitalize{};
|
|
bool editable{true};
|
|
bool readOnly{false};
|
|
SubmitBehavior submitBehavior{SubmitBehavior::Default};
|
|
bool multiline{false};
|
|
bool disableKeyboardShortcuts{false};
|
|
std::optional<std::vector<std::string>> acceptDragAndDropTypes{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/BaseTextInputShadowNode.h}:
|
|
namespace facebook::react {
|
|
template <
|
|
const char* concreteComponentName,
|
|
typename ViewPropsT,
|
|
typename ViewEventEmitterT,
|
|
typename StateDataT>
|
|
class BaseTextInputShadowNode : public ConcreteViewShadowNode<
|
|
concreteComponentName,
|
|
ViewPropsT,
|
|
ViewEventEmitterT,
|
|
StateDataT>,
|
|
public BaseTextShadowNode {
|
|
public:
|
|
using BaseShadowNode = ConcreteViewShadowNode<
|
|
concreteComponentName,
|
|
ViewPropsT,
|
|
ViewEventEmitterT,
|
|
StateDataT>;
|
|
using BaseShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = BaseShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::BaselineYogaNode);
|
|
return traits;
|
|
}
|
|
void setTextLayoutManager(
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager) {
|
|
Sealable::ensureUnsealed();
|
|
textLayoutManager_ = std::move(textLayoutManager);
|
|
}
|
|
|
|
protected:
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override {
|
|
const auto& props = BaseShadowNode::getConcreteProps();
|
|
auto textConstraints = getTextConstraints(layoutConstraints);
|
|
TextLayoutContext textLayoutContext{
|
|
.pointScaleFactor = layoutContext.pointScaleFactor,
|
|
.surfaceId = BaseShadowNode::getSurfaceId(),
|
|
};
|
|
auto textSize = textLayoutManager_
|
|
->measure(
|
|
attributedStringBoxToMeasure(layoutContext),
|
|
props.paragraphAttributes,
|
|
textLayoutContext,
|
|
textConstraints)
|
|
.size;
|
|
return layoutConstraints.clamp(textSize);
|
|
}
|
|
void layout(LayoutContext layoutContext) override {
|
|
updateStateIfNeeded(layoutContext);
|
|
BaseShadowNode::layout(layoutContext);
|
|
}
|
|
Float baseline(const LayoutContext& layoutContext, Size size) const override {
|
|
const auto& props = BaseShadowNode::getConcreteProps();
|
|
auto attributedString = getAttributedString(layoutContext);
|
|
if (attributedString.isEmpty()) {
|
|
attributedString = getPlaceholderAttributedString(layoutContext);
|
|
}
|
|
auto top = YGNodeLayoutGetBorder(
|
|
&(YogaLayoutableShadowNode::yogaNode_), YGEdgeTop) +
|
|
YGNodeLayoutGetPadding(
|
|
&(YogaLayoutableShadowNode::yogaNode_), YGEdgeTop);
|
|
AttributedStringBox attributedStringBox{attributedString};
|
|
if constexpr (TextLayoutManagerExtended::supportsLineMeasurement()) {
|
|
auto lines =
|
|
TextLayoutManagerExtended(*textLayoutManager_)
|
|
.measureLines(
|
|
attributedStringBox, props.paragraphAttributes, size);
|
|
return LineMeasurement::baseline(lines) + top;
|
|
} else {
|
|
LOG(WARNING)
|
|
<< "Baseline alignment is not supported by the current platform";
|
|
return top;
|
|
}
|
|
}
|
|
LayoutConstraints getTextConstraints(
|
|
const LayoutConstraints& layoutConstraints) const {
|
|
if (BaseShadowNode::getConcreteProps().multiline) {
|
|
return layoutConstraints;
|
|
} else {
|
|
return LayoutConstraints{
|
|
.minimumSize = layoutConstraints.minimumSize,
|
|
.maximumSize =
|
|
Size{
|
|
.width = std::numeric_limits<Float>::infinity(),
|
|
.height = layoutConstraints.maximumSize.height,
|
|
},
|
|
.layoutDirection = layoutConstraints.layoutDirection,
|
|
};
|
|
}
|
|
}
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager_;
|
|
};
|
|
BaseTextShadowNode::buildAttributedString(
|
|
textAttributes, *this, attributedString, attachments);
|
|
attributedString.setBaseTextAttributes(textAttributes);
|
|
return attributedString;
|
|
}
|
|
AttributedStringBox attributedStringBoxToMeasure(
|
|
const LayoutContext& layoutContext) const {
|
|
bool meaningfulState = BaseShadowNode::getState() &&
|
|
BaseShadowNode::getState()->getRevision() !=
|
|
State::initialRevisionValue &&
|
|
BaseShadowNode::getStateData()
|
|
.reactTreeAttributedString.getBaseTextAttributes()
|
|
.fontSizeMultiplier == layoutContext.fontSizeMultiplier;
|
|
if (meaningfulState) {
|
|
const auto& stateData = BaseShadowNode::getStateData();
|
|
auto attributedStringBox = stateData.attributedStringBox;
|
|
if (attributedStringBox.getMode() ==
|
|
AttributedStringBox::Mode::OpaquePointer ||
|
|
!attributedStringBox.getValue().isEmpty()) {
|
|
return stateData.attributedStringBox;
|
|
}
|
|
}
|
|
auto attributedString = meaningfulState
|
|
? AttributedString{}
|
|
: getAttributedString(layoutContext);
|
|
if (attributedString.isEmpty()) {
|
|
attributedString = getPlaceholderAttributedString(layoutContext);
|
|
}
|
|
return AttributedStringBox{attributedString};
|
|
}
|
|
AttributedString getPlaceholderAttributedString(
|
|
const LayoutContext& layoutContext) const {
|
|
const auto& props = BaseShadowNode::getConcreteProps();
|
|
AttributedString attributedString;
|
|
attributedString.setBaseTextAttributes(
|
|
props.getEffectiveTextAttributes(layoutContext.fontSizeMultiplier));
|
|
if (!props.placeholder.empty()) {
|
|
attributedString.appendFragment(
|
|
{.string = props.placeholder,
|
|
.textAttributes = attributedString.getBaseTextAttributes(),
|
|
.parentShadowView = {}});
|
|
}
|
|
return attributedString;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputEventEmitter.h}:
|
|
namespace facebook::react {
|
|
class TextInputEventEmitter : public ViewEventEmitter {
|
|
public:
|
|
using ViewEventEmitter::ViewEventEmitter;
|
|
struct Metrics {
|
|
std::string text;
|
|
AttributedString::Range selectionRange;
|
|
Size contentSize;
|
|
Point contentOffset;
|
|
EdgeInsets contentInset;
|
|
Size containerSize;
|
|
int eventCount;
|
|
Size layoutMeasurement;
|
|
Float zoomScale;
|
|
Tag target;
|
|
};
|
|
struct KeyPressMetrics {
|
|
std::string text;
|
|
int eventCount;
|
|
};
|
|
void onFocus(const Metrics& textInputMetrics) const;
|
|
void onBlur(const Metrics& textInputMetrics) const;
|
|
void onChange(const Metrics& textInputMetrics) const;
|
|
void onContentSizeChange(const Metrics& textInputMetrics) const;
|
|
void onSelectionChange(const Metrics& textInputMetrics) const;
|
|
void onEndEditing(const Metrics& textInputMetrics) const;
|
|
void onSubmitEditing(const Metrics& textInputMetrics) const;
|
|
void onKeyPress(const KeyPressMetrics& keyPressMetrics) const;
|
|
void onScroll(const Metrics& textInputMetrics) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/TextInputState.h}:
|
|
namespace facebook::react {
|
|
class TextInputState final {
|
|
public:
|
|
TextInputState() = default;
|
|
TextInputState(
|
|
AttributedStringBox attributedStringBox,
|
|
AttributedString reactTreeAttributedString,
|
|
ParagraphAttributes paragraphAttributes,
|
|
int64_t mostRecentEventCount)
|
|
: attributedStringBox(std::move(attributedStringBox)),
|
|
reactTreeAttributedString(std::move(reactTreeAttributedString)),
|
|
paragraphAttributes(std::move(paragraphAttributes)),
|
|
mostRecentEventCount(mostRecentEventCount) {}
|
|
AttributedStringBox attributedStringBox;
|
|
AttributedString reactTreeAttributedString{};
|
|
ParagraphAttributes paragraphAttributes;
|
|
int64_t mostRecentEventCount{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/baseConversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
SubmitBehavior& result) {
|
|
auto string = static_cast<std::string>(value);
|
|
if (string == "newline") {
|
|
result = SubmitBehavior::Newline;
|
|
} else if (string == "submit") {
|
|
result = SubmitBehavior::Submit;
|
|
} else if (string == "blurAndSubmit") {
|
|
result = SubmitBehavior::BlurAndSubmit;
|
|
} else {
|
|
abort();
|
|
}
|
|
}
|
|
inline folly::dynamic toDynamic(const SubmitBehavior& value) {
|
|
switch (value) {
|
|
case SubmitBehavior::Newline:
|
|
return "newline";
|
|
case SubmitBehavior::Submit:
|
|
return "submit";
|
|
case SubmitBehavior::BlurAndSubmit:
|
|
return "blurAndSubmit";
|
|
case SubmitBehavior::Default:
|
|
return {nullptr};
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/basePrimitives.h}:
|
|
namespace facebook::react {
|
|
enum class SubmitBehavior {
|
|
Default,
|
|
Submit,
|
|
BlurAndSubmit,
|
|
Newline,
|
|
};
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputComponentDescriptor.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputEventEmitter.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputState.h}
|
|
namespace facebook::react {
|
|
extern const char AndroidTextInputComponentName[];
|
|
class AndroidTextInputShadowNode final : public ConcreteViewShadowNode<
|
|
AndroidTextInputComponentName,
|
|
AndroidTextInputProps,
|
|
AndroidTextInputEventEmitter,
|
|
AndroidTextInputState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::BaselineYogaNode);
|
|
return traits;
|
|
}
|
|
void setTextLayoutManager(
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager);
|
|
|
|
protected:
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override;
|
|
void layout(LayoutContext layoutContext) override;
|
|
Float baseline(const LayoutContext& layoutContext, Size size) const override;
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager_;
|
|
LayoutConstraints getTextConstraints(
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class AndroidTextInputComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<AndroidTextInputShadowNode> {
|
|
public:
|
|
AndroidTextInputComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor<AndroidTextInputShadowNode>(parameters),
|
|
textLayoutManager_(
|
|
std::make_shared<TextLayoutManager>(contextContainer_)) {}
|
|
virtual State::Shared createInitialState(
|
|
const Props::Shared& props,
|
|
const ShadowNodeFamily::Shared& family) const override {
|
|
int surfaceId = family->getSurfaceId();
|
|
ThemePadding theme;
|
|
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
|
|
surfaceIdToThemePaddingMap_.end()) {
|
|
theme = surfaceIdToThemePaddingMap_[surfaceId];
|
|
} else {
|
|
const jni::global_ref<jobject>& fabricUIManager =
|
|
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
|
|
auto env = jni::Environment::current();
|
|
auto defaultTextInputPaddingArray = env->NewFloatArray(4);
|
|
static auto getThemeData =
|
|
jni::findClassStatic(UIManagerJavaDescriptor)
|
|
->getMethod<jboolean(jint, jfloatArray)>("getThemeData");
|
|
if (getThemeData(
|
|
fabricUIManager, surfaceId, defaultTextInputPaddingArray)) {
|
|
jfloat* defaultTextInputPadding =
|
|
env->GetFloatArrayElements(defaultTextInputPaddingArray, nullptr);
|
|
theme.start = defaultTextInputPadding[0];
|
|
theme.end = defaultTextInputPadding[1];
|
|
theme.top = defaultTextInputPadding[2];
|
|
theme.bottom = defaultTextInputPadding[3];
|
|
surfaceIdToThemePaddingMap_.emplace(std::make_pair(surfaceId, theme));
|
|
env->ReleaseFloatArrayElements(
|
|
defaultTextInputPaddingArray, defaultTextInputPadding, JNI_ABORT);
|
|
}
|
|
env->DeleteLocalRef(defaultTextInputPaddingArray);
|
|
}
|
|
return std::make_shared<AndroidTextInputShadowNode::ConcreteState>(
|
|
std::make_shared<const AndroidTextInputState>(
|
|
AndroidTextInputState({}, {}, {}, 0)),
|
|
family);
|
|
}
|
|
|
|
protected:
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
auto& textInputShadowNode =
|
|
static_cast<AndroidTextInputShadowNode&>(shadowNode);
|
|
textInputShadowNode.setTextLayoutManager(textLayoutManager_);
|
|
int surfaceId = textInputShadowNode.getSurfaceId();
|
|
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
|
|
surfaceIdToThemePaddingMap_.end()) {
|
|
const auto& theme = surfaceIdToThemePaddingMap_[surfaceId];
|
|
auto& textInputProps = textInputShadowNode.getConcreteProps();
|
|
auto& style = const_cast<yoga::Style&>(textInputProps.yogaStyle);
|
|
bool changedPadding = false;
|
|
if (!textInputProps.hasPadding && !textInputProps.hasPaddingStart &&
|
|
!textInputProps.hasPaddingLeft &&
|
|
!textInputProps.hasPaddingHorizontal) {
|
|
changedPadding = true;
|
|
style.setPadding(
|
|
yoga::Edge::Start, yoga::StyleLength::points(theme.start));
|
|
}
|
|
if (!textInputProps.hasPadding && !textInputProps.hasPaddingEnd &&
|
|
!textInputProps.hasPaddingRight &&
|
|
!textInputProps.hasPaddingHorizontal) {
|
|
changedPadding = true;
|
|
style.setPadding(yoga::Edge::End, yoga::StyleLength::points(theme.end));
|
|
}
|
|
if (!textInputProps.hasPadding && !textInputProps.hasPaddingTop &&
|
|
!textInputProps.hasPaddingVertical) {
|
|
changedPadding = true;
|
|
style.setPadding(yoga::Edge::Top, yoga::StyleLength::points(theme.top));
|
|
}
|
|
if (!textInputProps.hasPadding && !textInputProps.hasPaddingBottom &&
|
|
!textInputProps.hasPaddingVertical) {
|
|
changedPadding = true;
|
|
style.setPadding(
|
|
yoga::Edge::Bottom, yoga::StyleLength::points(theme.bottom));
|
|
}
|
|
if ((textInputProps.hasPadding || textInputProps.hasPaddingLeft ||
|
|
textInputProps.hasPaddingHorizontal) &&
|
|
!textInputProps.hasPaddingStart) {
|
|
style.setPadding(yoga::Edge::Start, yoga::StyleLength::undefined());
|
|
}
|
|
if ((textInputProps.hasPadding || textInputProps.hasPaddingRight ||
|
|
textInputProps.hasPaddingHorizontal) &&
|
|
!textInputProps.hasPaddingEnd) {
|
|
style.setPadding(yoga::Edge::End, yoga::StyleLength::undefined());
|
|
}
|
|
if (changedPadding) {
|
|
textInputShadowNode.updateYogaProps();
|
|
}
|
|
}
|
|
textInputShadowNode.dirtyLayout();
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
}
|
|
};
|
|
float end{};
|
|
float top{};
|
|
float bottom{};
|
|
};
|
|
constexpr static auto UIManagerJavaDescriptor =
|
|
"com/facebook/react/fabric/FabricUIManager";
|
|
const std::shared_ptr<TextLayoutManager> textLayoutManager_;
|
|
mutable std::unordered_map<int, ThemePadding> surfaceIdToThemePaddingMap_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputEventEmitter.h}:
|
|
namespace facebook::react {
|
|
class AndroidTextInputEventEmitter : public ViewEventEmitter {
|
|
public:
|
|
using ViewEventEmitter::ViewEventEmitter;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h}:
|
|
namespace facebook::react {
|
|
struct AndroidTextInputTextShadowOffsetStruct {
|
|
double width;
|
|
double height;
|
|
};
|
|
inline static bool operator==(
|
|
const AndroidTextInputTextShadowOffsetStruct& lhs,
|
|
const AndroidTextInputTextShadowOffsetStruct& rhs) {
|
|
return lhs.width == rhs.width && lhs.height == rhs.height;
|
|
}
|
|
static inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AndroidTextInputTextShadowOffsetStruct& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto width = map.find("width");
|
|
if (width != map.end()) {
|
|
fromRawValue(context, width->second, result.width);
|
|
}
|
|
auto height = map.find("height");
|
|
if (height != map.end()) {
|
|
fromRawValue(context, height->second, result.height);
|
|
}
|
|
}
|
|
static inline std::string toString(
|
|
const AndroidTextInputTextShadowOffsetStruct& value) {
|
|
return "[Object AndroidTextInputTextShadowOffsetStruct]";
|
|
}
|
|
inline folly::dynamic toDynamic(
|
|
const AndroidTextInputTextShadowOffsetStruct& value) {
|
|
folly::dynamic dynamicValue = folly::dynamic::object();
|
|
dynamicValue["width"] = value.width;
|
|
dynamicValue["height"] = value.height;
|
|
return dynamicValue;
|
|
}
|
|
class AndroidTextInputProps final : public BaseTextInputProps {
|
|
public:
|
|
AndroidTextInputProps() = default;
|
|
AndroidTextInputProps(
|
|
const PropsParserContext& context,
|
|
const AndroidTextInputProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
folly::dynamic getDynamic() const;
|
|
std::string autoComplete{};
|
|
std::string returnKeyLabel{};
|
|
int numberOfLines{0};
|
|
bool disableFullscreenUI{false};
|
|
std::string textBreakStrategy{};
|
|
std::string inlineImageLeft{};
|
|
int inlineImagePadding{0};
|
|
std::string importantForAutofill{};
|
|
bool showSoftInputOnFocus{false};
|
|
bool autoCorrect{false};
|
|
bool allowFontScaling{false};
|
|
Float maxFontSizeMultiplier{0.0};
|
|
std::string keyboardType{};
|
|
std::string returnKeyType{};
|
|
bool secureTextEntry{false};
|
|
std::string value{};
|
|
bool selectTextOnFocus{false};
|
|
bool caretHidden{false};
|
|
bool contextMenuHidden{false};
|
|
SharedColor textShadowColor{};
|
|
Float textShadowRadius{0.0};
|
|
std::string textDecorationLine{};
|
|
std::string fontStyle{};
|
|
AndroidTextInputTextShadowOffsetStruct textShadowOffset{};
|
|
Float lineHeight{0.0};
|
|
std::string textTransform{};
|
|
SharedColor color{0};
|
|
Float letterSpacing{0.0};
|
|
Float fontSize{0.0};
|
|
std::string textAlign{};
|
|
bool includeFontPadding{false};
|
|
std::string fontWeight{};
|
|
std::string fontFamily{};
|
|
bool hasPadding{};
|
|
bool hasPaddingHorizontal{};
|
|
bool hasPaddingVertical{};
|
|
bool hasPaddingLeft{};
|
|
bool hasPaddingTop{};
|
|
bool hasPaddingRight{};
|
|
bool hasPaddingBottom{};
|
|
bool hasPaddingStart{};
|
|
bool hasPaddingEnd{};
|
|
ComponentName getDiffPropsImplementationTarget() const override;
|
|
folly::dynamic getDiffProps(const Props* prevProps) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputEventEmitter.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputProps.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputState.h}
|
|
namespace facebook::react {
|
|
extern const char AndroidTextInputComponentName[];
|
|
class AndroidTextInputShadowNode final : public ConcreteViewShadowNode<
|
|
AndroidTextInputComponentName,
|
|
AndroidTextInputProps,
|
|
AndroidTextInputEventEmitter,
|
|
AndroidTextInputState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::LeafYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::MeasurableYogaNode);
|
|
traits.set(ShadowNodeTraits::Trait::BaselineYogaNode);
|
|
return traits;
|
|
}
|
|
void setTextLayoutManager(
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager);
|
|
|
|
protected:
|
|
Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const override;
|
|
void layout(LayoutContext layoutContext) override;
|
|
Float baseline(const LayoutContext& layoutContext, Size size) const override;
|
|
std::shared_ptr<const TextLayoutManager> textLayoutManager_;
|
|
LayoutConstraints getTextConstraints(
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputState.h}:
|
|
namespace facebook::react {
|
|
class AndroidTextInputState final {
|
|
public:
|
|
AndroidTextInputState() = default;
|
|
AndroidTextInputState(
|
|
AttributedStringBox attributedStringBox,
|
|
AttributedString reactTreeAttributedString,
|
|
ParagraphAttributes paragraphAttributes,
|
|
int64_t mostRecentEventCount)
|
|
: attributedStringBox(std::move(attributedStringBox)),
|
|
reactTreeAttributedString(std::move(reactTreeAttributedString)),
|
|
paragraphAttributes(std::move(paragraphAttributes)),
|
|
mostRecentEventCount(mostRecentEventCount) {}
|
|
AndroidTextInputState(
|
|
const AndroidTextInputState& previousState,
|
|
const folly::dynamic& data)
|
|
: attributedStringBox(previousState.attributedStringBox),
|
|
reactTreeAttributedString(previousState.reactTreeAttributedString),
|
|
paragraphAttributes(previousState.paragraphAttributes),
|
|
mostRecentEventCount(data.getDefault(
|
|
"mostRecentEventCount",
|
|
previousState.mostRecentEventCount)
|
|
.getInt()),
|
|
cachedAttributedStringId(data.getDefault(
|
|
"opaqueCacheId",
|
|
previousState.cachedAttributedStringId)
|
|
.getInt()) {}
|
|
folly::dynamic getDynamic() const;
|
|
MapBuffer getMapBuffer() const;
|
|
AttributedStringBox attributedStringBox;
|
|
AttributedString reactTreeAttributedString{};
|
|
ParagraphAttributes paragraphAttributes;
|
|
int64_t mostRecentEventCount{0};
|
|
int64_t cachedAttributedStringId{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class TextInputComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<TextInputShadowNode> {
|
|
public:
|
|
TextInputComponentDescriptor(const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor<TextInputShadowNode>(parameters),
|
|
textLayoutManager_(
|
|
std::make_shared<TextLayoutManager>(contextContainer_)) {}
|
|
|
|
protected:
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
auto& concreteShadowNode = static_cast<TextInputShadowNode&>(shadowNode);
|
|
concreteShadowNode.setTextLayoutManager(textLayoutManager_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputProps.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/TextInputProps.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char TextInputComponentName[];
|
|
class TextInputShadowNode final : public BaseTextInputShadowNode<
|
|
TextInputComponentName,
|
|
TextInputProps,
|
|
TextInputEventEmitter,
|
|
TextInputState> {
|
|
public:
|
|
using BaseTextInputShadowNode::BaseTextInputShadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/conversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AutocapitalizationType& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = AutocapitalizationType::None;
|
|
return;
|
|
}
|
|
if (string == "words") {
|
|
result = AutocapitalizationType::Words;
|
|
return;
|
|
}
|
|
if (string == "sentences") {
|
|
result = AutocapitalizationType::Sentences;
|
|
return;
|
|
}
|
|
if (string == "characters") {
|
|
result = AutocapitalizationType::Characters;
|
|
return;
|
|
}
|
|
result = AutocapitalizationType::None;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
KeyboardAppearance& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = KeyboardAppearance::Default;
|
|
return;
|
|
}
|
|
if (string == "light") {
|
|
result = KeyboardAppearance::Light;
|
|
return;
|
|
}
|
|
if (string == "dark") {
|
|
result = KeyboardAppearance::Dark;
|
|
return;
|
|
}
|
|
result = KeyboardAppearance::Default;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ReturnKeyType& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = ReturnKeyType::Default;
|
|
return;
|
|
}
|
|
if (string == "done") {
|
|
result = ReturnKeyType::Done;
|
|
return;
|
|
}
|
|
if (string == "go") {
|
|
result = ReturnKeyType::Go;
|
|
return;
|
|
}
|
|
if (string == "next") {
|
|
result = ReturnKeyType::Next;
|
|
return;
|
|
}
|
|
if (string == "search") {
|
|
result = ReturnKeyType::Search;
|
|
return;
|
|
}
|
|
if (string == "send") {
|
|
result = ReturnKeyType::Send;
|
|
return;
|
|
}
|
|
if (string == "none") {
|
|
result = ReturnKeyType::None;
|
|
return;
|
|
}
|
|
if (string == "previous") {
|
|
result = ReturnKeyType::Previous;
|
|
return;
|
|
}
|
|
if (string == "emergency-call") {
|
|
result = ReturnKeyType::EmergencyCall;
|
|
return;
|
|
}
|
|
if (string == "google") {
|
|
result = ReturnKeyType::Google;
|
|
return;
|
|
}
|
|
if (string == "join") {
|
|
result = ReturnKeyType::Join;
|
|
return;
|
|
}
|
|
if (string == "route") {
|
|
result = ReturnKeyType::Route;
|
|
return;
|
|
}
|
|
if (string == "yahoo") {
|
|
result = ReturnKeyType::Yahoo;
|
|
return;
|
|
}
|
|
if (string == "continue") {
|
|
result = ReturnKeyType::Continue;
|
|
return;
|
|
}
|
|
result = ReturnKeyType::Default;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextInputAccessoryVisibilityMode& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "never") {
|
|
result = TextInputAccessoryVisibilityMode::Never;
|
|
return;
|
|
}
|
|
if (string == "while-editing") {
|
|
result = TextInputAccessoryVisibilityMode::WhileEditing;
|
|
return;
|
|
}
|
|
if (string == "unless-editing") {
|
|
result = TextInputAccessoryVisibilityMode::UnlessEditing;
|
|
return;
|
|
}
|
|
if (string == "always") {
|
|
result = TextInputAccessoryVisibilityMode::Always;
|
|
return;
|
|
}
|
|
result = TextInputAccessoryVisibilityMode::Never;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
KeyboardType& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = KeyboardType::Default;
|
|
return;
|
|
}
|
|
if (string == "email-address") {
|
|
result = KeyboardType::EmailAddress;
|
|
return;
|
|
}
|
|
if (string == "numeric") {
|
|
result = KeyboardType::Numeric;
|
|
return;
|
|
}
|
|
if (string == "phone-pad") {
|
|
result = KeyboardType::PhonePad;
|
|
return;
|
|
}
|
|
if (string == "number-pad") {
|
|
result = KeyboardType::NumberPad;
|
|
return;
|
|
}
|
|
if (string == "url") {
|
|
result = KeyboardType::URL;
|
|
return;
|
|
}
|
|
if (string == "decimal-pad") {
|
|
result = KeyboardType::DecimalPad;
|
|
return;
|
|
}
|
|
if (string == "ascii-capable") {
|
|
result = KeyboardType::ASCIICapable;
|
|
return;
|
|
}
|
|
if (string == "numbers-and-punctuation") {
|
|
result = KeyboardType::NumbersAndPunctuation;
|
|
return;
|
|
}
|
|
if (string == "name-phone-pad") {
|
|
result = KeyboardType::NamePhonePad;
|
|
return;
|
|
}
|
|
if (string == "twitter") {
|
|
result = KeyboardType::Twitter;
|
|
return;
|
|
}
|
|
if (string == "web-search") {
|
|
result = KeyboardType::WebSearch;
|
|
return;
|
|
}
|
|
if (string == "ascii-capable-number-pad") {
|
|
result = KeyboardType::ASCIICapableNumberPad;
|
|
return;
|
|
}
|
|
if (string == "visible-password") {
|
|
result = KeyboardType::VisiblePassword;
|
|
return;
|
|
}
|
|
result = KeyboardType::Default;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/primitives.h}:
|
|
namespace facebook::react {
|
|
enum class AutocapitalizationType {
|
|
None,
|
|
Words,
|
|
Sentences,
|
|
Characters,
|
|
};
|
|
enum class KeyboardAppearance {
|
|
Default,
|
|
Light,
|
|
Dark,
|
|
};
|
|
enum class ReturnKeyType {
|
|
Default,
|
|
Done,
|
|
Go,
|
|
Next,
|
|
Search,
|
|
Send,
|
|
None,
|
|
Previous,
|
|
EmergencyCall,
|
|
Google,
|
|
Join,
|
|
Route,
|
|
Yahoo,
|
|
Continue,
|
|
};
|
|
enum class TextInputAccessoryVisibilityMode {
|
|
Never,
|
|
WhileEditing,
|
|
UnlessEditing,
|
|
Always,
|
|
};
|
|
enum class KeyboardType {
|
|
Default,
|
|
EmailAddress,
|
|
Numeric,
|
|
PhonePad,
|
|
NumberPad,
|
|
DecimalPad,
|
|
ASCIICapable,
|
|
NumbersAndPunctuation,
|
|
URL,
|
|
NamePhonePad,
|
|
Twitter,
|
|
WebSearch,
|
|
ASCIICapableNumberPad,
|
|
VisiblePassword,
|
|
};
|
|
class Selection final {
|
|
public:
|
|
int start{0};
|
|
int end{0};
|
|
};
|
|
class TextInputTraits final {
|
|
public:
|
|
AutocapitalizationType autocapitalizationType{
|
|
AutocapitalizationType::Sentences};
|
|
std::optional<bool> autoCorrect{};
|
|
bool contextMenuHidden{false};
|
|
bool editable{true};
|
|
bool enablesReturnKeyAutomatically{false};
|
|
KeyboardAppearance keyboardAppearance{KeyboardAppearance::Default};
|
|
std::optional<bool> spellCheck{};
|
|
bool caretHidden{false};
|
|
TextInputAccessoryVisibilityMode clearButtonMode{
|
|
TextInputAccessoryVisibilityMode::Never};
|
|
bool scrollEnabled{true};
|
|
bool secureTextEntry{false};
|
|
bool clearTextOnFocus{false};
|
|
KeyboardType keyboardType{KeyboardType::Default};
|
|
bool showSoftInputOnFocus{true};
|
|
ReturnKeyType returnKeyType{ReturnKeyType::Default};
|
|
bool selectTextOnFocus{false};
|
|
std::vector<std::string> dataDetectorTypes{};
|
|
std::string textContentType{};
|
|
std::string passwordRules{};
|
|
std::optional<bool> smartInsertDelete{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/propsConversions.h}:
|
|
namespace facebook::react {
|
|
static TextInputTraits convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const TextInputTraits& sourceTraits,
|
|
const TextInputTraits& defaultTraits) {
|
|
auto traits = TextInputTraits{};
|
|
traits.autocapitalizationType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"autoCapitalize",
|
|
sourceTraits.autocapitalizationType,
|
|
defaultTraits.autocapitalizationType);
|
|
traits.autoCorrect = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"autoCorrect",
|
|
sourceTraits.autoCorrect,
|
|
defaultTraits.autoCorrect);
|
|
traits.contextMenuHidden = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"contextMenuHidden",
|
|
sourceTraits.contextMenuHidden,
|
|
defaultTraits.contextMenuHidden);
|
|
traits.editable = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"editable",
|
|
sourceTraits.editable,
|
|
defaultTraits.editable);
|
|
traits.enablesReturnKeyAutomatically = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"enablesReturnKeyAutomatically",
|
|
sourceTraits.enablesReturnKeyAutomatically,
|
|
defaultTraits.enablesReturnKeyAutomatically);
|
|
traits.keyboardAppearance = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"keyboardAppearance",
|
|
sourceTraits.keyboardAppearance,
|
|
defaultTraits.keyboardAppearance);
|
|
traits.spellCheck = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"spellCheck",
|
|
sourceTraits.spellCheck,
|
|
defaultTraits.spellCheck);
|
|
traits.caretHidden = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"caretHidden",
|
|
sourceTraits.caretHidden,
|
|
defaultTraits.caretHidden);
|
|
traits.clearButtonMode = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"clearButtonMode",
|
|
sourceTraits.clearButtonMode,
|
|
defaultTraits.clearButtonMode);
|
|
traits.scrollEnabled = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"scrollEnabled",
|
|
sourceTraits.scrollEnabled,
|
|
defaultTraits.scrollEnabled);
|
|
traits.secureTextEntry = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"secureTextEntry",
|
|
sourceTraits.secureTextEntry,
|
|
defaultTraits.secureTextEntry);
|
|
traits.clearTextOnFocus = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"clearTextOnFocus",
|
|
sourceTraits.clearTextOnFocus,
|
|
defaultTraits.clearTextOnFocus);
|
|
traits.keyboardType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"keyboardType",
|
|
sourceTraits.keyboardType,
|
|
defaultTraits.keyboardType);
|
|
traits.showSoftInputOnFocus = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"showSoftInputOnFocus",
|
|
sourceTraits.showSoftInputOnFocus,
|
|
defaultTraits.showSoftInputOnFocus);
|
|
traits.returnKeyType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"returnKeyType",
|
|
sourceTraits.returnKeyType,
|
|
defaultTraits.returnKeyType);
|
|
traits.selectTextOnFocus = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"selectTextOnFocus",
|
|
sourceTraits.selectTextOnFocus,
|
|
defaultTraits.selectTextOnFocus);
|
|
traits.textContentType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"textContentType",
|
|
sourceTraits.textContentType,
|
|
defaultTraits.textContentType);
|
|
traits.passwordRules = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"passwordRules",
|
|
sourceTraits.passwordRules,
|
|
defaultTraits.passwordRules);
|
|
traits.smartInsertDelete = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"smartInsertDelete",
|
|
sourceTraits.smartInsertDelete,
|
|
defaultTraits.smartInsertDelete);
|
|
traits.dataDetectorTypes = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"dataDetectorTypes",
|
|
sourceTraits.dataDetectorTypes,
|
|
defaultTraits.dataDetectorTypes);
|
|
return traits;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Selection& result) {
|
|
if (value.hasType<std::unordered_map<std::string, int>>()) {
|
|
auto map = (std::unordered_map<std::string, int>)value;
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "start") {
|
|
result.start = pair.second;
|
|
} else if (pair.first == "end") {
|
|
result.end = pair.second;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Selection map key: " << pair.first;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
react_native_expect(value.hasType<std::vector<int>>());
|
|
if (value.hasType<std::vector<int>>()) {
|
|
auto array = (std::vector<int>)value;
|
|
react_native_expect(array.size() == 2);
|
|
if (array.size() >= 2) {
|
|
result = {array.at(0), array.at(1)};
|
|
} else {
|
|
result = {0, 0};
|
|
LOG(ERROR) << "Unsupported Selection vector size: " << array.size();
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Selection type";
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/MacOSTextInputEventEmitter.h}:
|
|
namespace facebook::react {
|
|
class MacOSTextInputEventEmitter : public TextInputEventEmitter {
|
|
public:
|
|
using TextInputEventEmitter::TextInputEventEmitter;
|
|
struct OnAutoCorrectChange {
|
|
bool enabled;
|
|
};
|
|
void onAutoCorrectChange(OnAutoCorrectChange value) const;
|
|
struct OnSpellCheckChange {
|
|
bool enabled;
|
|
};
|
|
void onSpellCheckChange(OnSpellCheckChange value) const;
|
|
struct OnGrammarCheckChange {
|
|
bool enabled;
|
|
};
|
|
void onGrammarCheckChange(OnGrammarCheckChange value) const;
|
|
struct PasteEvent {
|
|
std::vector<DataTransferItem> dataTransferItems;
|
|
};
|
|
void onPaste(const PasteEvent& pasteEvent) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/TextInputComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class TextInputComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<TextInputShadowNode> {
|
|
public:
|
|
TextInputComponentDescriptor(const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor<TextInputShadowNode>(parameters) {
|
|
textLayoutManager_ =
|
|
std::make_shared<const TextLayoutManager>(contextContainer_);
|
|
}
|
|
|
|
protected:
|
|
void adopt(ShadowNode& shadowNode) const override {
|
|
ConcreteComponentDescriptor::adopt(shadowNode);
|
|
auto& concreteShadowNode = static_cast<TextInputShadowNode&>(shadowNode);
|
|
concreteShadowNode.setTextLayoutManager(textLayoutManager_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/TextInputProps.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/ios/react/renderer/components/iostextinput/TextInputProps.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/TextInputShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char TextInputComponentName[];
|
|
class TextInputShadowNode final : public BaseTextInputShadowNode<
|
|
TextInputComponentName,
|
|
TextInputProps,
|
|
MacOSTextInputEventEmitter,
|
|
TextInputState> {
|
|
public:
|
|
using BaseTextInputShadowNode::BaseTextInputShadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/conversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AutocapitalizationType& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = AutocapitalizationType::None;
|
|
return;
|
|
}
|
|
if (string == "words") {
|
|
result = AutocapitalizationType::Words;
|
|
return;
|
|
}
|
|
if (string == "sentences") {
|
|
result = AutocapitalizationType::Sentences;
|
|
return;
|
|
}
|
|
if (string == "characters") {
|
|
result = AutocapitalizationType::Characters;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
KeyboardAppearance& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = KeyboardAppearance::Default;
|
|
return;
|
|
}
|
|
if (string == "light") {
|
|
result = KeyboardAppearance::Light;
|
|
return;
|
|
}
|
|
if (string == "dark") {
|
|
result = KeyboardAppearance::Dark;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ReturnKeyType& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = ReturnKeyType::Default;
|
|
return;
|
|
}
|
|
if (string == "done") {
|
|
result = ReturnKeyType::Done;
|
|
return;
|
|
}
|
|
if (string == "go") {
|
|
result = ReturnKeyType::Go;
|
|
return;
|
|
}
|
|
if (string == "next") {
|
|
result = ReturnKeyType::Next;
|
|
return;
|
|
}
|
|
if (string == "search") {
|
|
result = ReturnKeyType::Search;
|
|
return;
|
|
}
|
|
if (string == "send") {
|
|
result = ReturnKeyType::Send;
|
|
return;
|
|
}
|
|
if (string == "none") {
|
|
result = ReturnKeyType::None;
|
|
return;
|
|
}
|
|
if (string == "previous") {
|
|
result = ReturnKeyType::Previous;
|
|
return;
|
|
}
|
|
if (string == "emergency-call") {
|
|
result = ReturnKeyType::EmergencyCall;
|
|
return;
|
|
}
|
|
if (string == "google") {
|
|
result = ReturnKeyType::Google;
|
|
return;
|
|
}
|
|
if (string == "join") {
|
|
result = ReturnKeyType::Join;
|
|
return;
|
|
}
|
|
if (string == "route") {
|
|
result = ReturnKeyType::Route;
|
|
return;
|
|
}
|
|
if (string == "yahoo") {
|
|
result = ReturnKeyType::Yahoo;
|
|
return;
|
|
}
|
|
if (string == "continue") {
|
|
result = ReturnKeyType::Continue;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TextInputAccessoryVisibilityMode& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "never") {
|
|
result = TextInputAccessoryVisibilityMode::Never;
|
|
return;
|
|
}
|
|
if (string == "while-editing") {
|
|
result = TextInputAccessoryVisibilityMode::WhileEditing;
|
|
return;
|
|
}
|
|
if (string == "unless-editing") {
|
|
result = TextInputAccessoryVisibilityMode::UnlessEditing;
|
|
return;
|
|
}
|
|
if (string == "always") {
|
|
result = TextInputAccessoryVisibilityMode::Always;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
KeyboardType& result) {
|
|
auto string = (std::string)value;
|
|
if (string == "default") {
|
|
result = KeyboardType::Default;
|
|
return;
|
|
}
|
|
if (string == "email-address") {
|
|
result = KeyboardType::EmailAddress;
|
|
return;
|
|
}
|
|
if (string == "numeric") {
|
|
result = KeyboardType::Numeric;
|
|
return;
|
|
}
|
|
if (string == "phone-pad") {
|
|
result = KeyboardType::PhonePad;
|
|
return;
|
|
}
|
|
if (string == "number-pad") {
|
|
result = KeyboardType::NumberPad;
|
|
return;
|
|
}
|
|
if (string == "url") {
|
|
result = KeyboardType::URL;
|
|
return;
|
|
}
|
|
if (string == "decimal-pad") {
|
|
result = KeyboardType::DecimalPad;
|
|
return;
|
|
}
|
|
if (string == "ascii-capable") {
|
|
result = KeyboardType::ASCIICapable;
|
|
return;
|
|
}
|
|
if (string == "numbers-and-punctuation") {
|
|
result = KeyboardType::NumbersAndPunctuation;
|
|
return;
|
|
}
|
|
if (string == "name-phone-pad") {
|
|
result = KeyboardType::NamePhonePad;
|
|
return;
|
|
}
|
|
if (string == "twitter") {
|
|
result = KeyboardType::Twitter;
|
|
return;
|
|
}
|
|
if (string == "web-search") {
|
|
result = KeyboardType::WebSearch;
|
|
return;
|
|
}
|
|
if (string == "ascii-capable-number-pad") {
|
|
result = KeyboardType::ASCIICapableNumberPad;
|
|
return;
|
|
}
|
|
if (string == "visible-password") {
|
|
result = KeyboardType::VisiblePassword;
|
|
return;
|
|
}
|
|
abort();
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/primitives.h}:
|
|
namespace facebook::react {
|
|
enum class AutocapitalizationType {
|
|
None,
|
|
Words,
|
|
Sentences,
|
|
Characters,
|
|
};
|
|
enum class KeyboardAppearance {
|
|
Default,
|
|
Light,
|
|
Dark,
|
|
};
|
|
enum class ReturnKeyType {
|
|
Default,
|
|
Done,
|
|
Go,
|
|
Next,
|
|
Search,
|
|
Send,
|
|
None,
|
|
Previous,
|
|
EmergencyCall,
|
|
Google,
|
|
Join,
|
|
Route,
|
|
Yahoo,
|
|
Continue,
|
|
};
|
|
enum class TextInputAccessoryVisibilityMode {
|
|
Never,
|
|
WhileEditing,
|
|
UnlessEditing,
|
|
Always,
|
|
};
|
|
enum class KeyboardType {
|
|
Default,
|
|
EmailAddress,
|
|
Numeric,
|
|
PhonePad,
|
|
NumberPad,
|
|
DecimalPad,
|
|
ASCIICapable,
|
|
NumbersAndPunctuation,
|
|
URL,
|
|
NamePhonePad,
|
|
Twitter,
|
|
WebSearch,
|
|
ASCIICapableNumberPad,
|
|
VisiblePassword,
|
|
};
|
|
class Selection final {
|
|
public:
|
|
int start{0};
|
|
int end{0};
|
|
};
|
|
class TextInputTraits final {
|
|
public:
|
|
AutocapitalizationType autocapitalizationType{
|
|
AutocapitalizationType::Sentences};
|
|
std::optional<bool> autoCorrect{};
|
|
bool contextMenuHidden{false};
|
|
bool editable{true};
|
|
bool enablesReturnKeyAutomatically{false};
|
|
KeyboardAppearance keyboardAppearance{KeyboardAppearance::Default};
|
|
std::optional<bool> spellCheck{};
|
|
bool caretHidden{false};
|
|
TextInputAccessoryVisibilityMode clearButtonMode{
|
|
TextInputAccessoryVisibilityMode::Never};
|
|
bool scrollEnabled{true};
|
|
bool secureTextEntry{false};
|
|
bool clearTextOnFocus{false};
|
|
KeyboardType keyboardType{KeyboardType::Default};
|
|
bool showSoftInputOnFocus{true};
|
|
ReturnKeyType returnKeyType{ReturnKeyType::Default};
|
|
bool selectTextOnFocus{false};
|
|
std::string textContentType{};
|
|
std::string passwordRules{};
|
|
std::vector<KeyEvent> submitKeyEvents{};
|
|
bool clearTextOnSubmit{false};
|
|
std::optional<bool> grammarCheck{};
|
|
std::optional<bool> smartInsertDelete{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/textinput/platform/macos/react/renderer/components/iostextinput/propsConversions.h}:
|
|
namespace facebook::react {
|
|
static TextInputTraits convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const TextInputTraits& sourceTraits,
|
|
const TextInputTraits& defaultTraits) {
|
|
auto traits = TextInputTraits{};
|
|
traits.autocapitalizationType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"autoCapitalize",
|
|
sourceTraits.autocapitalizationType,
|
|
defaultTraits.autocapitalizationType);
|
|
traits.autoCorrect = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"autoCorrect",
|
|
sourceTraits.autoCorrect,
|
|
defaultTraits.autoCorrect);
|
|
traits.contextMenuHidden = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"contextMenuHidden",
|
|
sourceTraits.contextMenuHidden,
|
|
defaultTraits.contextMenuHidden);
|
|
traits.editable = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"editable",
|
|
sourceTraits.editable,
|
|
defaultTraits.editable);
|
|
traits.enablesReturnKeyAutomatically = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"enablesReturnKeyAutomatically",
|
|
sourceTraits.enablesReturnKeyAutomatically,
|
|
defaultTraits.enablesReturnKeyAutomatically);
|
|
traits.keyboardAppearance = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"keyboardAppearance",
|
|
sourceTraits.keyboardAppearance,
|
|
defaultTraits.keyboardAppearance);
|
|
traits.spellCheck = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"spellCheck",
|
|
sourceTraits.spellCheck,
|
|
defaultTraits.spellCheck);
|
|
traits.caretHidden = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"caretHidden",
|
|
sourceTraits.caretHidden,
|
|
defaultTraits.caretHidden);
|
|
traits.clearButtonMode = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"clearButtonMode",
|
|
sourceTraits.clearButtonMode,
|
|
defaultTraits.clearButtonMode);
|
|
traits.scrollEnabled = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"scrollEnabled",
|
|
sourceTraits.scrollEnabled,
|
|
defaultTraits.scrollEnabled);
|
|
traits.secureTextEntry = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"secureTextEntry",
|
|
sourceTraits.secureTextEntry,
|
|
defaultTraits.secureTextEntry);
|
|
traits.clearTextOnFocus = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"clearTextOnFocus",
|
|
sourceTraits.clearTextOnFocus,
|
|
defaultTraits.clearTextOnFocus);
|
|
traits.keyboardType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"keyboardType",
|
|
sourceTraits.keyboardType,
|
|
defaultTraits.keyboardType);
|
|
traits.showSoftInputOnFocus = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"showSoftInputOnFocus",
|
|
sourceTraits.showSoftInputOnFocus,
|
|
defaultTraits.showSoftInputOnFocus);
|
|
traits.returnKeyType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"returnKeyType",
|
|
sourceTraits.returnKeyType,
|
|
defaultTraits.returnKeyType);
|
|
traits.selectTextOnFocus = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"selectTextOnFocus",
|
|
sourceTraits.selectTextOnFocus,
|
|
defaultTraits.selectTextOnFocus);
|
|
traits.textContentType = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"textContentType",
|
|
sourceTraits.textContentType,
|
|
defaultTraits.textContentType);
|
|
traits.passwordRules = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"passwordRules",
|
|
sourceTraits.passwordRules,
|
|
defaultTraits.passwordRules);
|
|
traits.grammarCheck = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"grammarCheck",
|
|
sourceTraits.grammarCheck,
|
|
defaultTraits.grammarCheck);
|
|
traits.smartInsertDelete = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"smartInsertDelete",
|
|
sourceTraits.smartInsertDelete,
|
|
defaultTraits.smartInsertDelete);
|
|
return traits;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Selection& result) {
|
|
if (value.hasType<std::unordered_map<std::string, int>>()) {
|
|
auto map = (std::unordered_map<std::string, int>)value;
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "start") {
|
|
result.start = pair.second;
|
|
} else if (pair.first == "end") {
|
|
result.end = pair.second;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Selection map key: " << pair.first;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
react_native_expect(value.hasType<std::vector<int>>());
|
|
if (value.hasType<std::vector<int>>()) {
|
|
auto array = (std::vector<int>)value;
|
|
react_native_expect(array.size() == 2);
|
|
if (array.size() >= 2) {
|
|
result = {array.at(0), array.at(1)};
|
|
} else {
|
|
result = {0, 0};
|
|
LOG(ERROR) << "Unsupported Selection vector size: " << array.size();
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Selection type";
|
|
}
|
|
}
|
|
static inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
KeyEvent& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto tmp_key = map.find("key");
|
|
if (tmp_key != map.end()) {
|
|
fromRawValue(context, tmp_key->second, result.key);
|
|
}
|
|
auto tmp_altKey = map.find("altKey");
|
|
if (tmp_altKey != map.end()) {
|
|
fromRawValue(context, tmp_altKey->second, result.altKey);
|
|
}
|
|
auto tmp_shiftKey = map.find("shiftKey");
|
|
if (tmp_shiftKey != map.end()) {
|
|
fromRawValue(context, tmp_shiftKey->second, result.shiftKey);
|
|
}
|
|
auto tmp_ctrlKey = map.find("ctrlKey");
|
|
if (tmp_ctrlKey != map.end()) {
|
|
fromRawValue(context, tmp_ctrlKey->second, result.ctrlKey);
|
|
}
|
|
auto tmp_metaKey = map.find("metaKey");
|
|
if (tmp_metaKey != map.end()) {
|
|
fromRawValue(context, tmp_metaKey->second, result.metaKey);
|
|
}
|
|
auto tmp_functionKey = map.find("functionKey");
|
|
if (tmp_functionKey != map.end()) {
|
|
fromRawValue(context, tmp_functionKey->second, result.functionKey);
|
|
}
|
|
}
|
|
static inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<KeyEvent>& result) {
|
|
auto items = (std::vector<RawValue>)value;
|
|
for (const auto& item : items) {
|
|
KeyEvent newItem;
|
|
fromRawValue(context, item, newItem);
|
|
result.emplace_back(newItem);
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class UnimplementedViewComponentDescriptor final
|
|
: public ConcreteComponentDescriptor<UnimplementedViewShadowNode> {
|
|
public:
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
ComponentHandle getComponentHandle() const override;
|
|
ComponentName getComponentName() const override;
|
|
Props::Shared cloneProps(
|
|
const PropsParserContext& context,
|
|
const Props::Shared& props,
|
|
RawProps rawProps) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewProps.h}:
|
|
namespace facebook::react {
|
|
class UnimplementedViewProps final : public ViewProps {
|
|
public:
|
|
using ViewProps::ViewProps;
|
|
void setComponentName(ComponentName componentName);
|
|
ComponentName getComponentName() const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/unimplementedview/UnimplementedViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char UnimplementedViewComponentName[];
|
|
using UnimplementedViewShadowNode = ConcreteViewShadowNode<
|
|
UnimplementedViewComponentName,
|
|
UnimplementedViewProps>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityPrimitives.h}:
|
|
namespace facebook::react {
|
|
enum class AccessibilityTraits : uint32_t {
|
|
None = 0,
|
|
Button = (1 << 0),
|
|
Link = (1 << 1),
|
|
Image = (1 << 2),
|
|
Selected = (1 << 3),
|
|
PlaysSound = (1 << 4),
|
|
KeyboardKey = (1 << 5),
|
|
StaticText = (1 << 6),
|
|
SummaryElement = (1 << 7),
|
|
NotEnabled = (1 << 8),
|
|
UpdatesFrequently = (1 << 9),
|
|
SearchField = (1 << 10),
|
|
StartsMediaSession = (1 << 11),
|
|
Adjustable = (1 << 12),
|
|
AllowsDirectInteraction = (1 << 13),
|
|
CausesPageTurn = (1 << 14),
|
|
Header = (1 << 15),
|
|
Switch = (1 << 16),
|
|
TabBar = (1 << 17),
|
|
};
|
|
constexpr enum AccessibilityTraits operator|(
|
|
const enum AccessibilityTraits lhs,
|
|
const enum AccessibilityTraits rhs) {
|
|
return (enum AccessibilityTraits)((uint32_t)lhs | (uint32_t)rhs);
|
|
}
|
|
constexpr enum AccessibilityTraits operator&(
|
|
const enum AccessibilityTraits lhs,
|
|
const enum AccessibilityTraits rhs) {
|
|
return (enum AccessibilityTraits)((uint32_t)lhs & (uint32_t)rhs);
|
|
}
|
|
struct AccessibilityAction {
|
|
std::string name;
|
|
std::optional<std::string> label{};
|
|
};
|
|
inline std::string toString(const AccessibilityAction& accessibilityAction) {
|
|
std::string result = accessibilityAction.name;
|
|
if (accessibilityAction.label.has_value()) {
|
|
result += ": '" + accessibilityAction.label.value() + "'";
|
|
}
|
|
return result;
|
|
}
|
|
inline std::string toString(
|
|
std::vector<AccessibilityAction> accessibilityActions) {
|
|
std::string result = "[";
|
|
for (size_t i = 0; i < accessibilityActions.size(); i++) {
|
|
result += toString(accessibilityActions[i]);
|
|
if (i < accessibilityActions.size() - 1) {
|
|
result += ", ";
|
|
}
|
|
}
|
|
result += "]";
|
|
return result;
|
|
}
|
|
inline static bool operator==(
|
|
const AccessibilityAction& lhs,
|
|
const AccessibilityAction& rhs) {
|
|
return lhs.name == rhs.name && lhs.label == rhs.label;
|
|
}
|
|
inline static bool operator!=(
|
|
const AccessibilityAction& lhs,
|
|
const AccessibilityAction& rhs) {
|
|
return !(rhs == lhs);
|
|
}
|
|
struct AccessibilityState {
|
|
bool disabled{false};
|
|
bool selected{false};
|
|
bool busy{false};
|
|
std::optional<bool> expanded{std::nullopt};
|
|
enum { Unchecked, Checked, Mixed, None } checked{None};
|
|
};
|
|
constexpr bool operator==(
|
|
const AccessibilityState& lhs,
|
|
const AccessibilityState& rhs) {
|
|
return lhs.disabled == rhs.disabled && lhs.selected == rhs.selected &&
|
|
lhs.checked == rhs.checked && lhs.busy == rhs.busy &&
|
|
lhs.expanded == rhs.expanded;
|
|
}
|
|
constexpr bool operator!=(
|
|
const AccessibilityState& lhs,
|
|
const AccessibilityState& rhs) {
|
|
return !(rhs == lhs);
|
|
}
|
|
struct AccessibilityLabelledBy {
|
|
std::vector<std::string> value{};
|
|
};
|
|
inline static bool operator==(
|
|
const AccessibilityLabelledBy& lhs,
|
|
const AccessibilityLabelledBy& rhs) {
|
|
return lhs.value == rhs.value;
|
|
}
|
|
inline static bool operator!=(
|
|
const AccessibilityLabelledBy& lhs,
|
|
const AccessibilityLabelledBy& rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
struct AccessibilityValue {
|
|
std::optional<int> min;
|
|
std::optional<int> max;
|
|
std::optional<int> now;
|
|
std::optional<std::string> text{};
|
|
};
|
|
constexpr bool operator==(
|
|
const AccessibilityValue& lhs,
|
|
const AccessibilityValue& rhs) {
|
|
return lhs.min == rhs.min && lhs.max == rhs.max && lhs.now == rhs.now &&
|
|
lhs.text == rhs.text;
|
|
}
|
|
constexpr bool operator!=(
|
|
const AccessibilityValue& lhs,
|
|
const AccessibilityValue& rhs) {
|
|
return !(rhs == lhs);
|
|
}
|
|
enum class ImportantForAccessibility : uint8_t {
|
|
Auto,
|
|
Yes,
|
|
No,
|
|
NoHideDescendants,
|
|
};
|
|
enum class AccessibilityLiveRegion : uint8_t {
|
|
None,
|
|
Polite,
|
|
Assertive,
|
|
};
|
|
inline std::string toString(
|
|
const AccessibilityLiveRegion& accessibilityLiveRegion) {
|
|
switch (accessibilityLiveRegion) {
|
|
case AccessibilityLiveRegion::None:
|
|
return "none";
|
|
case AccessibilityLiveRegion::Polite:
|
|
return "polite";
|
|
case AccessibilityLiveRegion::Assertive:
|
|
return "assertive";
|
|
}
|
|
}
|
|
enum class AccessibilityRole {
|
|
None,
|
|
Button,
|
|
Dropdownlist,
|
|
Togglebutton,
|
|
Link,
|
|
Search,
|
|
Image,
|
|
Keyboardkey,
|
|
Text,
|
|
Adjustable,
|
|
Imagebutton,
|
|
Header,
|
|
Summary,
|
|
Alert,
|
|
Checkbox,
|
|
Combobox,
|
|
Menu,
|
|
Menubar,
|
|
Menuitem,
|
|
Progressbar,
|
|
Radio,
|
|
Radiogroup,
|
|
Scrollbar,
|
|
Spinbutton,
|
|
Switch,
|
|
Tab,
|
|
Tabbar,
|
|
Tablist,
|
|
Timer,
|
|
List,
|
|
Toolbar,
|
|
Grid,
|
|
Pager,
|
|
Scrollview,
|
|
Horizontalscrollview,
|
|
Viewgroup,
|
|
Webview,
|
|
Drawerlayout,
|
|
Slidingdrawer,
|
|
Iconmenu,
|
|
};
|
|
enum class Role {
|
|
Alert,
|
|
Alertdialog,
|
|
Application,
|
|
Article,
|
|
Banner,
|
|
Button,
|
|
Cell,
|
|
Checkbox,
|
|
Columnheader,
|
|
Combobox,
|
|
Complementary,
|
|
Contentinfo,
|
|
Definition,
|
|
Dialog,
|
|
Directory,
|
|
Document,
|
|
Feed,
|
|
Figure,
|
|
Form,
|
|
Grid,
|
|
Group,
|
|
Heading,
|
|
Img,
|
|
Link,
|
|
List,
|
|
Listitem,
|
|
Log,
|
|
Main,
|
|
Marquee,
|
|
Math,
|
|
Menu,
|
|
Menubar,
|
|
Menuitem,
|
|
Meter,
|
|
Navigation,
|
|
None,
|
|
Note,
|
|
Option,
|
|
Presentation,
|
|
Progressbar,
|
|
Radio,
|
|
Radiogroup,
|
|
Region,
|
|
Row,
|
|
Rowgroup,
|
|
Rowheader,
|
|
Scrollbar,
|
|
Searchbox,
|
|
Separator,
|
|
Slider,
|
|
Spinbutton,
|
|
Status,
|
|
Summary,
|
|
Switch,
|
|
Tab,
|
|
Table,
|
|
Tablist,
|
|
Tabpanel,
|
|
Term,
|
|
Timer,
|
|
Toolbar,
|
|
Tooltip,
|
|
Tree,
|
|
Treegrid,
|
|
Treeitem,
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/AccessibilityProps.h}:
|
|
namespace facebook::react {
|
|
class AccessibilityProps {
|
|
public:
|
|
AccessibilityProps() = default;
|
|
AccessibilityProps(
|
|
const PropsParserContext& context,
|
|
const AccessibilityProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
bool accessible{false};
|
|
std::optional<AccessibilityState> accessibilityState{std::nullopt};
|
|
std::string accessibilityLabel;
|
|
std::vector<std::string> accessibilityOrder{};
|
|
AccessibilityLabelledBy accessibilityLabelledBy{};
|
|
AccessibilityLiveRegion accessibilityLiveRegion{
|
|
AccessibilityLiveRegion::None};
|
|
AccessibilityTraits accessibilityTraits{AccessibilityTraits::None};
|
|
std::string accessibilityRole;
|
|
std::string accessibilityHint;
|
|
std::string accessibilityLanguage;
|
|
std::string accessibilityLargeContentTitle;
|
|
AccessibilityValue accessibilityValue;
|
|
std::vector<AccessibilityAction> accessibilityActions{};
|
|
bool accessibilityShowsLargeContentViewer{false};
|
|
bool accessibilityViewIsModal{false};
|
|
bool accessibilityElementsHidden{false};
|
|
bool accessibilityIgnoresInvertColors{false};
|
|
bool accessibilityRespondsToUserInteraction{true};
|
|
bool onAccessibilityTap{};
|
|
bool onAccessibilityMagicTap{};
|
|
bool onAccessibilityEscape{};
|
|
bool onAccessibilityAction{};
|
|
ImportantForAccessibility importantForAccessibility{
|
|
ImportantForAccessibility::Auto};
|
|
Role role{Role::None};
|
|
std::string testId;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/BaseTouch.h}:
|
|
namespace facebook::react {
|
|
struct BaseTouch {
|
|
Point pagePoint;
|
|
Point offsetPoint;
|
|
Point screenPoint;
|
|
int identifier;
|
|
Tag target;
|
|
Float force;
|
|
Float timestamp;
|
|
struct Hasher {
|
|
size_t operator()(const BaseTouch& touch) const {
|
|
return std::hash<decltype(touch.identifier)>()(touch.identifier);
|
|
}
|
|
};
|
|
struct Comparator {
|
|
bool operator()(const BaseTouch& lhs, const BaseTouch& rhs) const {
|
|
return lhs.identifier == rhs.identifier;
|
|
}
|
|
};
|
|
};
|
|
void setTouchPayloadOnObject(
|
|
jsi::Object& object,
|
|
jsi::Runtime& runtime,
|
|
const BaseTouch& touch);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/BaseViewEventEmitter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.h}
|
|
|
|
namespace facebook::react {
|
|
class BaseViewEventEmitter : public TouchEventEmitter {
|
|
public:
|
|
using TouchEventEmitter::TouchEventEmitter;
|
|
void onAccessibilityAction(const std::string& name) const;
|
|
void onAccessibilityTap() const;
|
|
void onAccessibilityMagicTap() const;
|
|
void onAccessibilityEscape() const;
|
|
void onLayout(const LayoutMetrics& layoutMetrics) const;
|
|
};
|
|
bool wasDispatched{false};
|
|
bool isDispatching{false};
|
|
};
|
|
mutable std::shared_ptr<LayoutEventState> layoutEventState_{
|
|
std::make_shared<LayoutEventState>()};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/BaseViewProps.h}:
|
|
namespace facebook::react {
|
|
class BaseViewProps : public YogaStylableProps, public AccessibilityProps {
|
|
public:
|
|
BaseViewProps() = default;
|
|
BaseViewProps(
|
|
const PropsParserContext& context,
|
|
const BaseViewProps& sourceProps,
|
|
const RawProps& rawProps,
|
|
const std::function<bool(const std::string&)>& filterObjectKeys =
|
|
nullptr);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
Float opacity{1.0};
|
|
SharedColor backgroundColor{};
|
|
CascadedBorderRadii borderRadii{};
|
|
CascadedBorderColors borderColors{};
|
|
CascadedBorderCurves borderCurves{};
|
|
CascadedBorderStyles borderStyles{};
|
|
SharedColor outlineColor{};
|
|
Float outlineOffset{};
|
|
OutlineStyle outlineStyle{OutlineStyle::Solid};
|
|
Float outlineWidth{};
|
|
SharedColor shadowColor{};
|
|
Size shadowOffset{0, -3};
|
|
Float shadowOpacity{};
|
|
Float shadowRadius{3};
|
|
Cursor cursor{};
|
|
std::vector<BoxShadow> boxShadow{};
|
|
std::vector<FilterFunction> filter{};
|
|
std::vector<BackgroundImage> backgroundImage{};
|
|
BlendMode mixBlendMode{BlendMode::Normal};
|
|
Isolation isolation{Isolation::Auto};
|
|
Transform transform{};
|
|
TransformOrigin transformOrigin{};
|
|
BackfaceVisibility backfaceVisibility{};
|
|
bool shouldRasterize{};
|
|
std::optional<int> zIndex{};
|
|
PointerEventsMode pointerEvents{};
|
|
EdgeInsets hitSlop{};
|
|
bool onLayout{};
|
|
ViewEvents events{};
|
|
bool collapsable{true};
|
|
bool collapsableChildren{true};
|
|
bool removeClippedSubviews{false};
|
|
CascadedBorderWidths getBorderWidths() const;
|
|
BorderMetrics resolveBorderMetrics(const LayoutMetrics& layoutMetrics) const;
|
|
Transform resolveTransform(const LayoutMetrics& layoutMetrics) const;
|
|
bool getClipsContentToBounds() const;
|
|
static Transform resolveTransform(
|
|
const Size& frameSize,
|
|
const Transform& transform,
|
|
const TransformOrigin& transformOrigin);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/BoxShadowPropsConversions.h}:
|
|
namespace facebook::react {
|
|
inline void parseProcessedBoxShadow(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<BoxShadow>& result) {
|
|
react_native_expect(value.hasType<std::vector<RawValue>>());
|
|
if (!value.hasType<std::vector<RawValue>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
std::vector<BoxShadow> boxShadows{};
|
|
auto rawBoxShadows = static_cast<std::vector<RawValue>>(value);
|
|
for (const auto& rawBoxShadow : rawBoxShadows) {
|
|
bool isMap =
|
|
rawBoxShadow.hasType<std::unordered_map<std::string, RawValue>>();
|
|
react_native_expect(isMap);
|
|
if (!isMap) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto rawBoxShadowMap =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(rawBoxShadow);
|
|
BoxShadow boxShadow{};
|
|
auto offsetX = rawBoxShadowMap.find("offsetX");
|
|
react_native_expect(offsetX != rawBoxShadowMap.end());
|
|
if (offsetX == rawBoxShadowMap.end()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
react_native_expect(offsetX->second.hasType<Float>());
|
|
if (!offsetX->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
boxShadow.offsetX = (Float)offsetX->second;
|
|
auto offsetY = rawBoxShadowMap.find("offsetY");
|
|
react_native_expect(offsetY != rawBoxShadowMap.end());
|
|
if (offsetY == rawBoxShadowMap.end()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
react_native_expect(offsetY->second.hasType<Float>());
|
|
if (!offsetY->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
boxShadow.offsetY = (Float)offsetY->second;
|
|
auto blurRadius = rawBoxShadowMap.find("blurRadius");
|
|
if (blurRadius != rawBoxShadowMap.end()) {
|
|
react_native_expect(blurRadius->second.hasType<Float>());
|
|
if (!blurRadius->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
boxShadow.blurRadius = (Float)blurRadius->second;
|
|
}
|
|
auto spreadDistance = rawBoxShadowMap.find("spreadDistance");
|
|
if (spreadDistance != rawBoxShadowMap.end()) {
|
|
react_native_expect(spreadDistance->second.hasType<Float>());
|
|
if (!spreadDistance->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
boxShadow.spreadDistance = (Float)spreadDistance->second;
|
|
}
|
|
auto inset = rawBoxShadowMap.find("inset");
|
|
if (inset != rawBoxShadowMap.end()) {
|
|
react_native_expect(inset->second.hasType<bool>());
|
|
if (!inset->second.hasType<bool>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
boxShadow.inset = (bool)inset->second;
|
|
}
|
|
auto color = rawBoxShadowMap.find("color");
|
|
if (color != rawBoxShadowMap.end()) {
|
|
fromRawValue(
|
|
context.contextContainer,
|
|
context.surfaceId,
|
|
color->second,
|
|
boxShadow.color);
|
|
}
|
|
boxShadows.push_back(boxShadow);
|
|
}
|
|
result = boxShadows;
|
|
}
|
|
inline std::optional<BoxShadow> fromCSSShadow(const CSSShadow& cssShadow) {
|
|
if (cssShadow.offsetX.unit != CSSLengthUnit::Px ||
|
|
cssShadow.offsetY.unit != CSSLengthUnit::Px ||
|
|
cssShadow.blurRadius.unit != CSSLengthUnit::Px ||
|
|
cssShadow.spreadDistance.unit != CSSLengthUnit::Px) {
|
|
return {};
|
|
}
|
|
return BoxShadow{
|
|
.offsetX = cssShadow.offsetX.value,
|
|
.offsetY = cssShadow.offsetY.value,
|
|
.blurRadius = cssShadow.blurRadius.value,
|
|
.spreadDistance = cssShadow.spreadDistance.value,
|
|
.color = fromCSSColor(cssShadow.color),
|
|
.inset = cssShadow.inset,
|
|
};
|
|
}
|
|
inline void parseUnprocessedBoxShadowString(
|
|
std::string&& value,
|
|
std::vector<BoxShadow>& result) {
|
|
auto boxShadowList = parseCSSProperty<CSSShadowList>((std::string)value);
|
|
if (!std::holds_alternative<CSSShadowList>(boxShadowList)) {
|
|
result = {};
|
|
return;
|
|
}
|
|
for (const auto& cssShadow : std::get<CSSShadowList>(boxShadowList)) {
|
|
if (auto boxShadow = fromCSSShadow(cssShadow)) {
|
|
result.push_back(*boxShadow);
|
|
} else {
|
|
result = {};
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
inline std::optional<BoxShadow> parseBoxShadowRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value) {
|
|
if (!value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
return {};
|
|
}
|
|
auto boxShadow = std::unordered_map<std::string, RawValue>(value);
|
|
auto rawOffsetX = boxShadow.find("offsetX");
|
|
if (rawOffsetX == boxShadow.end()) {
|
|
return {};
|
|
}
|
|
auto offsetX = coerceLength(rawOffsetX->second);
|
|
if (!offsetX.has_value()) {
|
|
return {};
|
|
}
|
|
auto rawOffsetY = boxShadow.find("offsetY");
|
|
if (rawOffsetY == boxShadow.end()) {
|
|
return {};
|
|
}
|
|
auto offsetY = coerceLength(rawOffsetY->second);
|
|
if (!offsetY.has_value()) {
|
|
return {};
|
|
}
|
|
Float blurRadius = 0;
|
|
auto rawBlurRadius = boxShadow.find("blurRadius");
|
|
if (rawBlurRadius != boxShadow.end()) {
|
|
if (auto blurRadiusValue = coerceLength(rawBlurRadius->second)) {
|
|
if (*blurRadiusValue < 0) {
|
|
return {};
|
|
}
|
|
blurRadius = *blurRadiusValue;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
Float spreadDistance = 0;
|
|
auto rawSpreadDistance = boxShadow.find("spreadDistance");
|
|
if (rawSpreadDistance != boxShadow.end()) {
|
|
if (auto spreadDistanceValue = coerceLength(rawSpreadDistance->second)) {
|
|
spreadDistance = *spreadDistanceValue;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
bool inset = false;
|
|
auto rawInset = boxShadow.find("inset");
|
|
if (rawInset != boxShadow.end()) {
|
|
if (rawInset->second.hasType<bool>()) {
|
|
inset = (bool)rawInset->second;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
SharedColor color;
|
|
auto rawColor = boxShadow.find("color");
|
|
if (rawColor != boxShadow.end()) {
|
|
color = coerceColor(rawColor->second, context);
|
|
if (!color) {
|
|
return {};
|
|
}
|
|
}
|
|
return BoxShadow{
|
|
.offsetX = *offsetX,
|
|
.offsetY = *offsetY,
|
|
.blurRadius = blurRadius,
|
|
.spreadDistance = spreadDistance,
|
|
.color = color,
|
|
.inset = inset};
|
|
}
|
|
inline void parseUnprocessedBoxShadowList(
|
|
const PropsParserContext& context,
|
|
std::vector<RawValue>&& value,
|
|
std::vector<BoxShadow>& result) {
|
|
for (const auto& rawValue : value) {
|
|
if (auto boxShadow = parseBoxShadowRawValue(context, rawValue)) {
|
|
result.push_back(*boxShadow);
|
|
} else {
|
|
result = {};
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
inline void parseUnprocessedBoxShadow(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<BoxShadow>& result) {
|
|
if (value.hasType<std::string>()) {
|
|
parseUnprocessedBoxShadowString((std::string)value, result);
|
|
} else if (value.hasType<std::vector<RawValue>>()) {
|
|
parseUnprocessedBoxShadowList(
|
|
context, (std::vector<RawValue>)value, result);
|
|
} else {
|
|
result = {};
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<BoxShadow>& result) {
|
|
if (ReactNativeFeatureFlags::enableNativeCSSParsing()) {
|
|
parseUnprocessedBoxShadow(context, value, result);
|
|
} else {
|
|
parseProcessedBoxShadow(context, value, result);
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/CSSConversions.h}:
|
|
namespace facebook::react {
|
|
inline SharedColor fromCSSColor(const CSSColor& cssColor) {
|
|
return hostPlatformColorFromRGBA(
|
|
cssColor.r, cssColor.g, cssColor.b, cssColor.a);
|
|
}
|
|
inline std::optional<Float> coerceAmount(const RawValue& value) {
|
|
if (value.hasType<Float>()) {
|
|
return (Float)value;
|
|
}
|
|
if (value.hasType<std::string>()) {
|
|
auto cssVal =
|
|
parseCSSProperty<CSSNumber, CSSPercentage>((std::string)value);
|
|
if (std::holds_alternative<CSSNumber>(cssVal)) {
|
|
return std::get<CSSNumber>(cssVal).value;
|
|
} else if (std::holds_alternative<CSSPercentage>(cssVal)) {
|
|
return std::get<CSSPercentage>(cssVal).value / 100.0f;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
inline std::optional<Float> coerceAngle(const RawValue& value) {
|
|
if (value.hasType<Float>()) {
|
|
return (Float)value;
|
|
}
|
|
if (value.hasType<std::string>()) {
|
|
auto cssVal = parseCSSProperty<CSSAngle>((std::string)value);
|
|
if (std::holds_alternative<CSSAngle>(cssVal)) {
|
|
return std::get<CSSAngle>(cssVal).degrees;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
inline SharedColor coerceColor(
|
|
const RawValue& value,
|
|
const PropsParserContext& context) {
|
|
if (value.hasType<std::string>()) {
|
|
auto cssColor = parseCSSProperty<CSSColor>((std::string)value);
|
|
if (!std::holds_alternative<CSSColor>(cssColor)) {
|
|
return {};
|
|
}
|
|
return fromCSSColor(std::get<CSSColor>(cssColor));
|
|
}
|
|
SharedColor color;
|
|
fromRawValue(context.contextContainer, context.surfaceId, value, color);
|
|
return color;
|
|
}
|
|
inline std::optional<Float> coerceLength(const RawValue& value) {
|
|
if (value.hasType<Float>()) {
|
|
return (Float)value;
|
|
}
|
|
if (value.hasType<std::string>()) {
|
|
auto len = parseCSSProperty<CSSLength>((std::string)value);
|
|
if (!std::holds_alternative<CSSLength>(len)) {
|
|
return {};
|
|
}
|
|
auto cssLen = std::get<CSSLength>(len);
|
|
if (cssLen.unit != CSSLengthUnit::Px) {
|
|
return {};
|
|
}
|
|
return cssLen.value;
|
|
}
|
|
return {};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/ConcreteViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
template <
|
|
const char* concreteComponentName,
|
|
typename ViewPropsT = ViewProps,
|
|
typename ViewEventEmitterT = ViewEventEmitter,
|
|
typename StateDataT = StateData>
|
|
requires(std::is_base_of_v<ViewProps, ViewPropsT>)
|
|
class ConcreteViewShadowNode : public ConcreteShadowNode<
|
|
concreteComponentName,
|
|
YogaLayoutableShadowNode,
|
|
ViewPropsT,
|
|
ViewEventEmitterT,
|
|
StateDataT> {
|
|
static_assert(
|
|
std::is_base_of<ViewProps, ViewPropsT>::value,
|
|
"ViewPropsT must be a descendant of ViewProps");
|
|
static_assert(
|
|
std::is_base_of<YogaStylableProps, ViewPropsT>::value,
|
|
"ViewPropsT must be a descendant of YogaStylableProps");
|
|
static_assert(
|
|
std::is_base_of<AccessibilityProps, ViewPropsT>::value,
|
|
"ViewPropsT must be a descendant of AccessibilityProps");
|
|
|
|
public:
|
|
using BaseShadowNode = ConcreteShadowNode<
|
|
concreteComponentName,
|
|
YogaLayoutableShadowNode,
|
|
ViewPropsT,
|
|
ViewEventEmitterT,
|
|
StateDataT>;
|
|
ConcreteViewShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family,
|
|
ShadowNodeTraits traits)
|
|
: BaseShadowNode(fragment, family, traits) {
|
|
initialize();
|
|
}
|
|
ConcreteViewShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment)
|
|
: BaseShadowNode(sourceShadowNode, fragment) {
|
|
initialize();
|
|
}
|
|
using ConcreteViewProps = ViewPropsT;
|
|
using BaseShadowNode::BaseShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = BaseShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::ViewKind);
|
|
traits.set(ShadowNodeTraits::Trait::FormsStackingContext);
|
|
traits.set(ShadowNodeTraits::Trait::FormsView);
|
|
return traits;
|
|
}
|
|
Transform getTransform() const override {
|
|
auto layoutMetrics = BaseShadowNode::getLayoutMetrics();
|
|
return BaseShadowNode::getConcreteProps().resolveTransform(layoutMetrics);
|
|
}
|
|
bool canBeTouchTarget() const override {
|
|
auto pointerEvents =
|
|
BaseShadowNode::getConcreteProps().ViewProps::pointerEvents;
|
|
return pointerEvents == PointerEventsMode::Auto ||
|
|
pointerEvents == PointerEventsMode::BoxOnly;
|
|
}
|
|
bool canChildrenBeTouchTarget() const override {
|
|
auto pointerEvents =
|
|
BaseShadowNode::getConcreteProps().ViewProps::pointerEvents;
|
|
return pointerEvents == PointerEventsMode::Auto ||
|
|
pointerEvents == PointerEventsMode::BoxNone;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/FilterPropsConversions.h}:
|
|
namespace facebook::react {
|
|
inline void parseProcessedFilter(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<FilterFunction>& result) {
|
|
react_native_expect(value.hasType<std::vector<RawValue>>());
|
|
if (!value.hasType<std::vector<RawValue>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
std::vector<FilterFunction> filter{};
|
|
auto rawFilter = static_cast<std::vector<RawValue>>(value);
|
|
for (const auto& rawFilterPrimitive : rawFilter) {
|
|
bool isMap =
|
|
rawFilterPrimitive.hasType<std::unordered_map<std::string, RawValue>>();
|
|
react_native_expect(isMap);
|
|
if (!isMap) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto rawFilterFunction =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(
|
|
rawFilterPrimitive);
|
|
FilterFunction filterFunction{};
|
|
try {
|
|
filterFunction.type =
|
|
filterTypeFromString(rawFilterFunction.begin()->first);
|
|
if (filterFunction.type == FilterType::DropShadow) {
|
|
auto rawDropShadow =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(
|
|
rawFilterFunction.begin()->second);
|
|
DropShadowParams dropShadowParams{};
|
|
auto offsetX = rawDropShadow.find("offsetX");
|
|
react_native_expect(offsetX != rawDropShadow.end());
|
|
if (offsetX == rawDropShadow.end()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
react_native_expect(offsetX->second.hasType<Float>());
|
|
if (!offsetX->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
dropShadowParams.offsetX = (Float)offsetX->second;
|
|
auto offsetY = rawDropShadow.find("offsetY");
|
|
react_native_expect(offsetY != rawDropShadow.end());
|
|
if (offsetY == rawDropShadow.end()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
react_native_expect(offsetY->second.hasType<Float>());
|
|
if (!offsetY->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
dropShadowParams.offsetY = (Float)offsetY->second;
|
|
auto standardDeviation = rawDropShadow.find("standardDeviation");
|
|
if (standardDeviation != rawDropShadow.end()) {
|
|
react_native_expect(standardDeviation->second.hasType<Float>());
|
|
if (!standardDeviation->second.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
dropShadowParams.standardDeviation = (Float)standardDeviation->second;
|
|
}
|
|
auto color = rawDropShadow.find("color");
|
|
if (color != rawDropShadow.end()) {
|
|
fromRawValue(
|
|
context.contextContainer,
|
|
context.surfaceId,
|
|
color->second,
|
|
dropShadowParams.color);
|
|
}
|
|
filterFunction.parameters = dropShadowParams;
|
|
} else {
|
|
filterFunction.parameters = (float)rawFilterFunction.begin()->second;
|
|
}
|
|
filter.push_back(std::move(filterFunction));
|
|
} catch (const std::exception& e) {
|
|
LOG(ERROR) << "Could not parse FilterFunction: " << e.what();
|
|
result = {};
|
|
return;
|
|
}
|
|
}
|
|
result = filter;
|
|
}
|
|
inline FilterType filterTypeFromVariant(
|
|
const CSSFilterFunctionVariant& filter) {
|
|
return std::visit(
|
|
[](auto&& filter) -> FilterType {
|
|
using FilterT = std::decay_t<decltype(filter)>;
|
|
if constexpr (std::is_same_v<FilterT, CSSBlurFilter>) {
|
|
return FilterType::Blur;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSBrightnessFilter>) {
|
|
return FilterType::Brightness;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSContrastFilter>) {
|
|
return FilterType::Contrast;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSDropShadowFilter>) {
|
|
return FilterType::DropShadow;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSGrayscaleFilter>) {
|
|
return FilterType::Grayscale;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSHueRotateFilter>) {
|
|
return FilterType::HueRotate;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSInvertFilter>) {
|
|
return FilterType::Invert;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSOpacityFilter>) {
|
|
return FilterType::Opacity;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSSaturateFilter>) {
|
|
return FilterType::Saturate;
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSSepiaFilter>) {
|
|
return FilterType::Sepia;
|
|
}
|
|
},
|
|
filter);
|
|
}
|
|
inline std::optional<FilterFunction> fromCSSFilter(
|
|
const CSSFilterFunctionVariant& cssFilter) {
|
|
return std::visit(
|
|
[&](auto&& filter) -> std::optional<FilterFunction> {
|
|
using FilterT = std::decay_t<decltype(filter)>;
|
|
if constexpr (std::is_same_v<FilterT, CSSBlurFilter>) {
|
|
if (filter.amount.unit != CSSLengthUnit::Px) {
|
|
return {};
|
|
}
|
|
return FilterFunction{
|
|
.type = filterTypeFromVariant(cssFilter),
|
|
.parameters = filter.amount.value,
|
|
};
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSDropShadowFilter>) {
|
|
if (filter.offsetX.unit != CSSLengthUnit::Px ||
|
|
filter.offsetY.unit != CSSLengthUnit::Px ||
|
|
filter.standardDeviation.unit != CSSLengthUnit::Px) {
|
|
return {};
|
|
}
|
|
return FilterFunction{
|
|
.type = FilterType::DropShadow,
|
|
.parameters = DropShadowParams{
|
|
.offsetX = filter.offsetX.value,
|
|
.offsetY = filter.offsetY.value,
|
|
.standardDeviation = filter.standardDeviation.value,
|
|
.color = fromCSSColor(filter.color),
|
|
}};
|
|
}
|
|
if constexpr (
|
|
std::is_same_v<FilterT, CSSBrightnessFilter> ||
|
|
std::is_same_v<FilterT, CSSContrastFilter> ||
|
|
std::is_same_v<FilterT, CSSGrayscaleFilter> ||
|
|
std::is_same_v<FilterT, CSSInvertFilter> ||
|
|
std::is_same_v<FilterT, CSSOpacityFilter> ||
|
|
std::is_same_v<FilterT, CSSSaturateFilter> ||
|
|
std::is_same_v<FilterT, CSSSepiaFilter>) {
|
|
return FilterFunction{
|
|
.type = filterTypeFromVariant(cssFilter),
|
|
.parameters = filter.amount,
|
|
};
|
|
}
|
|
if constexpr (std::is_same_v<FilterT, CSSHueRotateFilter>) {
|
|
return FilterFunction{
|
|
.type = filterTypeFromVariant(cssFilter),
|
|
.parameters = filter.degrees,
|
|
};
|
|
}
|
|
},
|
|
cssFilter);
|
|
}
|
|
inline void parseUnprocessedFilterString(
|
|
std::string&& value,
|
|
std::vector<FilterFunction>& result) {
|
|
auto filterList = parseCSSProperty<CSSFilterList>((std::string)value);
|
|
if (!std::holds_alternative<CSSFilterList>(filterList)) {
|
|
result = {};
|
|
return;
|
|
}
|
|
for (const auto& cssFilter : std::get<CSSFilterList>(filterList)) {
|
|
if (auto filter = fromCSSFilter(cssFilter)) {
|
|
result.push_back(*filter);
|
|
} else {
|
|
result = {};
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
inline std::optional<FilterFunction> parseDropShadow(
|
|
const PropsParserContext& context,
|
|
const RawValue& value) {
|
|
if (value.hasType<std::string>()) {
|
|
auto val = parseCSSProperty<CSSDropShadowFilter>(
|
|
std::string("drop-shadow(") + (std::string)value + ")");
|
|
if (std::holds_alternative<CSSDropShadowFilter>(val)) {
|
|
return fromCSSFilter(std::get<CSSDropShadowFilter>(val));
|
|
}
|
|
return {};
|
|
}
|
|
if (!value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
return {};
|
|
}
|
|
auto rawDropShadow =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(value);
|
|
DropShadowParams dropShadowParams{};
|
|
auto offsetX = rawDropShadow.find("offsetX");
|
|
if (offsetX == rawDropShadow.end()) {
|
|
return {};
|
|
}
|
|
if (auto parsedOffsetX = coerceLength(offsetX->second)) {
|
|
dropShadowParams.offsetX = *parsedOffsetX;
|
|
} else {
|
|
return {};
|
|
}
|
|
auto offsetY = rawDropShadow.find("offsetY");
|
|
if (offsetY == rawDropShadow.end()) {
|
|
return {};
|
|
}
|
|
if (auto parsedOffsetY = coerceLength(offsetY->second)) {
|
|
dropShadowParams.offsetY = *parsedOffsetY;
|
|
} else {
|
|
return {};
|
|
}
|
|
auto standardDeviation = rawDropShadow.find("standardDeviation");
|
|
if (standardDeviation != rawDropShadow.end()) {
|
|
if (auto parsedStandardDeviation =
|
|
coerceLength(standardDeviation->second)) {
|
|
if (*parsedStandardDeviation < 0.0f) {
|
|
return {};
|
|
}
|
|
dropShadowParams.standardDeviation = *parsedStandardDeviation;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
auto color = rawDropShadow.find("color");
|
|
if (color != rawDropShadow.end()) {
|
|
if (auto parsedColor = coerceColor(color->second, context)) {
|
|
dropShadowParams.color = *parsedColor;
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
return FilterFunction{FilterType::DropShadow, dropShadowParams};
|
|
}
|
|
inline std::optional<FilterFunction> parseFilterRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value) {
|
|
if (!value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
return {};
|
|
}
|
|
auto rawFilter =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(value);
|
|
if (rawFilter.size() != 1) {
|
|
return {};
|
|
}
|
|
const auto& filterKey = rawFilter.begin()->first;
|
|
if (filterKey == "drop-shadow") {
|
|
return parseDropShadow(context, rawFilter.begin()->second);
|
|
} else if (filterKey == "blur") {
|
|
if (auto length = coerceLength(rawFilter.begin()->second)) {
|
|
if (*length < 0.0f) {
|
|
return {};
|
|
}
|
|
return FilterFunction{FilterType::Blur, *length};
|
|
}
|
|
return {};
|
|
} else if (filterKey == "hue-rotate") {
|
|
if (auto angle = coerceAngle(rawFilter.begin()->second)) {
|
|
return FilterFunction{FilterType::HueRotate, *angle};
|
|
}
|
|
return {};
|
|
} else {
|
|
if (auto amount = coerceAmount(rawFilter.begin()->second)) {
|
|
if (*amount < 0.0f) {
|
|
return {};
|
|
}
|
|
return FilterFunction{filterTypeFromString(filterKey), *amount};
|
|
}
|
|
return {};
|
|
}
|
|
}
|
|
inline void parseUnprocessedFilterList(
|
|
const PropsParserContext& context,
|
|
std::vector<RawValue>&& value,
|
|
std::vector<FilterFunction>& result) {
|
|
for (const auto& rawValue : value) {
|
|
if (auto Filter = parseFilterRawValue(context, rawValue)) {
|
|
result.push_back(*Filter);
|
|
} else {
|
|
result = {};
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
inline void parseUnprocessedFilter(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<FilterFunction>& result) {
|
|
if (value.hasType<std::string>()) {
|
|
parseUnprocessedFilterString((std::string)value, result);
|
|
} else if (value.hasType<std::vector<RawValue>>()) {
|
|
parseUnprocessedFilterList(context, (std::vector<RawValue>)value, result);
|
|
} else {
|
|
result = {};
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<FilterFunction>& result) {
|
|
if (ReactNativeFeatureFlags::enableNativeCSSParsing()) {
|
|
parseUnprocessedFilter(context, value, result);
|
|
} else {
|
|
parseProcessedFilter(context, value, result);
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/LayoutConformanceComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using LayoutConformanceComponentDescriptor =
|
|
ConcreteComponentDescriptor<LayoutConformanceShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/LayoutConformanceProps.h}:
|
|
namespace facebook::react {
|
|
struct LayoutConformanceProps final : public YogaStylableProps {
|
|
LayoutConformance mode{LayoutConformance::Strict};
|
|
LayoutConformanceProps() = default;
|
|
LayoutConformanceProps(
|
|
const PropsParserContext& context,
|
|
const LayoutConformanceProps& sourceProps,
|
|
const RawProps& rawProps)
|
|
: YogaStylableProps(context, sourceProps, rawProps),
|
|
mode{convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"mode",
|
|
mode,
|
|
LayoutConformance::Strict)} {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/LayoutConformanceShadowNode.h}:
|
|
namespace facebook::react {
|
|
constexpr const char LayoutConformanceShadowNodeComponentName[] =
|
|
"LayoutConformance";
|
|
class LayoutConformanceShadowNode final
|
|
: public ConcreteShadowNode<
|
|
LayoutConformanceShadowNodeComponentName,
|
|
YogaLayoutableShadowNode,
|
|
LayoutConformanceProps> {
|
|
public:
|
|
using ConcreteShadowNode::ConcreteShadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/PointerEvent.h}:
|
|
namespace facebook::react {
|
|
struct PointerEvent : public EventPayload {
|
|
int pointerId;
|
|
Float pressure;
|
|
std::string pointerType;
|
|
Point clientPoint;
|
|
Point screenPoint;
|
|
Point offsetPoint;
|
|
Float width;
|
|
Float height;
|
|
int tiltX;
|
|
int tiltY;
|
|
int detail;
|
|
int buttons;
|
|
Float tangentialPressure;
|
|
int twist;
|
|
bool ctrlKey;
|
|
bool shiftKey;
|
|
bool altKey;
|
|
bool metaKey;
|
|
bool isPrimary;
|
|
int button;
|
|
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
|
|
EventPayloadType getType() const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/Touch.h}:
|
|
namespace facebook::react {
|
|
using Touch = HostPlatformTouch;
|
|
using Touches = std::unordered_set<Touch, Touch::Hasher, Touch::Comparator>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/TouchEvent.h}:
|
|
namespace facebook::react {
|
|
struct TouchEvent {
|
|
Touches touches;
|
|
Touches changedTouches;
|
|
Touches targetTouches;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/TouchEventEmitter.h}:
|
|
namespace facebook::react {
|
|
using SharedTouchEventEmitter = std::shared_ptr<const TouchEventEmitter>;
|
|
class TouchEventEmitter : public EventEmitter {
|
|
public:
|
|
using EventEmitter::EventEmitter;
|
|
void onTouchStart(TouchEvent event) const;
|
|
void onTouchMove(TouchEvent event) const;
|
|
void onTouchEnd(TouchEvent event) const;
|
|
void onTouchCancel(TouchEvent event) const;
|
|
void onClick(PointerEvent event) const;
|
|
void onPointerCancel(PointerEvent event) const;
|
|
void onPointerDown(PointerEvent event) const;
|
|
void onPointerMove(PointerEvent event) const;
|
|
void onPointerUp(PointerEvent event) const;
|
|
void onPointerEnter(PointerEvent event) const;
|
|
void onPointerLeave(PointerEvent event) const;
|
|
void onPointerOver(PointerEvent event) const;
|
|
void onPointerOut(PointerEvent event) const;
|
|
void onGotPointerCapture(PointerEvent event) const;
|
|
void onLostPointerCapture(PointerEvent event) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/ViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
class ViewComponentDescriptor
|
|
: public ConcreteComponentDescriptor<ViewShadowNode> {
|
|
public:
|
|
ViewComponentDescriptor(const ComponentDescriptorParameters& parameters)
|
|
: ConcreteComponentDescriptor<ViewShadowNode>(parameters) {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/ViewEventEmitter.h}:
|
|
namespace facebook::react {
|
|
using ViewEventEmitter = HostPlatformViewEventEmitter;
|
|
using SharedViewEventEmitter = std::shared_ptr<const ViewEventEmitter>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/ViewProps.h}:
|
|
namespace facebook::react {
|
|
using ViewProps = HostPlatformViewProps;
|
|
using SharedViewProps = std::shared_ptr<const ViewProps>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/ViewPropsInterpolation.h}:
|
|
namespace facebook::react {
|
|
static inline void interpolateViewProps(
|
|
Float animationProgress,
|
|
const Props::Shared& oldPropsShared,
|
|
const Props::Shared& newPropsShared,
|
|
Props::Shared& interpolatedPropsShared,
|
|
const Size& size) {
|
|
const ViewProps* oldViewProps =
|
|
static_cast<const ViewProps*>(oldPropsShared.get());
|
|
const ViewProps* newViewProps =
|
|
static_cast<const ViewProps*>(newPropsShared.get());
|
|
ViewProps* interpolatedProps = const_cast<ViewProps*>(
|
|
static_cast<const ViewProps*>(interpolatedPropsShared.get()));
|
|
interpolatedProps->opacity = oldViewProps->opacity +
|
|
(newViewProps->opacity - oldViewProps->opacity) * animationProgress;
|
|
interpolatedProps->transform = Transform::Interpolate(
|
|
animationProgress,
|
|
oldViewProps->transform,
|
|
newViewProps->transform,
|
|
size);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/ViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
extern const char ViewComponentName[];
|
|
class ViewShadowNodeProps final : public ViewProps {
|
|
public:
|
|
ViewShadowNodeProps() = default;
|
|
ViewShadowNodeProps(
|
|
const PropsParserContext& context,
|
|
const ViewShadowNodeProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
};
|
|
class ViewShadowNode final : public ConcreteViewShadowNode<
|
|
ViewComponentName,
|
|
ViewShadowNodeProps,
|
|
ViewEventEmitter> {
|
|
public:
|
|
ViewShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family,
|
|
ShadowNodeTraits traits);
|
|
ViewShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.h}:
|
|
namespace facebook::react {
|
|
class YogaLayoutableShadowNode : public LayoutableShadowNode {
|
|
public:
|
|
using Shared = std::shared_ptr<const YogaLayoutableShadowNode>;
|
|
using ListOfShared = std::vector<Shared>;
|
|
YogaLayoutableShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family,
|
|
ShadowNodeTraits traits);
|
|
YogaLayoutableShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment);
|
|
void completeClone(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment) override;
|
|
void enableMeasurement();
|
|
void appendChild(const std::shared_ptr<const ShadowNode>& child) override;
|
|
void replaceChild(
|
|
const ShadowNode& oldChild,
|
|
const std::shared_ptr<const ShadowNode>& newChild,
|
|
size_t suggestedIndex = SIZE_MAX) override;
|
|
void updateYogaChildren();
|
|
void updateYogaProps();
|
|
void setSize(Size size) const;
|
|
void setPadding(RectangleEdges<Float> padding) const;
|
|
void setPositionType(YGPositionType positionType) const;
|
|
void dirtyLayout() override;
|
|
bool getIsLayoutClean() const override;
|
|
void layoutTree(
|
|
LayoutContext layoutContext,
|
|
LayoutConstraints layoutConstraints) override;
|
|
void layout(LayoutContext layoutContext) override;
|
|
Rect getContentBounds() const;
|
|
|
|
protected:
|
|
virtual bool shouldNewRevisionDirtyMeasurement(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment) const;
|
|
yoga::Config yogaConfig_;
|
|
mutable yoga::Node yogaNode_;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/YogaStylableProps.h}:
|
|
namespace facebook::react {
|
|
class YogaStylableProps : public Props {
|
|
public:
|
|
YogaStylableProps() = default;
|
|
YogaStylableProps(
|
|
const PropsParserContext& context,
|
|
const YogaStylableProps& sourceProps,
|
|
const RawProps& rawProps,
|
|
const std::function<bool(const std::string&)>& filterObjectKeys =
|
|
nullptr);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
yoga::Style yogaStyle{};
|
|
yoga::Style::Length insetInlineStart;
|
|
yoga::Style::Length insetInlineEnd;
|
|
yoga::Style::Length marginInline;
|
|
yoga::Style::Length marginInlineStart;
|
|
yoga::Style::Length marginInlineEnd;
|
|
yoga::Style::Length marginBlock;
|
|
yoga::Style::Length paddingInline;
|
|
yoga::Style::Length paddingInlineStart;
|
|
yoga::Style::Length paddingInlineEnd;
|
|
yoga::Style::Length paddingBlock;
|
|
yoga::Style::Length insetBlockStart;
|
|
yoga::Style::Length insetBlockEnd;
|
|
yoga::Style::Length marginBlockStart;
|
|
yoga::Style::Length marginBlockEnd;
|
|
yoga::Style::Length paddingBlockStart;
|
|
yoga::Style::Length paddingBlockEnd;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/accessibilityPropsConversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromString(const std::string& string, AccessibilityTraits& result) {
|
|
if (string == "none") {
|
|
result = AccessibilityTraits::None;
|
|
return;
|
|
}
|
|
if (string == "button" || string == "togglebutton") {
|
|
result = AccessibilityTraits::Button;
|
|
return;
|
|
}
|
|
if (string == "link") {
|
|
result = AccessibilityTraits::Link;
|
|
return;
|
|
}
|
|
if (string == "image" || string == "img") {
|
|
result = AccessibilityTraits::Image;
|
|
return;
|
|
}
|
|
if (string == "selected") {
|
|
result = AccessibilityTraits::Selected;
|
|
return;
|
|
}
|
|
if (string == "plays") {
|
|
result = AccessibilityTraits::PlaysSound;
|
|
return;
|
|
}
|
|
if (string == "keyboardkey" || string == "key") {
|
|
result = AccessibilityTraits::KeyboardKey;
|
|
return;
|
|
}
|
|
if (string == "text") {
|
|
result = AccessibilityTraits::StaticText;
|
|
return;
|
|
}
|
|
if (string == "disabled") {
|
|
result = AccessibilityTraits::NotEnabled;
|
|
return;
|
|
}
|
|
if (string == "frequentUpdates") {
|
|
result = AccessibilityTraits::UpdatesFrequently;
|
|
return;
|
|
}
|
|
if (string == "search") {
|
|
result = AccessibilityTraits::SearchField;
|
|
return;
|
|
}
|
|
if (string == "startsMedia") {
|
|
result = AccessibilityTraits::StartsMediaSession;
|
|
return;
|
|
}
|
|
if (string == "adjustable") {
|
|
result = AccessibilityTraits::Adjustable;
|
|
return;
|
|
}
|
|
if (string == "allowsDirectInteraction") {
|
|
result = AccessibilityTraits::AllowsDirectInteraction;
|
|
return;
|
|
}
|
|
if (string == "pageTurn") {
|
|
result = AccessibilityTraits::CausesPageTurn;
|
|
return;
|
|
}
|
|
if (string == "header" || string == "heading") {
|
|
result = AccessibilityTraits::Header;
|
|
return;
|
|
}
|
|
if (string == "imagebutton") {
|
|
result = AccessibilityTraits::Image | AccessibilityTraits::Button;
|
|
return;
|
|
}
|
|
if (string == "summary") {
|
|
result = AccessibilityTraits::SummaryElement;
|
|
return;
|
|
}
|
|
if (string == "switch") {
|
|
result = AccessibilityTraits::Switch;
|
|
return;
|
|
}
|
|
if (string == "tabbar") {
|
|
result = AccessibilityTraits::TabBar;
|
|
return;
|
|
}
|
|
if (string == "progressbar") {
|
|
result = AccessibilityTraits::UpdatesFrequently;
|
|
return;
|
|
}
|
|
result = AccessibilityTraits::None;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AccessibilityTraits& result) {
|
|
if (value.hasType<std::string>()) {
|
|
fromString((std::string)value, result);
|
|
return;
|
|
}
|
|
result = {};
|
|
react_native_expect(value.hasType<std::vector<std::string>>());
|
|
if (value.hasType<std::vector<std::string>>()) {
|
|
auto items = (std::vector<std::string>)value;
|
|
for (auto& item : items) {
|
|
AccessibilityTraits itemAccessibilityTraits;
|
|
fromString(item, itemAccessibilityTraits);
|
|
result = result | itemAccessibilityTraits;
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "AccessibilityTraits parsing: unsupported type";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AccessibilityState& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto selected = map.find("selected");
|
|
if (selected != map.end()) {
|
|
fromRawValue(context, selected->second, result.selected);
|
|
}
|
|
auto disabled = map.find("disabled");
|
|
if (disabled != map.end()) {
|
|
fromRawValue(context, disabled->second, result.disabled);
|
|
}
|
|
auto checked = map.find("checked");
|
|
if (checked != map.end()) {
|
|
if (checked->second.hasType<std::string>()) {
|
|
if ((std::string)checked->second == "mixed") {
|
|
result.checked = AccessibilityState::Mixed;
|
|
} else {
|
|
result.checked = AccessibilityState::None;
|
|
}
|
|
} else if (checked->second.hasType<bool>()) {
|
|
if ((bool)checked->second == true) {
|
|
result.checked = AccessibilityState::Checked;
|
|
} else {
|
|
result.checked = AccessibilityState::Unchecked;
|
|
}
|
|
} else {
|
|
result.checked = AccessibilityState::None;
|
|
}
|
|
}
|
|
auto busy = map.find("busy");
|
|
if (busy != map.end()) {
|
|
fromRawValue(context, busy->second, result.busy);
|
|
}
|
|
auto expanded = map.find("expanded");
|
|
if (expanded != map.end()) {
|
|
fromRawValue(context, expanded->second, result.expanded);
|
|
}
|
|
}
|
|
inline std::string toString(
|
|
const ImportantForAccessibility& importantForAccessibility) {
|
|
switch (importantForAccessibility) {
|
|
case ImportantForAccessibility::Auto:
|
|
return "auto";
|
|
case ImportantForAccessibility::Yes:
|
|
return "yes";
|
|
case ImportantForAccessibility::No:
|
|
return "no";
|
|
case ImportantForAccessibility::NoHideDescendants:
|
|
return "no-hide-descendants";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
ImportantForAccessibility& result) {
|
|
result = ImportantForAccessibility::Auto;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "auto") {
|
|
result = ImportantForAccessibility::Auto;
|
|
} else if (string == "yes") {
|
|
result = ImportantForAccessibility::Yes;
|
|
} else if (string == "no") {
|
|
result = ImportantForAccessibility::No;
|
|
} else if (string == "no-hide-descendants") {
|
|
result = ImportantForAccessibility::NoHideDescendants;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported ImportantForAccessibility value: " << string;
|
|
react_native_expect(false);
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported ImportantForAccessibility type";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AccessibilityAction& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto name = map.find("name");
|
|
react_native_assert(name != map.end() && name->second.hasType<std::string>());
|
|
if (name != map.end()) {
|
|
fromRawValue(context, name->second, result.name);
|
|
}
|
|
auto label = map.find("label");
|
|
if (label != map.end()) {
|
|
if (label->second.hasType<std::string>()) {
|
|
result.label = (std::string)label->second;
|
|
}
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
AccessibilityValue& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto min = map.find("min");
|
|
if (min != map.end()) {
|
|
if (min->second.hasType<int>()) {
|
|
result.min = (int)min->second;
|
|
}
|
|
}
|
|
auto max = map.find("max");
|
|
if (max != map.end()) {
|
|
if (max->second.hasType<int>()) {
|
|
result.max = (int)max->second;
|
|
}
|
|
}
|
|
auto now = map.find("now");
|
|
if (now != map.end()) {
|
|
if (now->second.hasType<int>()) {
|
|
result.now = (int)now->second;
|
|
}
|
|
}
|
|
auto text = map.find("text");
|
|
if (text != map.end()) {
|
|
if (text->second.hasType<std::string>()) {
|
|
result.text = (std::string)text->second;
|
|
}
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AccessibilityLabelledBy& result) {
|
|
if (value.hasType<std::string>()) {
|
|
result.value.push_back((std::string)value);
|
|
} else if (value.hasType<std::vector<std::string>>()) {
|
|
result.value = (std::vector<std::string>)value;
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AccessibilityLiveRegion& result) {
|
|
result = AccessibilityLiveRegion::None;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = AccessibilityLiveRegion::None;
|
|
} else if (string == "polite") {
|
|
result = AccessibilityLiveRegion::Polite;
|
|
} else if (string == "assertive") {
|
|
result = AccessibilityLiveRegion::Assertive;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported AccessibilityLiveRegion value: " << string;
|
|
react_native_expect(false);
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported AccessibilityLiveRegion type";
|
|
}
|
|
}
|
|
inline std::string toString(const AccessibilityRole& accessibilityRole) {
|
|
switch (accessibilityRole) {
|
|
case AccessibilityRole::None:
|
|
return "none";
|
|
case AccessibilityRole::Button:
|
|
return "button";
|
|
case AccessibilityRole::Dropdownlist:
|
|
return "dropdownlist";
|
|
case AccessibilityRole::Togglebutton:
|
|
return "togglebutton";
|
|
case AccessibilityRole::Link:
|
|
return "link";
|
|
case AccessibilityRole::Search:
|
|
return "search";
|
|
case AccessibilityRole::Image:
|
|
return "image";
|
|
case AccessibilityRole::Keyboardkey:
|
|
return "keyboardkey";
|
|
case AccessibilityRole::Text:
|
|
return "text";
|
|
case AccessibilityRole::Adjustable:
|
|
return "adjustable";
|
|
case AccessibilityRole::Imagebutton:
|
|
return "imagebutton";
|
|
case AccessibilityRole::Header:
|
|
return "header";
|
|
case AccessibilityRole::Summary:
|
|
return "summary";
|
|
case AccessibilityRole::Alert:
|
|
return "alert";
|
|
case AccessibilityRole::Checkbox:
|
|
return "checkbox";
|
|
case AccessibilityRole::Combobox:
|
|
return "combobox";
|
|
case AccessibilityRole::Menu:
|
|
return "menu";
|
|
case AccessibilityRole::Menubar:
|
|
return "menubar";
|
|
case AccessibilityRole::Menuitem:
|
|
return "menuitem";
|
|
case AccessibilityRole::Progressbar:
|
|
return "progressbar";
|
|
case AccessibilityRole::Radio:
|
|
return "radio";
|
|
case AccessibilityRole::Radiogroup:
|
|
return "radiogroup";
|
|
case AccessibilityRole::Scrollbar:
|
|
return "scrollbar";
|
|
case AccessibilityRole::Spinbutton:
|
|
return "spinbutton";
|
|
case AccessibilityRole::Switch:
|
|
return "switch";
|
|
case AccessibilityRole::Tab:
|
|
return "tab";
|
|
case AccessibilityRole::Tabbar:
|
|
return "tabbar";
|
|
case AccessibilityRole::Tablist:
|
|
return "tablist";
|
|
case AccessibilityRole::Timer:
|
|
return "timer";
|
|
case AccessibilityRole::List:
|
|
return "timer";
|
|
case AccessibilityRole::Toolbar:
|
|
return "toolbar";
|
|
case AccessibilityRole::Grid:
|
|
return "grid";
|
|
case AccessibilityRole::Pager:
|
|
return "pager";
|
|
case AccessibilityRole::Scrollview:
|
|
return "scrollview";
|
|
case AccessibilityRole::Horizontalscrollview:
|
|
return "horizontalscrollview";
|
|
case AccessibilityRole::Viewgroup:
|
|
return "viewgroup";
|
|
case AccessibilityRole::Webview:
|
|
return "webview";
|
|
case AccessibilityRole::Drawerlayout:
|
|
return "drawerlayout";
|
|
case AccessibilityRole::Slidingdrawer:
|
|
return "slidingdrawer";
|
|
case AccessibilityRole::Iconmenu:
|
|
return "iconmenu";
|
|
}
|
|
LOG(ERROR) << "Unsupported AccessibilityRole value";
|
|
react_native_expect(false);
|
|
return "none";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
AccessibilityRole& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "none") {
|
|
result = AccessibilityRole::None;
|
|
} else if (string == "button") {
|
|
result = AccessibilityRole::Button;
|
|
} else if (string == "dropdownlist") {
|
|
result = AccessibilityRole::Dropdownlist;
|
|
} else if (string == "togglebutton") {
|
|
result = AccessibilityRole::Togglebutton;
|
|
} else if (string == "link") {
|
|
result = AccessibilityRole::Link;
|
|
} else if (string == "search") {
|
|
result = AccessibilityRole::Search;
|
|
} else if (string == "image") {
|
|
result = AccessibilityRole::Image;
|
|
} else if (string == "keyboardkey") {
|
|
result = AccessibilityRole::Keyboardkey;
|
|
} else if (string == "text") {
|
|
result = AccessibilityRole::Text;
|
|
} else if (string == "adjustable") {
|
|
result = AccessibilityRole::Adjustable;
|
|
} else if (string == "imagebutton") {
|
|
result = AccessibilityRole::Imagebutton;
|
|
} else if (string == "header") {
|
|
result = AccessibilityRole::Header;
|
|
} else if (string == "summary") {
|
|
result = AccessibilityRole::Summary;
|
|
} else if (string == "alert") {
|
|
result = AccessibilityRole::Alert;
|
|
} else if (string == "checkbox") {
|
|
result = AccessibilityRole::Checkbox;
|
|
} else if (string == "combobox") {
|
|
result = AccessibilityRole::Combobox;
|
|
} else if (string == "menu") {
|
|
result = AccessibilityRole::Menu;
|
|
} else if (string == "menubar") {
|
|
result = AccessibilityRole::Menubar;
|
|
} else if (string == "menuitem") {
|
|
result = AccessibilityRole::Menuitem;
|
|
} else if (string == "progressbar") {
|
|
result = AccessibilityRole::Progressbar;
|
|
} else if (string == "radio") {
|
|
result = AccessibilityRole::Radio;
|
|
} else if (string == "radiogroup") {
|
|
result = AccessibilityRole::Radiogroup;
|
|
} else if (string == "scrollbar") {
|
|
result = AccessibilityRole::Scrollbar;
|
|
} else if (string == "spinbutton") {
|
|
result = AccessibilityRole::Spinbutton;
|
|
} else if (string == "switch") {
|
|
result = AccessibilityRole::Switch;
|
|
} else if (string == "tab") {
|
|
result = AccessibilityRole::Tab;
|
|
} else if (string == "tabbar") {
|
|
result = AccessibilityRole::Tabbar;
|
|
} else if (string == "tablist") {
|
|
result = AccessibilityRole::Tablist;
|
|
} else if (string == "timer") {
|
|
result = AccessibilityRole::Timer;
|
|
} else if (string == "toolbar") {
|
|
result = AccessibilityRole::Toolbar;
|
|
} else if (string == "grid") {
|
|
result = AccessibilityRole::Grid;
|
|
} else if (string == "pager") {
|
|
result = AccessibilityRole::Pager;
|
|
} else if (string == "scrollview") {
|
|
result = AccessibilityRole::Scrollview;
|
|
} else if (string == "horizontalscrollview") {
|
|
result = AccessibilityRole::Horizontalscrollview;
|
|
} else if (string == "viewgroup") {
|
|
result = AccessibilityRole::Viewgroup;
|
|
} else if (string == "webview") {
|
|
result = AccessibilityRole::Webview;
|
|
} else if (string == "drawerlayout") {
|
|
result = AccessibilityRole::Drawerlayout;
|
|
} else if (string == "slidingdrawer") {
|
|
result = AccessibilityRole::Slidingdrawer;
|
|
} else if (string == "iconmenu") {
|
|
result = AccessibilityRole::Iconmenu;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported AccessibilityRole value: " << string;
|
|
react_native_expect(false);
|
|
result = AccessibilityRole::None;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported AccessibilityRole type";
|
|
react_native_expect(false);
|
|
result = AccessibilityRole::None;
|
|
}
|
|
inline std::string toString(const Role& role) {
|
|
switch (role) {
|
|
case Role::Alert:
|
|
return "alert";
|
|
case Role::Alertdialog:
|
|
return "alertdialog";
|
|
case Role::Application:
|
|
return "application";
|
|
case Role::Article:
|
|
return "article";
|
|
case Role::Banner:
|
|
return "banner";
|
|
case Role::Button:
|
|
return "button";
|
|
case Role::Cell:
|
|
return "cell";
|
|
case Role::Checkbox:
|
|
return "checkbox";
|
|
case Role::Columnheader:
|
|
return "columnheader";
|
|
case Role::Combobox:
|
|
return "combobox";
|
|
case Role::Complementary:
|
|
return "complementary";
|
|
case Role::Contentinfo:
|
|
return "contentinfo";
|
|
case Role::Definition:
|
|
return "definition";
|
|
case Role::Dialog:
|
|
return "dialog";
|
|
case Role::Directory:
|
|
return "directory";
|
|
case Role::Document:
|
|
return "document";
|
|
case Role::Feed:
|
|
return "feed";
|
|
case Role::Figure:
|
|
return "figure";
|
|
case Role::Form:
|
|
return "form";
|
|
case Role::Grid:
|
|
return "grid";
|
|
case Role::Group:
|
|
return "group";
|
|
case Role::Heading:
|
|
return "heading";
|
|
case Role::Img:
|
|
return "img";
|
|
case Role::Link:
|
|
return "link";
|
|
case Role::List:
|
|
return "list";
|
|
case Role::Listitem:
|
|
return "listitem";
|
|
case Role::Log:
|
|
return "log";
|
|
case Role::Main:
|
|
return "main";
|
|
case Role::Marquee:
|
|
return "marquee";
|
|
case Role::Math:
|
|
return "math";
|
|
case Role::Menu:
|
|
return "menu";
|
|
case Role::Menubar:
|
|
return "menubar";
|
|
case Role::Menuitem:
|
|
return "menuitem";
|
|
case Role::Meter:
|
|
return "meter";
|
|
case Role::Navigation:
|
|
return "navigation";
|
|
case Role::None:
|
|
return "none";
|
|
case Role::Note:
|
|
return "note";
|
|
case Role::Option:
|
|
return "option";
|
|
case Role::Presentation:
|
|
return "presentation";
|
|
case Role::Progressbar:
|
|
return "progressbar";
|
|
case Role::Radio:
|
|
return "radio";
|
|
case Role::Radiogroup:
|
|
return "radiogroup";
|
|
case Role::Region:
|
|
return "region";
|
|
case Role::Row:
|
|
return "row";
|
|
case Role::Rowgroup:
|
|
return "rowgroup";
|
|
case Role::Rowheader:
|
|
return "rowheader";
|
|
case Role::Scrollbar:
|
|
return "scrollbar";
|
|
case Role::Searchbox:
|
|
return "searchbox";
|
|
case Role::Separator:
|
|
return "separator";
|
|
case Role::Slider:
|
|
return "slider";
|
|
case Role::Spinbutton:
|
|
return "spinbutton";
|
|
case Role::Status:
|
|
return "status";
|
|
case Role::Summary:
|
|
return "summary";
|
|
case Role::Switch:
|
|
return "switch";
|
|
case Role::Tab:
|
|
return "tab";
|
|
case Role::Table:
|
|
return "table";
|
|
case Role::Tablist:
|
|
return "tablist";
|
|
case Role::Tabpanel:
|
|
return "tabpanel";
|
|
case Role::Term:
|
|
return "term";
|
|
case Role::Timer:
|
|
return "timer";
|
|
case Role::Toolbar:
|
|
return "toolbar";
|
|
case Role::Tooltip:
|
|
return "tooltip";
|
|
case Role::Tree:
|
|
return "tree";
|
|
case Role::Treegrid:
|
|
return "treegrid";
|
|
case Role::Treeitem:
|
|
return "treeitem";
|
|
}
|
|
LOG(ERROR) << "Unsupported Role value";
|
|
react_native_expect(false);
|
|
return "none";
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Role& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (value.hasType<std::string>()) {
|
|
auto string = (std::string)value;
|
|
if (string == "alert") {
|
|
result = Role::Alert;
|
|
} else if (string == "alertdialog") {
|
|
result = Role::Alertdialog;
|
|
} else if (string == "application") {
|
|
result = Role::Application;
|
|
} else if (string == "article") {
|
|
result = Role::Article;
|
|
} else if (string == "banner") {
|
|
result = Role::Banner;
|
|
} else if (string == "button") {
|
|
result = Role::Button;
|
|
} else if (string == "cell") {
|
|
result = Role::Cell;
|
|
} else if (string == "checkbox") {
|
|
result = Role::Checkbox;
|
|
} else if (string == "columnheader") {
|
|
result = Role::Columnheader;
|
|
} else if (string == "combobox") {
|
|
result = Role::Combobox;
|
|
} else if (string == "complementary") {
|
|
result = Role::Complementary;
|
|
} else if (string == "contentinfo") {
|
|
result = Role::Contentinfo;
|
|
} else if (string == "definition") {
|
|
result = Role::Definition;
|
|
} else if (string == "dialog") {
|
|
result = Role::Dialog;
|
|
} else if (string == "directory") {
|
|
result = Role::Directory;
|
|
} else if (string == "document") {
|
|
result = Role::Document;
|
|
} else if (string == "feed") {
|
|
result = Role::Feed;
|
|
} else if (string == "figure") {
|
|
result = Role::Figure;
|
|
} else if (string == "form") {
|
|
result = Role::Form;
|
|
} else if (string == "grid") {
|
|
result = Role::Grid;
|
|
} else if (string == "group") {
|
|
result = Role::Group;
|
|
} else if (string == "heading") {
|
|
result = Role::Heading;
|
|
} else if (string == "img") {
|
|
result = Role::Img;
|
|
} else if (string == "link") {
|
|
result = Role::Link;
|
|
} else if (string == "list") {
|
|
result = Role::List;
|
|
} else if (string == "listitem") {
|
|
result = Role::Listitem;
|
|
} else if (string == "log") {
|
|
result = Role::Log;
|
|
} else if (string == "main") {
|
|
result = Role::Main;
|
|
} else if (string == "marquee") {
|
|
result = Role::Marquee;
|
|
} else if (string == "math") {
|
|
result = Role::Math;
|
|
} else if (string == "menu") {
|
|
result = Role::Menu;
|
|
} else if (string == "menubar") {
|
|
result = Role::Menubar;
|
|
} else if (string == "menuitem") {
|
|
result = Role::Menuitem;
|
|
} else if (string == "meter") {
|
|
result = Role::Meter;
|
|
} else if (string == "navigation") {
|
|
result = Role::Navigation;
|
|
} else if (string == "none") {
|
|
result = Role::None;
|
|
} else if (string == "note") {
|
|
result = Role::Note;
|
|
} else if (string == "option") {
|
|
result = Role::Option;
|
|
} else if (string == "presentation") {
|
|
result = Role::Presentation;
|
|
} else if (string == "progressbar") {
|
|
result = Role::Progressbar;
|
|
} else if (string == "radio") {
|
|
result = Role::Radio;
|
|
} else if (string == "radiogroup") {
|
|
result = Role::Radiogroup;
|
|
} else if (string == "region") {
|
|
result = Role::Region;
|
|
} else if (string == "row") {
|
|
result = Role::Row;
|
|
} else if (string == "rowgroup") {
|
|
result = Role::Rowgroup;
|
|
} else if (string == "rowheader") {
|
|
result = Role::Rowheader;
|
|
} else if (string == "scrollbar") {
|
|
result = Role::Scrollbar;
|
|
} else if (string == "searchbox") {
|
|
result = Role::Searchbox;
|
|
} else if (string == "separator") {
|
|
result = Role::Separator;
|
|
} else if (string == "slider") {
|
|
result = Role::Slider;
|
|
} else if (string == "spinbutton") {
|
|
result = Role::Spinbutton;
|
|
} else if (string == "status") {
|
|
result = Role::Status;
|
|
} else if (string == "summary") {
|
|
result = Role::Summary;
|
|
} else if (string == "switch") {
|
|
result = Role::Switch;
|
|
} else if (string == "tab") {
|
|
result = Role::Tab;
|
|
} else if (string == "table") {
|
|
result = Role::Table;
|
|
} else if (string == "tablist") {
|
|
result = Role::Tablist;
|
|
} else if (string == "tabpanel") {
|
|
result = Role::Tabpanel;
|
|
} else if (string == "term") {
|
|
result = Role::Term;
|
|
} else if (string == "timer") {
|
|
result = Role::Timer;
|
|
} else if (string == "toolbar") {
|
|
result = Role::Toolbar;
|
|
} else if (string == "tooltip") {
|
|
result = Role::Tooltip;
|
|
} else if (string == "tree") {
|
|
result = Role::Tree;
|
|
} else if (string == "treegrid") {
|
|
result = Role::Treegrid;
|
|
} else if (string == "treeitem") {
|
|
result = Role::Treeitem;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Role value: " << string;
|
|
react_native_expect(false);
|
|
result = Role::None;
|
|
}
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported Role type";
|
|
react_native_expect(false);
|
|
result = Role::None;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/conversions.h}:
|
|
namespace facebook::react {
|
|
inline Float floatFromYogaFloat(float value) {
|
|
static_assert(
|
|
YGUndefined != YGUndefined,
|
|
"The code of this function assumes that YGUndefined is NaN.");
|
|
if (std::isnan(value)) {
|
|
return std::numeric_limits<Float>::infinity();
|
|
}
|
|
return (Float)value;
|
|
}
|
|
inline float yogaFloatFromFloat(Float value) {
|
|
if (!std::isfinite(value)) {
|
|
return YGUndefined;
|
|
}
|
|
return (float)value;
|
|
}
|
|
inline Float floatFromYogaOptionalFloat(yoga::FloatOptional value) {
|
|
if (value.isUndefined()) {
|
|
return std::numeric_limits<Float>::quiet_NaN();
|
|
}
|
|
return floatFromYogaFloat(value.unwrap());
|
|
}
|
|
inline yoga::FloatOptional yogaOptionalFloatFromFloat(Float value) {
|
|
if (std::isnan(value)) {
|
|
return yoga::FloatOptional();
|
|
}
|
|
return yoga::FloatOptional((float)value);
|
|
}
|
|
inline std::optional<Float> optionalFloatFromYogaValue(
|
|
const yoga::Style::Length& length,
|
|
std::optional<Float> base = {}) {
|
|
if (length.isPoints()) {
|
|
return floatFromYogaOptionalFloat(length.value());
|
|
} else if (length.isPercent()) {
|
|
return base.has_value()
|
|
? std::optional<Float>(
|
|
base.value() * floatFromYogaOptionalFloat(length.value()))
|
|
: std::optional<Float>();
|
|
} else {
|
|
return {};
|
|
}
|
|
}
|
|
static inline PositionType positionTypeFromYogaPositionType(
|
|
yoga::PositionType positionType) {
|
|
switch (positionType) {
|
|
case yoga::PositionType::Static:
|
|
return PositionType::Static;
|
|
case yoga::PositionType::Relative:
|
|
return PositionType::Relative;
|
|
case yoga::PositionType::Absolute:
|
|
return PositionType::Absolute;
|
|
}
|
|
}
|
|
inline DisplayType displayTypeFromYGDisplay(YGDisplay display) {
|
|
switch (display) {
|
|
case YGDisplayNone:
|
|
return DisplayType::None;
|
|
case YGDisplayContents:
|
|
return DisplayType::Contents;
|
|
case YGDisplayFlex:
|
|
return DisplayType::Flex;
|
|
}
|
|
}
|
|
inline LayoutMetrics layoutMetricsFromYogaNode(yoga::Node& yogaNode) {
|
|
auto layoutMetrics = LayoutMetrics{};
|
|
layoutMetrics.frame = Rect{
|
|
Point{
|
|
floatFromYogaFloat(YGNodeLayoutGetLeft(&yogaNode)),
|
|
floatFromYogaFloat(YGNodeLayoutGetTop(&yogaNode))},
|
|
Size{
|
|
floatFromYogaFloat(YGNodeLayoutGetWidth(&yogaNode)),
|
|
floatFromYogaFloat(YGNodeLayoutGetHeight(&yogaNode))}};
|
|
layoutMetrics.borderWidth = EdgeInsets{
|
|
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeLeft)),
|
|
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeTop)),
|
|
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeRight)),
|
|
floatFromYogaFloat(YGNodeLayoutGetBorder(&yogaNode, YGEdgeBottom))};
|
|
layoutMetrics.contentInsets = EdgeInsets{
|
|
layoutMetrics.borderWidth.left +
|
|
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeLeft)),
|
|
layoutMetrics.borderWidth.top +
|
|
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeTop)),
|
|
layoutMetrics.borderWidth.right +
|
|
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeRight)),
|
|
layoutMetrics.borderWidth.bottom +
|
|
floatFromYogaFloat(YGNodeLayoutGetPadding(&yogaNode, YGEdgeBottom))};
|
|
layoutMetrics.displayType =
|
|
displayTypeFromYGDisplay(YGNodeStyleGetDisplay(&yogaNode));
|
|
layoutMetrics.positionType =
|
|
positionTypeFromYogaPositionType(yogaNode.style().positionType());
|
|
layoutMetrics.layoutDirection =
|
|
YGNodeLayoutGetDirection(&yogaNode) == YGDirectionRTL
|
|
? LayoutDirection::RightToLeft
|
|
: LayoutDirection::LeftToRight;
|
|
return layoutMetrics;
|
|
}
|
|
inline YGDirection yogaDirectionFromLayoutDirection(LayoutDirection direction) {
|
|
switch (direction) {
|
|
case LayoutDirection::Undefined:
|
|
return YGDirectionInherit;
|
|
case LayoutDirection::LeftToRight:
|
|
return YGDirectionLTR;
|
|
case LayoutDirection::RightToLeft:
|
|
return YGDirectionRTL;
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Direction& result) {
|
|
result = yoga::Direction::Inherit;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "inherit") {
|
|
result = yoga::Direction::Inherit;
|
|
return;
|
|
}
|
|
if (stringValue == "ltr") {
|
|
result = yoga::Direction::LTR;
|
|
return;
|
|
}
|
|
if (stringValue == "rtl") {
|
|
result = yoga::Direction::RTL;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::Direction: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::FlexDirection& result) {
|
|
result = yoga::FlexDirection::Column;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "row") {
|
|
result = yoga::FlexDirection::Row;
|
|
return;
|
|
}
|
|
if (stringValue == "column") {
|
|
result = yoga::FlexDirection::Column;
|
|
return;
|
|
}
|
|
if (stringValue == "column-reverse") {
|
|
result = yoga::FlexDirection::ColumnReverse;
|
|
return;
|
|
}
|
|
if (stringValue == "row-reverse") {
|
|
result = yoga::FlexDirection::RowReverse;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::FlexDirection: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
yoga::BoxSizing& result) {
|
|
result = yoga::BoxSizing::BorderBox;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "border-box") {
|
|
result = yoga::BoxSizing::BorderBox;
|
|
return;
|
|
}
|
|
if (stringValue == "content-box") {
|
|
result = yoga::BoxSizing::ContentBox;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::BoxSizing: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Justify& result) {
|
|
result = yoga::Justify::FlexStart;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "flex-start") {
|
|
result = yoga::Justify::FlexStart;
|
|
return;
|
|
}
|
|
if (stringValue == "center") {
|
|
result = yoga::Justify::Center;
|
|
return;
|
|
}
|
|
if (stringValue == "flex-end") {
|
|
result = yoga::Justify::FlexEnd;
|
|
return;
|
|
}
|
|
if (stringValue == "space-between") {
|
|
result = yoga::Justify::SpaceBetween;
|
|
return;
|
|
}
|
|
if (stringValue == "space-around") {
|
|
result = yoga::Justify::SpaceAround;
|
|
return;
|
|
}
|
|
if (stringValue == "space-evenly") {
|
|
result = yoga::Justify::SpaceEvenly;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::Justify: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Align& result) {
|
|
result = yoga::Align::Stretch;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "auto") {
|
|
result = yoga::Align::Auto;
|
|
return;
|
|
}
|
|
if (stringValue == "flex-start") {
|
|
result = yoga::Align::FlexStart;
|
|
return;
|
|
}
|
|
if (stringValue == "center") {
|
|
result = yoga::Align::Center;
|
|
return;
|
|
}
|
|
if (stringValue == "flex-end") {
|
|
result = yoga::Align::FlexEnd;
|
|
return;
|
|
}
|
|
if (stringValue == "stretch") {
|
|
result = yoga::Align::Stretch;
|
|
return;
|
|
}
|
|
if (stringValue == "baseline") {
|
|
result = yoga::Align::Baseline;
|
|
return;
|
|
}
|
|
if (stringValue == "space-between") {
|
|
result = yoga::Align::SpaceBetween;
|
|
return;
|
|
}
|
|
if (stringValue == "space-around") {
|
|
result = yoga::Align::SpaceAround;
|
|
return;
|
|
}
|
|
if (stringValue == "space-evenly") {
|
|
result = yoga::Align::SpaceEvenly;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::Align: " << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::PositionType& result) {
|
|
result = yoga::PositionType::Relative;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "static") {
|
|
result = yoga::PositionType::Static;
|
|
return;
|
|
}
|
|
if (stringValue == "relative") {
|
|
result = yoga::PositionType::Relative;
|
|
return;
|
|
}
|
|
if (stringValue == "absolute") {
|
|
result = yoga::PositionType::Absolute;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::PositionType: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Wrap& result) {
|
|
result = yoga::Wrap::NoWrap;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "nowrap") {
|
|
result = yoga::Wrap::NoWrap;
|
|
return;
|
|
}
|
|
if (stringValue == "wrap") {
|
|
result = yoga::Wrap::Wrap;
|
|
return;
|
|
}
|
|
if (stringValue == "wrap-reverse") {
|
|
result = yoga::Wrap::WrapReverse;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::Wrap: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Overflow& result) {
|
|
result = yoga::Overflow::Visible;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "visible") {
|
|
result = yoga::Overflow::Visible;
|
|
return;
|
|
}
|
|
if (stringValue == "hidden") {
|
|
result = yoga::Overflow::Hidden;
|
|
return;
|
|
}
|
|
if (stringValue == "scroll") {
|
|
result = yoga::Overflow::Scroll;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::Overflow:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Display& result) {
|
|
result = yoga::Display::Flex;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "flex") {
|
|
result = yoga::Display::Flex;
|
|
return;
|
|
}
|
|
if (stringValue == "none") {
|
|
result = yoga::Display::None;
|
|
return;
|
|
}
|
|
if (stringValue == "contents") {
|
|
result = yoga::Display::Contents;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse yoga::Display: " << stringValue;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
yoga::Style::SizeLength& result) {
|
|
if (value.hasType<Float>()) {
|
|
result = yoga::StyleSizeLength::points((float)value);
|
|
return;
|
|
} else if (value.hasType<std::string>()) {
|
|
const auto stringValue = (std::string)value;
|
|
if (stringValue == "auto") {
|
|
result = yoga::StyleSizeLength::ofAuto();
|
|
return;
|
|
} else if (stringValue == "max-content") {
|
|
result = yoga::StyleSizeLength::ofMaxContent();
|
|
return;
|
|
} else if (stringValue == "stretch") {
|
|
result = yoga::StyleSizeLength::ofStretch();
|
|
return;
|
|
} else if (stringValue == "fit-content") {
|
|
result = yoga::StyleSizeLength::ofFitContent();
|
|
return;
|
|
} else {
|
|
auto parsed = parseCSSProperty<CSSNumber, CSSPercentage>(stringValue);
|
|
if (std::holds_alternative<CSSPercentage>(parsed)) {
|
|
result = yoga::StyleSizeLength::percent(
|
|
std::get<CSSPercentage>(parsed).value);
|
|
return;
|
|
} else if (std::holds_alternative<CSSNumber>(parsed)) {
|
|
result =
|
|
yoga::StyleSizeLength::points(std::get<CSSNumber>(parsed).value);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
result = yoga::StyleSizeLength::undefined();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::Style::Length& result) {
|
|
if (value.hasType<Float>()) {
|
|
result = yoga::StyleLength::points((float)value);
|
|
return;
|
|
} else if (value.hasType<std::string>()) {
|
|
const auto stringValue = (std::string)value;
|
|
if (stringValue == "auto") {
|
|
result = yoga::StyleLength::ofAuto();
|
|
return;
|
|
} else {
|
|
auto parsed = parseCSSProperty<CSSNumber, CSSPercentage>(stringValue);
|
|
if (std::holds_alternative<CSSPercentage>(parsed)) {
|
|
result =
|
|
yoga::StyleLength::percent(std::get<CSSPercentage>(parsed).value);
|
|
return;
|
|
} else if (std::holds_alternative<CSSNumber>(parsed)) {
|
|
result = yoga::StyleLength::points(std::get<CSSNumber>(parsed).value);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
result = yoga::StyleLength::undefined();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
YGValue& result) {
|
|
yoga::Style::Length length{};
|
|
fromRawValue(context, value, length);
|
|
result = (YGValue)length;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
yoga::FloatOptional& result) {
|
|
result = value.hasType<float>() ? yoga::FloatOptional((float)value)
|
|
: yoga::FloatOptional();
|
|
}
|
|
inline std::optional<Float> toRadians(const RawValue& value) {
|
|
if (value.hasType<Float>()) {
|
|
return (Float)value;
|
|
}
|
|
if (!value.hasType<std::string>()) {
|
|
return {};
|
|
}
|
|
auto angle = parseCSSProperty<CSSAngle>((std::string)value);
|
|
if (std::holds_alternative<CSSAngle>(angle)) {
|
|
return std::get<CSSAngle>(angle).degrees * M_PI / 180.0f;
|
|
}
|
|
return {};
|
|
}
|
|
inline ValueUnit toValueUnit(const RawValue& value) {
|
|
if (value.hasType<Float>()) {
|
|
return ValueUnit((Float)value, UnitType::Point);
|
|
}
|
|
if (!value.hasType<std::string>()) {
|
|
return {};
|
|
}
|
|
auto pct = parseCSSProperty<CSSPercentage>((std::string)value);
|
|
if (std::holds_alternative<CSSPercentage>(pct)) {
|
|
return ValueUnit(std::get<CSSPercentage>(pct).value, UnitType::Percent);
|
|
}
|
|
return {};
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
ValueUnit& result) {
|
|
result = toValueUnit(value);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Transform& result) {
|
|
auto transformMatrix = Transform{};
|
|
react_native_expect(value.hasType<std::vector<RawValue>>());
|
|
if (!value.hasType<std::vector<RawValue>>()) {
|
|
result = transformMatrix;
|
|
return;
|
|
}
|
|
auto configurations = static_cast<std::vector<RawValue>>(value);
|
|
for (const auto& configuration : configurations) {
|
|
if (!configuration.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto configurationPair =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(configuration);
|
|
if (configurationPair.size() != 1) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto pair = configurationPair.begin();
|
|
auto operation = pair->first;
|
|
auto& parameters = pair->second;
|
|
auto Zero = ValueUnit(0, UnitType::Point);
|
|
auto One = ValueUnit(1, UnitType::Point);
|
|
if (operation == "matrix") {
|
|
if (configurations.size() > 1) {
|
|
result = {};
|
|
return;
|
|
}
|
|
if (!parameters.hasType<std::vector<Float>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto numbers = (std::vector<Float>)parameters;
|
|
if (numbers.size() != 9 && numbers.size() != 16) {
|
|
result = {};
|
|
return;
|
|
}
|
|
size_t i = 0;
|
|
for (auto number : numbers) {
|
|
transformMatrix.matrix[i++] = number;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Arbitrary, Zero, Zero, Zero});
|
|
} else if (operation == "perspective") {
|
|
if (!parameters.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Perspective,
|
|
ValueUnit((Float)parameters, UnitType::Point),
|
|
Zero,
|
|
Zero});
|
|
} else if (operation == "rotateX") {
|
|
auto radians = toRadians(parameters);
|
|
if (!radians.has_value()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Rotate,
|
|
ValueUnit(*radians, UnitType::Point),
|
|
Zero,
|
|
Zero});
|
|
} else if (operation == "rotateY") {
|
|
auto radians = toRadians(parameters);
|
|
if (!radians.has_value()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Rotate,
|
|
Zero,
|
|
ValueUnit(*radians, UnitType::Point),
|
|
Zero});
|
|
} else if (operation == "rotateZ" || operation == "rotate") {
|
|
auto radians = toRadians(parameters);
|
|
if (!radians.has_value()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Rotate,
|
|
Zero,
|
|
Zero,
|
|
ValueUnit(*radians, UnitType::Point)});
|
|
} else if (operation == "scale") {
|
|
if (!parameters.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto number = ValueUnit((Float)parameters, UnitType::Point);
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Scale, number, number, number});
|
|
} else if (operation == "scaleX") {
|
|
if (!parameters.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Scale,
|
|
ValueUnit((Float)parameters, UnitType::Point),
|
|
One,
|
|
One});
|
|
} else if (operation == "scaleY") {
|
|
if (!parameters.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Scale,
|
|
One,
|
|
ValueUnit((Float)parameters, UnitType::Point),
|
|
One});
|
|
} else if (operation == "scaleZ") {
|
|
if (!parameters.hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Scale,
|
|
One,
|
|
One,
|
|
ValueUnit((Float)parameters, UnitType::Point)});
|
|
} else if (operation == "translate") {
|
|
if (!parameters.hasType<std::vector<RawValue>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto numbers = (std::vector<RawValue>)parameters;
|
|
if (numbers.size() != 2) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto valueX = toValueUnit(numbers[0]);
|
|
if (!valueX) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto valueY = toValueUnit(numbers[1]);
|
|
if (!valueY) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Translate, valueX, valueY, Zero});
|
|
} else if (operation == "translateX") {
|
|
auto valueX = toValueUnit(parameters);
|
|
if (!valueX) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Translate, valueX, Zero, Zero});
|
|
} else if (operation == "translateY") {
|
|
auto valueY = toValueUnit(parameters);
|
|
if (!valueY) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Translate, Zero, valueY, Zero});
|
|
} else if (operation == "skewX") {
|
|
auto radians = toRadians(parameters);
|
|
if (!radians.has_value()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Skew,
|
|
ValueUnit(*radians, UnitType::Point),
|
|
Zero,
|
|
Zero});
|
|
} else if (operation == "skewY") {
|
|
auto radians = toRadians(parameters);
|
|
if (!radians.has_value()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformMatrix.operations.push_back(TransformOperation{
|
|
TransformOperationType::Skew,
|
|
Zero,
|
|
ValueUnit(*radians, UnitType::Point),
|
|
Zero});
|
|
}
|
|
}
|
|
result = transformMatrix;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
TransformOrigin& result) {
|
|
if (!value.hasType<std::vector<RawValue>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto origins = (std::vector<RawValue>)value;
|
|
if (origins.size() != 3) {
|
|
result = {};
|
|
return;
|
|
}
|
|
TransformOrigin transformOrigin;
|
|
for (size_t i = 0; i < 2; i++) {
|
|
auto origin = toValueUnit(origins[i]);
|
|
if (!origin) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformOrigin.xy[i] = origin;
|
|
}
|
|
if (!origins[2].hasType<Float>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
transformOrigin.z = (Float)origins[2];
|
|
result = transformOrigin;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
PointerEventsMode& result) {
|
|
result = PointerEventsMode::Auto;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "auto") {
|
|
result = PointerEventsMode::Auto;
|
|
return;
|
|
}
|
|
if (stringValue == "none") {
|
|
result = PointerEventsMode::None;
|
|
return;
|
|
}
|
|
if (stringValue == "box-none") {
|
|
result = PointerEventsMode::BoxNone;
|
|
return;
|
|
}
|
|
if (stringValue == "box-only") {
|
|
result = PointerEventsMode::BoxOnly;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse PointerEventsMode:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline std::string toString(const PointerEventsMode& value) {
|
|
switch (value) {
|
|
case PointerEventsMode::Auto:
|
|
return "auto";
|
|
case PointerEventsMode::None:
|
|
return "none";
|
|
case PointerEventsMode::BoxNone:
|
|
return "box-none";
|
|
case PointerEventsMode::BoxOnly:
|
|
return "box-only";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
BackfaceVisibility& result) {
|
|
result = BackfaceVisibility::Auto;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "auto") {
|
|
result = BackfaceVisibility::Auto;
|
|
return;
|
|
}
|
|
if (stringValue == "visible") {
|
|
result = BackfaceVisibility::Visible;
|
|
return;
|
|
}
|
|
if (stringValue == "hidden") {
|
|
result = BackfaceVisibility::Hidden;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse BackfaceVisibility:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
BorderCurve& result) {
|
|
result = BorderCurve::Circular;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "circular") {
|
|
result = BorderCurve::Circular;
|
|
return;
|
|
}
|
|
if (stringValue == "continuous") {
|
|
result = BorderCurve::Continuous;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse BorderCurve:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
BorderStyle& result) {
|
|
result = BorderStyle::Solid;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "solid") {
|
|
result = BorderStyle::Solid;
|
|
return;
|
|
}
|
|
if (stringValue == "dotted") {
|
|
result = BorderStyle::Dotted;
|
|
return;
|
|
}
|
|
if (stringValue == "dashed") {
|
|
result = BorderStyle::Dashed;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse BorderStyle:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
OutlineStyle& result) {
|
|
result = OutlineStyle::Solid;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "solid") {
|
|
result = OutlineStyle::Solid;
|
|
return;
|
|
}
|
|
if (stringValue == "dotted") {
|
|
result = OutlineStyle::Dotted;
|
|
return;
|
|
}
|
|
if (stringValue == "dashed") {
|
|
result = OutlineStyle::Dashed;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse OutlineStyle:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Cursor& result) {
|
|
result = Cursor::Auto;
|
|
react_native_expect(value.hasType<std::string>());
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "alias") {
|
|
result = Cursor::Alias;
|
|
return;
|
|
}
|
|
if (stringValue == "all-scroll") {
|
|
result = Cursor::AllScroll;
|
|
return;
|
|
}
|
|
if (stringValue == "auto") {
|
|
result = Cursor::Auto;
|
|
return;
|
|
}
|
|
if (stringValue == "cell") {
|
|
result = Cursor::Cell;
|
|
return;
|
|
}
|
|
if (stringValue == "col-resize") {
|
|
result = Cursor::ColResize;
|
|
return;
|
|
}
|
|
if (stringValue == "context-menu") {
|
|
result = Cursor::ContextMenu;
|
|
return;
|
|
}
|
|
if (stringValue == "copy") {
|
|
result = Cursor::Copy;
|
|
return;
|
|
}
|
|
if (stringValue == "crosshair") {
|
|
result = Cursor::Crosshair;
|
|
return;
|
|
}
|
|
if (stringValue == "default") {
|
|
result = Cursor::Default;
|
|
return;
|
|
}
|
|
if (stringValue == "e-resize") {
|
|
result = Cursor::EResize;
|
|
return;
|
|
}
|
|
if (stringValue == "ew-resize") {
|
|
result = Cursor::EWResize;
|
|
return;
|
|
}
|
|
if (stringValue == "grab") {
|
|
result = Cursor::Grab;
|
|
return;
|
|
}
|
|
if (stringValue == "grabbing") {
|
|
result = Cursor::Grabbing;
|
|
return;
|
|
}
|
|
if (stringValue == "help") {
|
|
result = Cursor::Help;
|
|
return;
|
|
}
|
|
if (stringValue == "move") {
|
|
result = Cursor::Move;
|
|
return;
|
|
}
|
|
if (stringValue == "n-resize") {
|
|
result = Cursor::NResize;
|
|
return;
|
|
}
|
|
if (stringValue == "ne-resize") {
|
|
result = Cursor::NEResize;
|
|
return;
|
|
}
|
|
if (stringValue == "nesw-resize") {
|
|
result = Cursor::NESWResize;
|
|
return;
|
|
}
|
|
if (stringValue == "ns-resize") {
|
|
result = Cursor::NSResize;
|
|
return;
|
|
}
|
|
if (stringValue == "nw-resize") {
|
|
result = Cursor::NWResize;
|
|
return;
|
|
}
|
|
if (stringValue == "nwse-resize") {
|
|
result = Cursor::NWSEResize;
|
|
return;
|
|
}
|
|
if (stringValue == "no-drop") {
|
|
result = Cursor::NoDrop;
|
|
return;
|
|
}
|
|
if (stringValue == "none") {
|
|
result = Cursor::None;
|
|
return;
|
|
}
|
|
if (stringValue == "not-allowed") {
|
|
result = Cursor::NotAllowed;
|
|
return;
|
|
}
|
|
if (stringValue == "pointer") {
|
|
result = Cursor::Pointer;
|
|
return;
|
|
}
|
|
if (stringValue == "progress") {
|
|
result = Cursor::Progress;
|
|
return;
|
|
}
|
|
if (stringValue == "row-resize") {
|
|
result = Cursor::RowResize;
|
|
return;
|
|
}
|
|
if (stringValue == "s-resize") {
|
|
result = Cursor::SResize;
|
|
return;
|
|
}
|
|
if (stringValue == "se-resize") {
|
|
result = Cursor::SEResize;
|
|
return;
|
|
}
|
|
if (stringValue == "sw-resize") {
|
|
result = Cursor::SWResize;
|
|
return;
|
|
}
|
|
if (stringValue == "text") {
|
|
result = Cursor::Text;
|
|
return;
|
|
}
|
|
if (stringValue == "url") {
|
|
result = Cursor::Url;
|
|
return;
|
|
}
|
|
if (stringValue == "w-resize") {
|
|
result = Cursor::WResize;
|
|
return;
|
|
}
|
|
if (stringValue == "wait") {
|
|
result = Cursor::Wait;
|
|
return;
|
|
}
|
|
if (stringValue == "zoom-in") {
|
|
result = Cursor::ZoomIn;
|
|
return;
|
|
}
|
|
if (stringValue == "zoom-out") {
|
|
result = Cursor::ZoomOut;
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Could not parse Cursor:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
LayoutConformance& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
result = LayoutConformance::Strict;
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto stringValue = (std::string)value;
|
|
if (stringValue == "strict") {
|
|
result = LayoutConformance::Strict;
|
|
} else if (stringValue == "compatibility") {
|
|
result = LayoutConformance::Compatibility;
|
|
} else {
|
|
LOG(ERROR) << "Unexpected LayoutConformance value:" << stringValue;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
BlendMode& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
result = BlendMode::Normal;
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto rawBlendMode = static_cast<std::string>(value);
|
|
std::optional<BlendMode> blendMode = blendModeFromString(rawBlendMode);
|
|
if (!blendMode) {
|
|
LOG(ERROR) << "Could not parse blend mode: " << rawBlendMode;
|
|
return;
|
|
}
|
|
result = blendMode.value();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
std::vector<BackgroundImage>& result) {
|
|
react_native_expect(value.hasType<std::vector<RawValue>>());
|
|
if (!value.hasType<std::vector<RawValue>>()) {
|
|
result = {};
|
|
return;
|
|
}
|
|
std::vector<BackgroundImage> backgroundImage{};
|
|
auto rawBackgroundImage = static_cast<std::vector<RawValue>>(value);
|
|
for (const auto& rawBackgroundImageValue : rawBackgroundImage) {
|
|
bool isMap = rawBackgroundImageValue
|
|
.hasType<std::unordered_map<std::string, RawValue>>();
|
|
react_native_expect(isMap);
|
|
if (!isMap) {
|
|
result = {};
|
|
return;
|
|
}
|
|
auto rawBackgroundImageMap =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(
|
|
rawBackgroundImageValue);
|
|
auto typeIt = rawBackgroundImageMap.find("type");
|
|
if (typeIt == rawBackgroundImageMap.end() ||
|
|
!typeIt->second.hasType<std::string>()) {
|
|
continue;
|
|
}
|
|
std::string type = (std::string)(typeIt->second);
|
|
std::vector<ColorStop> colorStops;
|
|
auto colorStopsIt = rawBackgroundImageMap.find("colorStops");
|
|
if (colorStopsIt != rawBackgroundImageMap.end() &&
|
|
colorStopsIt->second.hasType<std::vector<RawValue>>()) {
|
|
auto rawColorStops =
|
|
static_cast<std::vector<RawValue>>(colorStopsIt->second);
|
|
for (const auto& stop : rawColorStops) {
|
|
if (stop.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto stopMap =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(stop);
|
|
auto positionIt = stopMap.find("position");
|
|
auto colorIt = stopMap.find("color");
|
|
if (positionIt != stopMap.end() && colorIt != stopMap.end()) {
|
|
ColorStop colorStop;
|
|
if (positionIt->second.hasValue()) {
|
|
auto valueUnit = toValueUnit(positionIt->second);
|
|
if (!valueUnit) {
|
|
result = {};
|
|
return;
|
|
}
|
|
colorStop.position = valueUnit;
|
|
}
|
|
if (colorIt->second.hasValue()) {
|
|
fromRawValue(
|
|
context.contextContainer,
|
|
context.surfaceId,
|
|
colorIt->second,
|
|
colorStop.color);
|
|
}
|
|
colorStops.push_back(colorStop);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (type == "linear-gradient") {
|
|
LinearGradient linearGradient;
|
|
auto directionIt = rawBackgroundImageMap.find("direction");
|
|
if (directionIt != rawBackgroundImageMap.end() &&
|
|
directionIt->second
|
|
.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto directionMap =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(
|
|
directionIt->second);
|
|
auto directionTypeIt = directionMap.find("type");
|
|
auto valueIt = directionMap.find("value");
|
|
if (directionTypeIt != directionMap.end() &&
|
|
valueIt != directionMap.end()) {
|
|
std::string directionType = (std::string)(directionTypeIt->second);
|
|
if (directionType == "angle") {
|
|
linearGradient.direction.type = GradientDirectionType::Angle;
|
|
if (valueIt->second.hasType<Float>()) {
|
|
linearGradient.direction.value = (Float)(valueIt->second);
|
|
}
|
|
} else if (directionType == "keyword") {
|
|
linearGradient.direction.type = GradientDirectionType::Keyword;
|
|
if (valueIt->second.hasType<std::string>()) {
|
|
linearGradient.direction.value =
|
|
parseGradientKeyword((std::string)(valueIt->second));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!colorStops.empty()) {
|
|
linearGradient.colorStops = colorStops;
|
|
}
|
|
backgroundImage.emplace_back(std::move(linearGradient));
|
|
} else if (type == "radial-gradient") {
|
|
RadialGradient radialGradient;
|
|
auto shapeIt = rawBackgroundImageMap.find("shape");
|
|
if (shapeIt != rawBackgroundImageMap.end() &&
|
|
shapeIt->second.hasType<std::string>()) {
|
|
auto shape = (std::string)(shapeIt->second);
|
|
radialGradient.shape = shape == "circle" ? RadialGradientShape::Circle
|
|
: RadialGradientShape::Ellipse;
|
|
}
|
|
auto sizeIt = rawBackgroundImageMap.find("size");
|
|
if (sizeIt != rawBackgroundImageMap.end()) {
|
|
if (sizeIt->second.hasType<std::string>()) {
|
|
auto sizeStr = (std::string)(sizeIt->second);
|
|
if (sizeStr == "closest-side") {
|
|
radialGradient.size.value =
|
|
RadialGradientSize::SizeKeyword::ClosestSide;
|
|
} else if (sizeStr == "farthest-side") {
|
|
radialGradient.size.value =
|
|
RadialGradientSize::SizeKeyword::FarthestSide;
|
|
} else if (sizeStr == "closest-corner") {
|
|
radialGradient.size.value =
|
|
RadialGradientSize::SizeKeyword::ClosestCorner;
|
|
} else if (sizeStr == "farthest-corner") {
|
|
radialGradient.size.value =
|
|
RadialGradientSize::SizeKeyword::FarthestCorner;
|
|
}
|
|
} else if (sizeIt->second
|
|
.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto sizeMap = static_cast<std::unordered_map<std::string, RawValue>>(
|
|
sizeIt->second);
|
|
auto xIt = sizeMap.find("x");
|
|
auto yIt = sizeMap.find("y");
|
|
if (xIt != sizeMap.end() && yIt != sizeMap.end()) {
|
|
RadialGradientSize sizeObj;
|
|
sizeObj.value = RadialGradientSize::Dimensions{
|
|
toValueUnit(xIt->second), toValueUnit(yIt->second)};
|
|
radialGradient.size = sizeObj;
|
|
}
|
|
}
|
|
auto positionIt = rawBackgroundImageMap.find("position");
|
|
if (positionIt != rawBackgroundImageMap.end() &&
|
|
positionIt->second
|
|
.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto positionMap =
|
|
static_cast<std::unordered_map<std::string, RawValue>>(
|
|
positionIt->second);
|
|
auto topIt = positionMap.find("top");
|
|
auto bottomIt = positionMap.find("bottom");
|
|
auto leftIt = positionMap.find("left");
|
|
auto rightIt = positionMap.find("right");
|
|
if (topIt != positionMap.end()) {
|
|
auto topValue = toValueUnit(topIt->second);
|
|
radialGradient.position.top = topValue;
|
|
} else if (bottomIt != positionMap.end()) {
|
|
auto bottomValue = toValueUnit(bottomIt->second);
|
|
radialGradient.position.bottom = bottomValue;
|
|
}
|
|
if (leftIt != positionMap.end()) {
|
|
auto leftValue = toValueUnit(leftIt->second);
|
|
radialGradient.position.left = leftValue;
|
|
} else if (rightIt != positionMap.end()) {
|
|
auto rightValue = toValueUnit(rightIt->second);
|
|
radialGradient.position.right = rightValue;
|
|
}
|
|
}
|
|
}
|
|
if (!colorStops.empty()) {
|
|
radialGradient.colorStops = colorStops;
|
|
}
|
|
backgroundImage.emplace_back(std::move(radialGradient));
|
|
}
|
|
}
|
|
result = backgroundImage;
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& value,
|
|
Isolation& result) {
|
|
react_native_expect(value.hasType<std::string>());
|
|
result = Isolation::Auto;
|
|
if (!value.hasType<std::string>()) {
|
|
return;
|
|
}
|
|
auto rawIsolation = static_cast<std::string>(value);
|
|
std::optional<Isolation> isolation = isolationFromString(rawIsolation);
|
|
if (!isolation) {
|
|
LOG(ERROR) << "Could not parse isolation: " << rawIsolation;
|
|
return;
|
|
}
|
|
result = isolation.value();
|
|
}
|
|
template <size_t N>
|
|
inline std::string toString(const std::array<float, N> vec) {
|
|
std::string s;
|
|
s.append("{");
|
|
for (size_t i = 0; i < N - 1; i++) {
|
|
s.append(std::to_string(vec[i]) + ", ");
|
|
}
|
|
s.append(std::to_string(vec[N - 1]));
|
|
s.append("}");
|
|
return s;
|
|
}
|
|
inline std::string toString(const yoga::Direction& value) {
|
|
return YGDirectionToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::FlexDirection& value) {
|
|
return YGFlexDirectionToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::Justify& value) {
|
|
return YGJustifyToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::Align& value) {
|
|
return YGAlignToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::PositionType& value) {
|
|
return YGPositionTypeToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::Wrap& value) {
|
|
return YGWrapToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::Overflow& value) {
|
|
return YGOverflowToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::Display& value) {
|
|
return YGDisplayToString(yoga::unscopedEnum(value));
|
|
}
|
|
inline std::string toString(const yoga::Style::Length& length) {
|
|
if (length.isUndefined()) {
|
|
return "undefined";
|
|
} else if (length.isAuto()) {
|
|
return "auto";
|
|
} else if (length.isPoints()) {
|
|
return std::to_string(length.value().unwrap());
|
|
} else if (length.isPercent()) {
|
|
return std::to_string(length.value().unwrap()) + "%";
|
|
} else {
|
|
return "unknown";
|
|
}
|
|
}
|
|
inline std::string toString(const yoga::Style::SizeLength& length) {
|
|
if (length.isUndefined()) {
|
|
return "undefined";
|
|
} else if (length.isAuto()) {
|
|
return "auto";
|
|
} else if (length.isPoints()) {
|
|
return std::to_string(length.value().unwrap());
|
|
} else if (length.isPercent()) {
|
|
return std::to_string(length.value().unwrap()) + "%";
|
|
} else if (length.isMaxContent()) {
|
|
return "max-content";
|
|
} else if (length.isFitContent()) {
|
|
return "fit-content";
|
|
} else if (length.isStretch()) {
|
|
return "stretch";
|
|
} else {
|
|
return "unknown";
|
|
}
|
|
}
|
|
inline std::string toString(const yoga::FloatOptional& value) {
|
|
if (value.isUndefined()) {
|
|
return "undefined";
|
|
}
|
|
return std::to_string(value.unwrap());
|
|
}
|
|
inline std::string toString(const LayoutConformance& value) {
|
|
switch (value) {
|
|
case LayoutConformance::Strict:
|
|
return "strict";
|
|
case LayoutConformance::Compatibility:
|
|
return "compatibility";
|
|
}
|
|
}
|
|
inline std::string toString(const std::array<Float, 16>& m) {
|
|
std::string result;
|
|
result += "[ " + std::to_string(m[0]) + " " + std::to_string(m[1]) + " " +
|
|
std::to_string(m[2]) + " " + std::to_string(m[3]) + " ]\n";
|
|
result += "[ " + std::to_string(m[4]) + " " + std::to_string(m[5]) + " " +
|
|
std::to_string(m[6]) + " " + std::to_string(m[7]) + " ]\n";
|
|
result += "[ " + std::to_string(m[8]) + " " + std::to_string(m[9]) + " " +
|
|
std::to_string(m[10]) + " " + std::to_string(m[11]) + " ]\n";
|
|
result += "[ " + std::to_string(m[12]) + " " + std::to_string(m[13]) + " " +
|
|
std::to_string(m[14]) + " " + std::to_string(m[15]) + " ]";
|
|
return result;
|
|
}
|
|
inline std::string toString(const Transform& transform) {
|
|
std::string result = "[";
|
|
bool first = true;
|
|
for (const auto& operation : transform.operations) {
|
|
if (!first) {
|
|
result += ", ";
|
|
}
|
|
first = false;
|
|
switch (operation.type) {
|
|
case TransformOperationType::Perspective: {
|
|
result +=
|
|
"{\"perspective\": " + std::to_string(operation.x.value) + "}";
|
|
break;
|
|
}
|
|
case TransformOperationType::Rotate: {
|
|
if (operation.x.value != 0 && operation.y.value == 0 &&
|
|
operation.z.value == 0) {
|
|
result +=
|
|
R"({"rotateX": ")" + std::to_string(operation.x.value) + "rad\"}";
|
|
} else if (
|
|
operation.x.value == 0 && operation.y.value != 0 &&
|
|
operation.z.value == 0) {
|
|
result +=
|
|
R"({"rotateY": ")" + std::to_string(operation.y.value) + "rad\"}";
|
|
} else if (
|
|
operation.x.value == 0 && operation.y.value == 0 &&
|
|
operation.z.value != 0) {
|
|
result +=
|
|
R"({"rotateZ": ")" + std::to_string(operation.z.value) + "rad\"}";
|
|
}
|
|
break;
|
|
}
|
|
case TransformOperationType::Scale: {
|
|
if (operation.x.value == operation.y.value &&
|
|
operation.x.value == operation.z.value) {
|
|
result += "{\"scale\": " + std::to_string(operation.x.value) + "}";
|
|
} else if (operation.y.value == 1 && operation.z.value == 1) {
|
|
result += "{\"scaleX\": " + std::to_string(operation.x.value) + "}";
|
|
} else if (operation.x.value == 1 && operation.z.value == 1) {
|
|
result += "{\"scaleY\": " + std::to_string(operation.y.value) + "}";
|
|
} else if (operation.x.value == 1 && operation.y.value == 1) {
|
|
result += "{\"scaleZ\": " + std::to_string(operation.z.value) + "}";
|
|
}
|
|
break;
|
|
}
|
|
case TransformOperationType::Translate: {
|
|
if (operation.x.value != 0 && operation.y.value != 0 &&
|
|
operation.z.value == 0) {
|
|
result += "{\"translate\": [";
|
|
result += std::to_string(operation.x.value) + ", " +
|
|
std::to_string(operation.y.value);
|
|
result += "]}";
|
|
} else if (operation.x.value != 0 && operation.y.value == 0) {
|
|
result +=
|
|
"{\"translateX\": " + std::to_string(operation.x.value) + "}";
|
|
} else if (operation.x.value == 0 && operation.y.value != 0) {
|
|
result +=
|
|
"{\"translateY\": " + std::to_string(operation.y.value) + "}";
|
|
}
|
|
break;
|
|
}
|
|
case TransformOperationType::Skew: {
|
|
if (operation.x.value != 0 && operation.y.value == 0) {
|
|
result +=
|
|
R"({"skewX": ")" + std::to_string(operation.x.value) + "rad\"}";
|
|
} else if (operation.x.value == 0 && operation.y.value != 0) {
|
|
result +=
|
|
R"({"skewY": ")" + std::to_string(operation.y.value) + "rad\"}";
|
|
}
|
|
break;
|
|
}
|
|
case TransformOperationType::Arbitrary: {
|
|
result += "{\"matrix\": " + toString(transform.matrix) + "}";
|
|
break;
|
|
}
|
|
case TransformOperationType::Identity: {
|
|
result += "{\"identity\": true}";
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
result += "]";
|
|
return result;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformTouch.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformTouch.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewEventEmitter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformViewEventEmitter.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewProps.h}:
|
|
namespace facebook::react {
|
|
class HostPlatformViewProps : public BaseViewProps {
|
|
public:
|
|
HostPlatformViewProps() = default;
|
|
HostPlatformViewProps(
|
|
const PropsParserContext& context,
|
|
const HostPlatformViewProps& sourceProps,
|
|
const RawProps& rawProps,
|
|
const std::function<bool(const std::string&)>& filterObjectKeys =
|
|
nullptr);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
Float elevation{};
|
|
std::optional<NativeDrawable> nativeBackground{};
|
|
std::optional<NativeDrawable> nativeForeground{};
|
|
bool focusable{false};
|
|
bool hasTVPreferredFocus{false};
|
|
bool needsOffscreenAlphaCompositing{false};
|
|
bool renderToHardwareTextureAndroid{false};
|
|
bool screenReaderFocusable{false};
|
|
bool getProbablyMoreHorizontalThanVertical_DEPRECATED() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewTraitsInitializer.h}:
|
|
namespace facebook::react::HostPlatformViewTraitsInitializer {
|
|
inline bool formsStackingContext(const ViewProps& viewProps) {
|
|
return viewProps.elevation != 0;
|
|
}
|
|
inline bool formsView(const ViewProps& viewProps) {
|
|
return viewProps.nativeBackground.has_value() ||
|
|
viewProps.nativeForeground.has_value() || viewProps.focusable ||
|
|
viewProps.hasTVPreferredFocus ||
|
|
viewProps.needsOffscreenAlphaCompositing ||
|
|
viewProps.renderToHardwareTextureAndroid ||
|
|
viewProps.screenReaderFocusable;
|
|
}
|
|
inline bool isKeyboardFocusable(const ViewProps& viewProps) {
|
|
return (viewProps.focusable || viewProps.hasTVPreferredFocus);
|
|
}
|
|
} // namespace facebook::react::HostPlatformViewTraitsInitializer
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/NativeDrawable.h}:
|
|
namespace facebook::react {
|
|
struct NativeDrawable {
|
|
enum class Kind : uint8_t {
|
|
Ripple,
|
|
ThemeAttr,
|
|
};
|
|
struct Ripple {
|
|
std::optional<int32_t> color{};
|
|
std::optional<Float> rippleRadius{};
|
|
bool borderless{false};
|
|
bool operator==(const Ripple& rhs) const {
|
|
return std::tie(this->color, this->borderless, this->rippleRadius) ==
|
|
std::tie(rhs.color, rhs.borderless, rhs.rippleRadius);
|
|
}
|
|
};
|
|
std::string themeAttr;
|
|
Ripple ripple;
|
|
Kind kind;
|
|
bool operator==(const NativeDrawable& rhs) const {
|
|
if (this->kind != rhs.kind) {
|
|
return false;
|
|
}
|
|
switch (this->kind) {
|
|
case Kind::ThemeAttr:
|
|
return this->themeAttr == rhs.themeAttr;
|
|
case Kind::Ripple:
|
|
return this->ripple == rhs.ripple;
|
|
}
|
|
}
|
|
bool operator!=(const NativeDrawable& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
~NativeDrawable() = default;
|
|
};
|
|
static inline void fromRawValue(
|
|
const PropsParserContext&,
|
|
const RawValue& rawValue,
|
|
NativeDrawable& result) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)rawValue;
|
|
auto typeIterator = map.find("type");
|
|
react_native_expect(
|
|
typeIterator != map.end() && typeIterator->second.hasType<std::string>());
|
|
std::string type = (std::string)typeIterator->second;
|
|
if (type == "ThemeAttrAndroid") {
|
|
auto attrIterator = map.find("attribute");
|
|
react_native_expect(
|
|
attrIterator != map.end() &&
|
|
attrIterator->second.hasType<std::string>());
|
|
result = NativeDrawable{
|
|
(std::string)attrIterator->second,
|
|
{},
|
|
NativeDrawable::Kind::ThemeAttr,
|
|
};
|
|
} else if (type == "RippleAndroid") {
|
|
auto color = map.find("color");
|
|
auto borderless = map.find("borderless");
|
|
auto rippleRadius = map.find("rippleRadius");
|
|
result = NativeDrawable{
|
|
std::string{},
|
|
NativeDrawable::Ripple{
|
|
color != map.end() && color->second.hasType<int32_t>()
|
|
? (int32_t)color->second
|
|
: std::optional<int32_t>{},
|
|
rippleRadius != map.end() && rippleRadius->second.hasType<Float>()
|
|
? (Float)rippleRadius->second
|
|
: std::optional<Float>{},
|
|
borderless != map.end() && borderless->second.hasType<bool>()
|
|
? (bool)borderless->second
|
|
: false,
|
|
},
|
|
NativeDrawable::Kind::Ripple,
|
|
};
|
|
} else {
|
|
LOG(ERROR) << "Unknown native drawable type: " << type;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformTouch.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformTouch.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformViewEventEmitter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/android/react/renderer/components/view/HostPlatformViewEventEmitter.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformViewProps.h}:
|
|
namespace facebook::react {
|
|
using HostPlatformViewProps = BaseViewProps;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/cxx/react/renderer/components/view/HostPlatformViewTraitsInitializer.h}:
|
|
namespace facebook::react::HostPlatformViewTraitsInitializer {
|
|
inline bool formsStackingContext(const ViewProps& props) {
|
|
return false;
|
|
}
|
|
inline bool formsView(const ViewProps& props) {
|
|
return false;
|
|
}
|
|
inline bool isKeyboardFocusable(const ViewProps&) {
|
|
return false;
|
|
}
|
|
} // namespace facebook::react::HostPlatformViewTraitsInitializer
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformTouch.h}:
|
|
namespace facebook::react {
|
|
class HostPlatformTouch : public BaseTouch {
|
|
public:
|
|
int button;
|
|
std::string pointerType;
|
|
bool altKey;
|
|
bool ctrlKey;
|
|
bool shiftKey;
|
|
bool metaKey;
|
|
double pointerTimestamp;
|
|
};
|
|
inline static void setTouchPayloadOnObject(
|
|
jsi::Object& object,
|
|
jsi::Runtime& runtime,
|
|
const HostPlatformTouch& touch) {
|
|
object.setProperty(runtime, "locationX", touch.offsetPoint.x);
|
|
object.setProperty(runtime, "locationY", touch.offsetPoint.y);
|
|
object.setProperty(runtime, "pageX", touch.pagePoint.x);
|
|
object.setProperty(runtime, "pageY", touch.pagePoint.y);
|
|
object.setProperty(runtime, "screenX", touch.screenPoint.x);
|
|
object.setProperty(runtime, "screenY", touch.screenPoint.y);
|
|
object.setProperty(runtime, "identifier", touch.identifier);
|
|
object.setProperty(runtime, "target", touch.target);
|
|
object.setProperty(runtime, "timestamp", touch.timestamp);
|
|
object.setProperty(runtime, "force", touch.force);
|
|
object.setProperty(runtime, "button", touch.button);
|
|
object.setProperty(runtime, "altKey", touch.altKey);
|
|
object.setProperty(runtime, "ctrlKey", touch.ctrlKey);
|
|
object.setProperty(runtime, "shiftKey", touch.shiftKey);
|
|
object.setProperty(runtime, "metaKey", touch.metaKey);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEventEmitter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/MouseEvent.h}
|
|
|
|
namespace facebook::react {
|
|
class HostPlatformViewEventEmitter : public BaseViewEventEmitter {
|
|
public:
|
|
using BaseViewEventEmitter::BaseViewEventEmitter;
|
|
void onKeyDown(const KeyEvent& keyEvent) const;
|
|
void onKeyUp(const KeyEvent& keyEvent) const;
|
|
void onMouseEnter(const MouseEvent& mouseEvent) const;
|
|
void onMouseLeave(const MouseEvent& mouseEvent) const;
|
|
void onDoubleClick(const MouseEvent& mouseEvent) const;
|
|
void onDragEnter(const DragEvent& dragEvent) const;
|
|
void onDragLeave(const DragEvent& dragEvent) const;
|
|
void onDrop(const DragEvent& dragEvent) const;
|
|
static jsi::Value dataTransferPayload(
|
|
jsi::Runtime& runtime,
|
|
const std::vector<DataTransferItem>& dataTransferItems);
|
|
void onFocus() const;
|
|
void onBlur() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h}:
|
|
namespace facebook::react {
|
|
struct HostPlatformViewEvents {
|
|
std::bitset<32> bits{};
|
|
enum class Offset : std::size_t {
|
|
KeyDown = 1,
|
|
KeyUp = 2,
|
|
MouseEnter = 3,
|
|
MouseLeave = 4,
|
|
DoubleClick = 5,
|
|
};
|
|
constexpr bool operator[](const Offset offset) const {
|
|
return bits[static_cast<std::size_t>(offset)];
|
|
}
|
|
std::bitset<32>::reference operator[](const Offset offset) {
|
|
return bits[static_cast<std::size_t>(offset)];
|
|
}
|
|
};
|
|
inline static bool operator==(
|
|
const HostPlatformViewEvents& lhs,
|
|
const HostPlatformViewEvents& rhs) {
|
|
return lhs.bits == rhs.bits;
|
|
}
|
|
inline static bool operator!=(
|
|
const HostPlatformViewEvents& lhs,
|
|
const HostPlatformViewEvents& rhs) {
|
|
return lhs.bits != rhs.bits;
|
|
}
|
|
static inline HostPlatformViewEvents convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const HostPlatformViewEvents& sourceValue,
|
|
const HostPlatformViewEvents& defaultValue) {
|
|
HostPlatformViewEvents result{};
|
|
using Offset = HostPlatformViewEvents::Offset;
|
|
result[Offset::KeyDown] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onKeyDown",
|
|
sourceValue[Offset::KeyDown],
|
|
defaultValue[Offset::KeyDown]);
|
|
result[Offset::KeyUp] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onKeyUp",
|
|
sourceValue[Offset::KeyUp],
|
|
defaultValue[Offset::KeyUp]);
|
|
result[Offset::MouseEnter] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onMouseEnter",
|
|
sourceValue[Offset::MouseEnter],
|
|
defaultValue[Offset::MouseEnter]);
|
|
result[Offset::MouseLeave] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onMouseLeave",
|
|
sourceValue[Offset::MouseLeave],
|
|
defaultValue[Offset::MouseLeave]);
|
|
result[Offset::DoubleClick] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onDoubleClick",
|
|
sourceValue[Offset::DoubleClick],
|
|
defaultValue[Offset::DoubleClick]);
|
|
return result;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewProps.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewEvents.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h}
|
|
|
|
namespace facebook::react {
|
|
class HostPlatformViewProps : public BaseViewProps {
|
|
public:
|
|
HostPlatformViewProps() = default;
|
|
HostPlatformViewProps(
|
|
const PropsParserContext& context,
|
|
const HostPlatformViewProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
HostPlatformViewEvents hostPlatformEvents{};
|
|
bool enableFocusRing{true};
|
|
bool focusable{false};
|
|
std::vector<std::string> draggedTypes{};
|
|
std::optional<std::string> tooltip{};
|
|
std::optional<std::vector<HandledKey>> validKeysDown{};
|
|
std::optional<std::vector<HandledKey>> validKeysUp{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/HostPlatformViewTraitsInitializer.h}:
|
|
namespace facebook::react::HostPlatformViewTraitsInitializer {
|
|
inline bool formsStackingContext(const ViewProps& props) {
|
|
constexpr decltype(HostPlatformViewEvents::bits) mouseEventMask = {
|
|
(1 << (int)HostPlatformViewEvents::Offset::MouseEnter) |
|
|
(1 << (int)HostPlatformViewEvents::Offset::MouseLeave) |
|
|
(1 << (int)HostPlatformViewEvents::Offset::DoubleClick)};
|
|
return (props.hostPlatformEvents.bits & mouseEventMask).any() ||
|
|
props.tooltip ||
|
|
(props.validKeysDown.has_value() && !props.validKeysDown->empty()) ||
|
|
(props.validKeysUp.has_value() && !props.validKeysUp->empty());
|
|
}
|
|
inline bool formsView(const ViewProps& props) {
|
|
return props.focusable;
|
|
}
|
|
inline bool isKeyboardFocusable(const ViewProps& props) {
|
|
return props.focusable;
|
|
}
|
|
} // namespace facebook::react::HostPlatformViewTraitsInitializer
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/KeyEvent.h}:
|
|
namespace facebook::react {
|
|
struct HandledKey {
|
|
std::string key{};
|
|
std::optional<bool> altKey{};
|
|
std::optional<bool> ctrlKey{};
|
|
std::optional<bool> shiftKey{};
|
|
std::optional<bool> metaKey{};
|
|
};
|
|
inline static bool operator==(const HandledKey& lhs, const HandledKey& rhs) {
|
|
return lhs.key == rhs.key && lhs.altKey == rhs.altKey &&
|
|
lhs.ctrlKey == rhs.ctrlKey && lhs.shiftKey == rhs.shiftKey &&
|
|
lhs.metaKey == rhs.metaKey;
|
|
}
|
|
struct KeyEvent {
|
|
std::string key{};
|
|
bool altKey{false};
|
|
bool ctrlKey{false};
|
|
bool shiftKey{false};
|
|
bool metaKey{false};
|
|
bool capsLockKey{false};
|
|
bool numericPadKey{false};
|
|
bool helpKey{false};
|
|
bool functionKey{false};
|
|
};
|
|
inline static bool operator==(const KeyEvent& lhs, const HandledKey& rhs) {
|
|
return lhs.key == rhs.key &&
|
|
(!rhs.altKey.has_value() || lhs.altKey == *rhs.altKey) &&
|
|
(!rhs.ctrlKey.has_value() || lhs.ctrlKey == *rhs.ctrlKey) &&
|
|
(!rhs.shiftKey.has_value() || lhs.shiftKey == *rhs.shiftKey) &&
|
|
(!rhs.metaKey.has_value() || lhs.metaKey == *rhs.metaKey);
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
HandledKey& result) {
|
|
if (value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto map = static_cast<std::unordered_map<std::string, RawValue>>(value);
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "key") {
|
|
result.key = static_cast<std::string>(pair.second);
|
|
} else if (pair.first == "altKey") {
|
|
result.altKey = static_cast<bool>(pair.second);
|
|
} else if (pair.first == "ctrlKey") {
|
|
result.ctrlKey = static_cast<bool>(pair.second);
|
|
} else if (pair.first == "shiftKey") {
|
|
result.shiftKey = static_cast<bool>(pair.second);
|
|
} else if (pair.first == "metaKey") {
|
|
result.metaKey = static_cast<bool>(pair.second);
|
|
}
|
|
}
|
|
} else if (value.hasType<std::string>()) {
|
|
result.key = (std::string)value;
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/macos/react/renderer/components/view/MouseEvent.h}:
|
|
namespace facebook::react {
|
|
struct MouseEvent {
|
|
Float clientX{0};
|
|
Float clientY{0};
|
|
Float screenX{0};
|
|
Float screenY{0};
|
|
bool altKey{false};
|
|
bool ctrlKey{false};
|
|
bool shiftKey{false};
|
|
bool metaKey{false};
|
|
};
|
|
struct DataTransferItem {
|
|
std::string name{};
|
|
std::string kind{};
|
|
std::string type{};
|
|
std::string uri{};
|
|
std::optional<int> size{};
|
|
std::optional<int> width{};
|
|
std::optional<int> height{};
|
|
};
|
|
struct DragEvent : MouseEvent {
|
|
std::vector<DataTransferItem> dataTransferItems;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/HostPlatformTouch.h}:
|
|
namespace facebook::react {
|
|
class HostPlatformTouch : public BaseTouch {
|
|
public:
|
|
int button;
|
|
std::string pointerType;
|
|
bool altKey;
|
|
bool ctrlKey;
|
|
bool shiftKey;
|
|
double pointerTimestamp;
|
|
};
|
|
inline static void setTouchPayloadOnObject(
|
|
jsi::Object& object,
|
|
jsi::Runtime& runtime,
|
|
const HostPlatformTouch& touch) {
|
|
object.setProperty(runtime, "locationX", touch.offsetPoint.x);
|
|
object.setProperty(runtime, "locationY", touch.offsetPoint.y);
|
|
object.setProperty(runtime, "pageX", touch.pagePoint.x);
|
|
object.setProperty(runtime, "pageY", touch.pagePoint.y);
|
|
object.setProperty(runtime, "screenX", touch.screenPoint.x);
|
|
object.setProperty(runtime, "screenY", touch.screenPoint.y);
|
|
object.setProperty(runtime, "identifier", touch.identifier);
|
|
object.setProperty(runtime, "target", touch.target);
|
|
object.setProperty(runtime, "timestamp", touch.pointerTimestamp / 1000);
|
|
object.setProperty(runtime, "force", touch.force);
|
|
object.setProperty(runtime, "button", touch.button);
|
|
object.setProperty(runtime, "pointerType", touch.pointerType);
|
|
object.setProperty(runtime, "altKey", touch.altKey);
|
|
object.setProperty(runtime, "ctrlKey", touch.ctrlKey);
|
|
object.setProperty(runtime, "shiftKey", touch.shiftKey);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/HostPlatformViewEventEmitter.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/KeyEvent.h}
|
|
|
|
namespace facebook::react {
|
|
class HostPlatformViewEventEmitter : public BaseViewEventEmitter {
|
|
public:
|
|
using BaseViewEventEmitter::BaseViewEventEmitter;
|
|
void onKeyDown(const KeyEvent& keyEvent) const;
|
|
void onKeyUp(const KeyEvent& keyEvent) const;
|
|
void onFocus() const;
|
|
void onBlur() const;
|
|
void onMouseEnter(const PointerEvent& pointerEvent) const;
|
|
void onMouseLeave(const PointerEvent& pointerEvent) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/HostPlatformViewProps.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/KeyEvent.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/WindowsViewEvents.h}
|
|
|
|
namespace facebook::react {
|
|
class HostPlatformViewProps : public BaseViewProps {
|
|
public:
|
|
HostPlatformViewProps() = default;
|
|
HostPlatformViewProps(
|
|
const PropsParserContext& context,
|
|
const HostPlatformViewProps& sourceProps,
|
|
const RawProps& rawProps);
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
WindowsViewEvents windowsEvents{};
|
|
bool enableFocusRing{true};
|
|
bool focusable{false};
|
|
std::optional<std::string> overflowAnchor{};
|
|
std::optional<std::string> tooltip{};
|
|
std::vector<HandledKeyEvent> keyDownEvents{};
|
|
std::vector<HandledKeyEvent> keyUpEvents{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/HostPlatformViewTraitsInitializer.h}:
|
|
namespace facebook::react::HostPlatformViewTraitsInitializer {
|
|
inline bool formsStackingContext(const ViewProps& viewProps) {
|
|
constexpr decltype(WindowsViewEvents::bits) focusEventsMask = {
|
|
(1 << (int)WindowsViewEvents::Offset::Focus) &
|
|
(1 << (int)WindowsViewEvents::Offset::Blur)};
|
|
return (viewProps.windowsEvents.bits & focusEventsMask).any();
|
|
}
|
|
inline bool formsView(const ViewProps& viewProps) {
|
|
return viewProps.focusable;
|
|
}
|
|
inline bool isKeyboardFocusable(const ViewProps& viewProps) {
|
|
return viewProps.focusable;
|
|
}
|
|
} // namespace facebook::react::HostPlatformViewTraitsInitializer
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/KeyEvent.h}:
|
|
namespace facebook::react {
|
|
struct BaseKeyEvent {
|
|
std::string code{};
|
|
bool altKey{false};
|
|
bool ctrlKey{false};
|
|
bool shiftKey{false};
|
|
bool metaKey{false};
|
|
};
|
|
inline static bool operator==(
|
|
const BaseKeyEvent& lhs,
|
|
const BaseKeyEvent& rhs) {
|
|
return lhs.code == rhs.code && lhs.altKey == rhs.altKey &&
|
|
lhs.ctrlKey == rhs.ctrlKey && lhs.shiftKey == rhs.shiftKey &&
|
|
lhs.metaKey == rhs.metaKey;
|
|
}
|
|
enum class HandledEventPhase { Capturing = 1, Bubbling = 3 };
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
HandledEventPhase& result) {
|
|
if (value.hasType<int>()) {
|
|
result = static_cast<HandledEventPhase>((int)value);
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported HandledKeyEvent::EventPhase type";
|
|
}
|
|
struct HandledKeyEvent : BaseKeyEvent {
|
|
HandledEventPhase handledEventPhase{HandledEventPhase::Bubbling};
|
|
};
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
HandledKeyEvent& result) {
|
|
if (value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
auto map = (std::unordered_map<std::string, RawValue>)value;
|
|
auto attrIterator = map.find("handledEventPhase");
|
|
if (attrIterator != map.end())
|
|
fromRawValue(context, attrIterator->second, result.handledEventPhase);
|
|
attrIterator = map.find("altKey");
|
|
if (attrIterator != map.end())
|
|
fromRawValue(context, attrIterator->second, result.altKey);
|
|
attrIterator = map.find("ctrlKey");
|
|
if (attrIterator != map.end())
|
|
fromRawValue(context, attrIterator->second, result.ctrlKey);
|
|
attrIterator = map.find("metaKey");
|
|
if (attrIterator != map.end())
|
|
fromRawValue(context, attrIterator->second, result.metaKey);
|
|
attrIterator = map.find("shiftKey");
|
|
if (attrIterator != map.end())
|
|
fromRawValue(context, attrIterator->second, result.shiftKey);
|
|
attrIterator = map.find("code");
|
|
if (attrIterator != map.end())
|
|
fromRawValue(context, attrIterator->second, result.code);
|
|
return;
|
|
}
|
|
LOG(ERROR) << "Unsupported HandledKeyEvent type";
|
|
}
|
|
inline static bool operator==(
|
|
const HandledKeyEvent& lhs,
|
|
const HandledKeyEvent& rhs) {
|
|
return lhs.handledEventPhase == rhs.handledEventPhase &&
|
|
static_cast<BaseKeyEvent>(lhs) == static_cast<BaseKeyEvent>(rhs);
|
|
}
|
|
struct KeyEvent : BaseKeyEvent {
|
|
std::string key{};
|
|
Float timestamp{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/platform/windows/third-party/react/renderer/components/view/WindowsViewEvents.h}:
|
|
namespace facebook::react {
|
|
struct WindowsViewEvents {
|
|
std::bitset<32> bits{};
|
|
enum class Offset : std::size_t {
|
|
Focus = 0,
|
|
Blur = 1,
|
|
KeyUp = 2,
|
|
KeyDown = 3,
|
|
MouseEnter = 4,
|
|
MouseLeave = 5,
|
|
};
|
|
constexpr bool operator[](const Offset offset) const {
|
|
return bits[static_cast<std::size_t>(offset)];
|
|
}
|
|
std::bitset<32>::reference operator[](const Offset offset) {
|
|
return bits[static_cast<std::size_t>(offset)];
|
|
}
|
|
};
|
|
inline static bool operator==(
|
|
const WindowsViewEvents& lhs,
|
|
const WindowsViewEvents& rhs) {
|
|
return lhs.bits == rhs.bits;
|
|
}
|
|
inline static bool operator!=(
|
|
const WindowsViewEvents& lhs,
|
|
const WindowsViewEvents& rhs) {
|
|
return lhs.bits != rhs.bits;
|
|
}
|
|
static inline WindowsViewEvents convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const WindowsViewEvents& sourceValue,
|
|
const WindowsViewEvents& defaultValue) {
|
|
WindowsViewEvents result{};
|
|
using Offset = WindowsViewEvents::Offset;
|
|
result[Offset::Focus] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onFocus",
|
|
sourceValue[Offset::Focus],
|
|
defaultValue[Offset::Focus]);
|
|
result[Offset::Blur] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onBlur",
|
|
sourceValue[Offset::Blur],
|
|
defaultValue[Offset::Blur]);
|
|
result[Offset::KeyDown] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onKeyDown",
|
|
sourceValue[Offset::KeyDown],
|
|
defaultValue[Offset::KeyDown]);
|
|
result[Offset::KeyUp] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onKeyUp",
|
|
sourceValue[Offset::KeyUp],
|
|
defaultValue[Offset::KeyUp]);
|
|
result[Offset::MouseEnter] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onMouseEnter",
|
|
sourceValue[Offset::MouseEnter],
|
|
defaultValue[Offset::MouseEnter]);
|
|
result[Offset::MouseLeave] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onMouseLeave",
|
|
sourceValue[Offset::MouseLeave],
|
|
defaultValue[Offset::MouseLeave]);
|
|
return result;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/primitives.h}:
|
|
namespace facebook::react {
|
|
enum class PointerEventsMode : uint8_t { Auto, None, BoxNone, BoxOnly };
|
|
struct ViewEvents {
|
|
std::bitset<64> bits{};
|
|
enum class Offset : std::size_t {
|
|
PointerEnter = 0,
|
|
PointerMove = 1,
|
|
PointerLeave = 2,
|
|
MoveShouldSetResponder = 3,
|
|
MoveShouldSetResponderCapture = 4,
|
|
StartShouldSetResponder = 5,
|
|
StartShouldSetResponderCapture = 6,
|
|
ResponderGrant = 7,
|
|
ResponderReject = 8,
|
|
ResponderStart = 9,
|
|
ResponderEnd = 10,
|
|
ResponderRelease = 11,
|
|
ResponderMove = 12,
|
|
ResponderTerminate = 13,
|
|
ResponderTerminationRequest = 14,
|
|
ShouldBlockNativeResponder = 15,
|
|
TouchStart = 16,
|
|
TouchMove = 17,
|
|
TouchEnd = 18,
|
|
TouchCancel = 19,
|
|
PointerEnterCapture = 23,
|
|
PointerLeaveCapture = 24,
|
|
PointerMoveCapture = 25,
|
|
PointerOver = 26,
|
|
PointerOut = 27,
|
|
PointerOverCapture = 28,
|
|
PointerOutCapture = 29,
|
|
Click = 30,
|
|
ClickCapture = 31,
|
|
GotPointerCapture = 32,
|
|
LostPointerCapture = 33,
|
|
PointerDown = 34,
|
|
PointerDownCapture = 35,
|
|
PointerUp = 36,
|
|
PointerUpCapture = 37,
|
|
};
|
|
constexpr bool operator[](const Offset offset) const {
|
|
return bits[static_cast<std::size_t>(offset)];
|
|
}
|
|
std::bitset<64>::reference operator[](const Offset offset) {
|
|
return bits[static_cast<std::size_t>(offset)];
|
|
}
|
|
};
|
|
inline static bool operator==(const ViewEvents& lhs, const ViewEvents& rhs) {
|
|
return lhs.bits == rhs.bits;
|
|
}
|
|
inline static bool operator!=(const ViewEvents& lhs, const ViewEvents& rhs) {
|
|
return lhs.bits != rhs.bits;
|
|
}
|
|
enum class BackfaceVisibility : uint8_t { Auto, Visible, Hidden };
|
|
enum class BorderCurve : uint8_t { Circular, Continuous };
|
|
enum class BorderStyle : uint8_t { Solid, Dotted, Dashed };
|
|
enum class OutlineStyle : uint8_t { Solid, Dotted, Dashed };
|
|
struct CornerRadii {
|
|
float vertical{0.0f};
|
|
float horizontal{0.0f};
|
|
bool operator==(const CornerRadii& other) const = default;
|
|
};
|
|
enum class Cursor : uint8_t {
|
|
Auto,
|
|
Alias,
|
|
AllScroll,
|
|
Cell,
|
|
ColResize,
|
|
ContextMenu,
|
|
Copy,
|
|
Crosshair,
|
|
Default,
|
|
EResize,
|
|
EWResize,
|
|
Grab,
|
|
Grabbing,
|
|
Help,
|
|
Move,
|
|
NEResize,
|
|
NESWResize,
|
|
NResize,
|
|
NSResize,
|
|
NWResize,
|
|
NWSEResize,
|
|
NoDrop,
|
|
None,
|
|
NotAllowed,
|
|
Pointer,
|
|
Progress,
|
|
RowResize,
|
|
SResize,
|
|
SEResize,
|
|
SWResize,
|
|
Text,
|
|
Url,
|
|
WResize,
|
|
Wait,
|
|
ZoomIn,
|
|
ZoomOut,
|
|
};
|
|
enum class LayoutConformance : uint8_t { Strict, Compatibility };
|
|
template <typename T>
|
|
struct CascadedRectangleEdges {
|
|
using Counterpart = RectangleEdges<T>;
|
|
using OptionalT = std::optional<T>;
|
|
OptionalT left{};
|
|
OptionalT top{};
|
|
OptionalT right{};
|
|
OptionalT bottom{};
|
|
OptionalT start{};
|
|
OptionalT end{};
|
|
OptionalT horizontal{};
|
|
OptionalT vertical{};
|
|
OptionalT all{};
|
|
OptionalT block{};
|
|
OptionalT blockStart{};
|
|
OptionalT blockEnd{};
|
|
Counterpart resolve(bool isRTL, T defaults) const {
|
|
const auto leadingEdge = isRTL ? end : start;
|
|
const auto trailingEdge = isRTL ? start : end;
|
|
const auto horizontalOrAllOrDefault =
|
|
horizontal.value_or(all.value_or(defaults));
|
|
const auto verticalOrAllOrDefault =
|
|
vertical.value_or(all.value_or(defaults));
|
|
return {
|
|
left.value_or(leadingEdge.value_or(horizontalOrAllOrDefault)),
|
|
blockStart.value_or(
|
|
block.value_or(top.value_or(verticalOrAllOrDefault))),
|
|
right.value_or(trailingEdge.value_or(horizontalOrAllOrDefault)),
|
|
blockEnd.value_or(
|
|
block.value_or(bottom.value_or(verticalOrAllOrDefault))),
|
|
};
|
|
}
|
|
bool operator==(const CascadedRectangleEdges<T>& rhs) const {
|
|
return std::tie(
|
|
this->left,
|
|
this->top,
|
|
this->right,
|
|
this->bottom,
|
|
this->start,
|
|
this->end,
|
|
this->horizontal,
|
|
this->vertical,
|
|
this->all,
|
|
this->block,
|
|
this->blockStart,
|
|
this->blockEnd) ==
|
|
std::tie(
|
|
rhs.left,
|
|
rhs.top,
|
|
rhs.right,
|
|
rhs.bottom,
|
|
rhs.start,
|
|
rhs.end,
|
|
rhs.horizontal,
|
|
rhs.vertical,
|
|
rhs.all,
|
|
rhs.block,
|
|
rhs.blockStart,
|
|
rhs.blockEnd);
|
|
}
|
|
bool operator!=(const CascadedRectangleEdges<T>& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
template <typename T>
|
|
struct CascadedRectangleCorners {
|
|
using Counterpart = RectangleCorners<T>;
|
|
using OptionalT = std::optional<T>;
|
|
OptionalT topLeft{};
|
|
OptionalT topRight{};
|
|
OptionalT bottomLeft{};
|
|
OptionalT bottomRight{};
|
|
OptionalT topStart{};
|
|
OptionalT topEnd{};
|
|
OptionalT bottomStart{};
|
|
OptionalT bottomEnd{};
|
|
OptionalT all{};
|
|
OptionalT endEnd{};
|
|
OptionalT endStart{};
|
|
OptionalT startEnd{};
|
|
OptionalT startStart{};
|
|
Counterpart resolve(bool isRTL, T defaults) const {
|
|
const auto logicalTopStart = topStart ? topStart : startStart;
|
|
const auto logicalTopEnd = topEnd ? topEnd : startEnd;
|
|
const auto logicalBottomStart = bottomStart ? bottomStart : endStart;
|
|
const auto logicalBottomEnd = bottomEnd ? bottomEnd : endEnd;
|
|
const auto topLeading = isRTL ? logicalTopEnd : logicalTopStart;
|
|
const auto topTrailing = isRTL ? logicalTopStart : logicalTopEnd;
|
|
const auto bottomLeading = isRTL ? logicalBottomEnd : logicalBottomStart;
|
|
const auto bottomTrailing = isRTL ? logicalBottomStart : logicalBottomEnd;
|
|
return {
|
|
topLeft.value_or(topLeading.value_or(all.value_or(defaults))),
|
|
topRight.value_or(topTrailing.value_or(all.value_or(defaults))),
|
|
bottomLeft.value_or(bottomLeading.value_or(all.value_or(defaults))),
|
|
bottomRight.value_or(bottomTrailing.value_or(all.value_or(defaults))),
|
|
};
|
|
}
|
|
bool operator==(const CascadedRectangleCorners<T>& rhs) const {
|
|
return std::tie(
|
|
this->topLeft,
|
|
this->topRight,
|
|
this->bottomLeft,
|
|
this->bottomRight,
|
|
this->topStart,
|
|
this->topEnd,
|
|
this->bottomStart,
|
|
this->bottomEnd,
|
|
this->all,
|
|
this->endEnd,
|
|
this->endStart,
|
|
this->startEnd,
|
|
this->startStart) ==
|
|
std::tie(
|
|
rhs.topLeft,
|
|
rhs.topRight,
|
|
rhs.bottomLeft,
|
|
rhs.bottomRight,
|
|
rhs.topStart,
|
|
rhs.topEnd,
|
|
rhs.bottomStart,
|
|
rhs.bottomEnd,
|
|
rhs.all,
|
|
rhs.endEnd,
|
|
rhs.endStart,
|
|
rhs.startEnd,
|
|
rhs.startStart);
|
|
}
|
|
bool operator!=(const CascadedRectangleCorners<T>& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
using BorderWidths = RectangleEdges<Float>;
|
|
using BorderCurves = RectangleCorners<BorderCurve>;
|
|
using BorderStyles = RectangleEdges<BorderStyle>;
|
|
using BorderColors = RectangleEdges<SharedColor>;
|
|
using BorderRadii = RectangleCorners<CornerRadii>;
|
|
using CascadedBorderWidths = CascadedRectangleEdges<Float>;
|
|
using CascadedBorderCurves = CascadedRectangleCorners<BorderCurve>;
|
|
using CascadedBorderStyles = CascadedRectangleEdges<BorderStyle>;
|
|
using CascadedBorderColors = CascadedRectangleEdges<SharedColor>;
|
|
using CascadedBorderRadii = CascadedRectangleCorners<ValueUnit>;
|
|
struct BorderMetrics {
|
|
BorderColors borderColors{};
|
|
BorderWidths borderWidths{};
|
|
BorderRadii borderRadii{};
|
|
BorderCurves borderCurves{};
|
|
BorderStyles borderStyles{};
|
|
bool operator==(const BorderMetrics& rhs) const {
|
|
return std::tie(
|
|
this->borderColors,
|
|
this->borderWidths,
|
|
this->borderRadii,
|
|
this->borderCurves,
|
|
this->borderStyles) ==
|
|
std::tie(
|
|
rhs.borderColors,
|
|
rhs.borderWidths,
|
|
rhs.borderRadii,
|
|
rhs.borderCurves,
|
|
rhs.borderStyles);
|
|
}
|
|
bool operator!=(const BorderMetrics& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/view/propsConversions.h}:
|
|
namespace facebook::react {
|
|
static inline yoga::Style convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const yoga::Style& sourceValue) {
|
|
yoga::Style yogaStyle{};
|
|
yogaStyle.setDirection(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"direction",
|
|
sourceValue.direction(),
|
|
yogaStyle.direction()));
|
|
yogaStyle.setFlexDirection(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"flexDirection",
|
|
sourceValue.flexDirection(),
|
|
yogaStyle.flexDirection()));
|
|
yogaStyle.setJustifyContent(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"justifyContent",
|
|
sourceValue.justifyContent(),
|
|
yogaStyle.justifyContent()));
|
|
yogaStyle.setAlignContent(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"alignContent",
|
|
sourceValue.alignContent(),
|
|
yogaStyle.alignContent()));
|
|
yogaStyle.setAlignItems(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"alignItems",
|
|
sourceValue.alignItems(),
|
|
yogaStyle.alignItems()));
|
|
yogaStyle.setAlignSelf(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"alignSelf",
|
|
sourceValue.alignSelf(),
|
|
yogaStyle.alignSelf()));
|
|
yogaStyle.setPositionType(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"position",
|
|
sourceValue.positionType(),
|
|
yogaStyle.positionType()));
|
|
yogaStyle.setFlexWrap(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"flexWrap",
|
|
sourceValue.flexWrap(),
|
|
yogaStyle.flexWrap()));
|
|
yogaStyle.setOverflow(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"overflow",
|
|
sourceValue.overflow(),
|
|
yogaStyle.overflow()));
|
|
yogaStyle.setDisplay(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"display",
|
|
sourceValue.display(),
|
|
yogaStyle.display()));
|
|
yogaStyle.setFlex(convertRawProp(
|
|
context, rawProps, "flex", sourceValue.flex(), yogaStyle.flex()));
|
|
yogaStyle.setFlexGrow(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"flexGrow",
|
|
sourceValue.flexGrow(),
|
|
yogaStyle.flexGrow()));
|
|
yogaStyle.setFlexShrink(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"flexShrink",
|
|
sourceValue.flexShrink(),
|
|
yogaStyle.flexShrink()));
|
|
yogaStyle.setFlexBasis(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"flexBasis",
|
|
sourceValue.flexBasis(),
|
|
yogaStyle.flexBasis()));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Left,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginLeft",
|
|
sourceValue.margin(yoga::Edge::Left),
|
|
yogaStyle.margin(yoga::Edge::Left)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Top,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginTop",
|
|
sourceValue.margin(yoga::Edge::Top),
|
|
yogaStyle.margin(yoga::Edge::Top)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Right,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginRight",
|
|
sourceValue.margin(yoga::Edge::Right),
|
|
yogaStyle.margin(yoga::Edge::Right)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Bottom,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginBottom",
|
|
sourceValue.margin(yoga::Edge::Bottom),
|
|
yogaStyle.margin(yoga::Edge::Bottom)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Start,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginStart",
|
|
sourceValue.margin(yoga::Edge::Start),
|
|
yogaStyle.margin(yoga::Edge::Start)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::End,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginEnd",
|
|
sourceValue.margin(yoga::Edge::End),
|
|
yogaStyle.margin(yoga::Edge::End)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Horizontal,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginHorizontal",
|
|
sourceValue.margin(yoga::Edge::Horizontal),
|
|
yogaStyle.margin(yoga::Edge::Horizontal)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::Vertical,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"marginVertical",
|
|
sourceValue.margin(yoga::Edge::Vertical),
|
|
yogaStyle.margin(yoga::Edge::Vertical)));
|
|
yogaStyle.setMargin(
|
|
yoga::Edge::All,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"margin",
|
|
sourceValue.margin(yoga::Edge::All),
|
|
yogaStyle.margin(yoga::Edge::All)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Left,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"left",
|
|
sourceValue.position(yoga::Edge::Left),
|
|
yogaStyle.position(yoga::Edge::Left)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Top,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"top",
|
|
sourceValue.position(yoga::Edge::Top),
|
|
yogaStyle.position(yoga::Edge::Top)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Right,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"right",
|
|
sourceValue.position(yoga::Edge::Right),
|
|
yogaStyle.position(yoga::Edge::Right)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Bottom,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"bottom",
|
|
sourceValue.position(yoga::Edge::Bottom),
|
|
yogaStyle.position(yoga::Edge::Bottom)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Start,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"start",
|
|
sourceValue.position(yoga::Edge::Start),
|
|
yogaStyle.position(yoga::Edge::Start)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::End,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"end",
|
|
sourceValue.position(yoga::Edge::End),
|
|
yogaStyle.position(yoga::Edge::End)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Horizontal,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"insetInline",
|
|
sourceValue.position(yoga::Edge::Horizontal),
|
|
yogaStyle.position(yoga::Edge::Horizontal)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::Vertical,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"insetBlock",
|
|
sourceValue.position(yoga::Edge::Vertical),
|
|
yogaStyle.position(yoga::Edge::Vertical)));
|
|
yogaStyle.setPosition(
|
|
yoga::Edge::All,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"inset",
|
|
sourceValue.position(yoga::Edge::All),
|
|
yogaStyle.position(yoga::Edge::All)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Left,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingLeft",
|
|
sourceValue.padding(yoga::Edge::Left),
|
|
yogaStyle.padding(yoga::Edge::Left)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Top,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingTop",
|
|
sourceValue.padding(yoga::Edge::Top),
|
|
yogaStyle.padding(yoga::Edge::Top)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Right,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingRight",
|
|
sourceValue.padding(yoga::Edge::Right),
|
|
yogaStyle.padding(yoga::Edge::Right)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Bottom,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingBottom",
|
|
sourceValue.padding(yoga::Edge::Bottom),
|
|
yogaStyle.padding(yoga::Edge::Bottom)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Start,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingStart",
|
|
sourceValue.padding(yoga::Edge::Start),
|
|
yogaStyle.padding(yoga::Edge::Start)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::End,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingEnd",
|
|
sourceValue.padding(yoga::Edge::End),
|
|
yogaStyle.padding(yoga::Edge::End)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Horizontal,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingHorizontal",
|
|
sourceValue.padding(yoga::Edge::Horizontal),
|
|
yogaStyle.padding(yoga::Edge::Horizontal)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::Vertical,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"paddingVertical",
|
|
sourceValue.padding(yoga::Edge::Vertical),
|
|
yogaStyle.padding(yoga::Edge::Vertical)));
|
|
yogaStyle.setPadding(
|
|
yoga::Edge::All,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"padding",
|
|
sourceValue.padding(yoga::Edge::All),
|
|
yogaStyle.padding(yoga::Edge::All)));
|
|
yogaStyle.setGap(
|
|
yoga::Gutter::Row,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"rowGap",
|
|
sourceValue.gap(yoga::Gutter::Row),
|
|
yogaStyle.gap(yoga::Gutter::Row)));
|
|
yogaStyle.setGap(
|
|
yoga::Gutter::Column,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"columnGap",
|
|
sourceValue.gap(yoga::Gutter::Column),
|
|
yogaStyle.gap(yoga::Gutter::Column)));
|
|
yogaStyle.setGap(
|
|
yoga::Gutter::All,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"gap",
|
|
sourceValue.gap(yoga::Gutter::All),
|
|
yogaStyle.gap(yoga::Gutter::All)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Left,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderLeftWidth",
|
|
sourceValue.border(yoga::Edge::Left),
|
|
yogaStyle.border(yoga::Edge::Left)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Top,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderTopWidth",
|
|
sourceValue.border(yoga::Edge::Top),
|
|
yogaStyle.border(yoga::Edge::Top)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Right,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderRightWidth",
|
|
sourceValue.border(yoga::Edge::Right),
|
|
yogaStyle.border(yoga::Edge::Right)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Bottom,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderBottomWidth",
|
|
sourceValue.border(yoga::Edge::Bottom),
|
|
yogaStyle.border(yoga::Edge::Bottom)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Start,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderStartWidth",
|
|
sourceValue.border(yoga::Edge::Start),
|
|
yogaStyle.border(yoga::Edge::Start)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::End,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderEndWidth",
|
|
sourceValue.border(yoga::Edge::End),
|
|
yogaStyle.border(yoga::Edge::End)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Horizontal,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderHorizontalWidth",
|
|
sourceValue.border(yoga::Edge::Horizontal),
|
|
yogaStyle.border(yoga::Edge::Horizontal)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::Vertical,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderVerticalWidth",
|
|
sourceValue.border(yoga::Edge::Vertical),
|
|
yogaStyle.border(yoga::Edge::Vertical)));
|
|
yogaStyle.setBorder(
|
|
yoga::Edge::All,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"borderWidth",
|
|
sourceValue.border(yoga::Edge::All),
|
|
yogaStyle.border(yoga::Edge::All)));
|
|
yogaStyle.setDimension(
|
|
yoga::Dimension::Width,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"width",
|
|
sourceValue.dimension(yoga::Dimension::Width),
|
|
{}));
|
|
yogaStyle.setDimension(
|
|
yoga::Dimension::Height,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"height",
|
|
sourceValue.dimension(yoga::Dimension::Height),
|
|
{}));
|
|
yogaStyle.setMinDimension(
|
|
yoga::Dimension::Width,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"minWidth",
|
|
sourceValue.minDimension(yoga::Dimension::Width),
|
|
{}));
|
|
yogaStyle.setMinDimension(
|
|
yoga::Dimension::Height,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"minHeight",
|
|
sourceValue.minDimension(yoga::Dimension::Height),
|
|
{}));
|
|
yogaStyle.setMaxDimension(
|
|
yoga::Dimension::Width,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"maxWidth",
|
|
sourceValue.maxDimension(yoga::Dimension::Width),
|
|
{}));
|
|
yogaStyle.setMaxDimension(
|
|
yoga::Dimension::Height,
|
|
convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"maxHeight",
|
|
sourceValue.maxDimension(yoga::Dimension::Height),
|
|
{}));
|
|
yogaStyle.setAspectRatio(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"aspectRatio",
|
|
sourceValue.aspectRatio(),
|
|
yogaStyle.aspectRatio()));
|
|
yogaStyle.setBoxSizing(convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"boxSizing",
|
|
sourceValue.boxSizing(),
|
|
yogaStyle.boxSizing()));
|
|
return yogaStyle;
|
|
}
|
|
template <typename T>
|
|
static inline CascadedRectangleCorners<T> convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const char* prefix,
|
|
const char* suffix,
|
|
const CascadedRectangleCorners<T>& sourceValue,
|
|
const CascadedRectangleCorners<T>& defaultValue) {
|
|
CascadedRectangleCorners<T> result;
|
|
result.topLeft = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"TopLeft",
|
|
sourceValue.topLeft,
|
|
defaultValue.topLeft,
|
|
prefix,
|
|
suffix);
|
|
result.topRight = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"TopRight",
|
|
sourceValue.topRight,
|
|
defaultValue.topRight,
|
|
prefix,
|
|
suffix);
|
|
result.bottomLeft = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"BottomLeft",
|
|
sourceValue.bottomLeft,
|
|
defaultValue.bottomLeft,
|
|
prefix,
|
|
suffix);
|
|
result.bottomRight = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"BottomRight",
|
|
sourceValue.bottomRight,
|
|
defaultValue.bottomRight,
|
|
prefix,
|
|
suffix);
|
|
result.topStart = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"TopStart",
|
|
sourceValue.topStart,
|
|
defaultValue.topStart,
|
|
prefix,
|
|
suffix);
|
|
result.topEnd = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"TopEnd",
|
|
sourceValue.topEnd,
|
|
defaultValue.topEnd,
|
|
prefix,
|
|
suffix);
|
|
result.bottomStart = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"BottomStart",
|
|
sourceValue.bottomStart,
|
|
defaultValue.bottomStart,
|
|
prefix,
|
|
suffix);
|
|
result.bottomEnd = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"BottomEnd",
|
|
sourceValue.bottomEnd,
|
|
defaultValue.bottomEnd,
|
|
prefix,
|
|
suffix);
|
|
result.endEnd = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"EndEnd",
|
|
sourceValue.endEnd,
|
|
defaultValue.endEnd,
|
|
prefix,
|
|
suffix);
|
|
result.endStart = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"EndStart",
|
|
sourceValue.endStart,
|
|
defaultValue.endStart,
|
|
prefix,
|
|
suffix);
|
|
result.startEnd = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"StartEnd",
|
|
sourceValue.startEnd,
|
|
defaultValue.startEnd,
|
|
prefix,
|
|
suffix);
|
|
result.startStart = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"StartStart",
|
|
sourceValue.startStart,
|
|
defaultValue.startStart,
|
|
prefix,
|
|
suffix);
|
|
result.all = convertRawProp(
|
|
context, rawProps, "", sourceValue.all, defaultValue.all, prefix, suffix);
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
static inline CascadedRectangleEdges<T> convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const char* prefix,
|
|
const char* suffix,
|
|
const CascadedRectangleEdges<T>& sourceValue,
|
|
const CascadedRectangleEdges<T>& defaultValue) {
|
|
CascadedRectangleEdges<T> result;
|
|
result.left = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Left",
|
|
sourceValue.left,
|
|
defaultValue.left,
|
|
prefix,
|
|
suffix);
|
|
result.right = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Right",
|
|
sourceValue.right,
|
|
defaultValue.right,
|
|
prefix,
|
|
suffix);
|
|
result.top = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Top",
|
|
sourceValue.top,
|
|
defaultValue.top,
|
|
prefix,
|
|
suffix);
|
|
result.bottom = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Bottom",
|
|
sourceValue.bottom,
|
|
defaultValue.bottom,
|
|
prefix,
|
|
suffix);
|
|
result.start = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Start",
|
|
sourceValue.start,
|
|
defaultValue.start,
|
|
prefix,
|
|
suffix);
|
|
result.end = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"End",
|
|
sourceValue.end,
|
|
defaultValue.end,
|
|
prefix,
|
|
suffix);
|
|
result.horizontal = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Horizontal",
|
|
sourceValue.horizontal,
|
|
defaultValue.horizontal,
|
|
prefix,
|
|
suffix);
|
|
result.vertical = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Vertical",
|
|
sourceValue.vertical,
|
|
defaultValue.vertical,
|
|
prefix,
|
|
suffix);
|
|
result.block = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"Block",
|
|
sourceValue.block,
|
|
defaultValue.block,
|
|
prefix,
|
|
suffix);
|
|
result.blockEnd = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"BlockEnd",
|
|
sourceValue.blockEnd,
|
|
defaultValue.blockEnd,
|
|
prefix,
|
|
suffix);
|
|
result.blockStart = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"BlockStart",
|
|
sourceValue.blockStart,
|
|
defaultValue.blockStart,
|
|
prefix,
|
|
suffix);
|
|
result.all = convertRawProp(
|
|
context, rawProps, "", sourceValue.all, defaultValue.all, prefix, suffix);
|
|
return result;
|
|
}
|
|
static inline ViewEvents convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const ViewEvents& sourceValue,
|
|
const ViewEvents& defaultValue) {
|
|
ViewEvents result{};
|
|
using Offset = ViewEvents::Offset;
|
|
result[Offset::PointerEnter] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerEnter",
|
|
sourceValue[Offset::PointerEnter],
|
|
defaultValue[Offset::PointerEnter]);
|
|
result[Offset::PointerMove] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerMove",
|
|
sourceValue[Offset::PointerMove],
|
|
defaultValue[Offset::PointerMove]);
|
|
result[Offset::PointerLeave] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerLeave",
|
|
sourceValue[Offset::PointerLeave],
|
|
defaultValue[Offset::PointerLeave]);
|
|
result[Offset::PointerEnterCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerEnterCapture",
|
|
sourceValue[Offset::PointerEnterCapture],
|
|
defaultValue[Offset::PointerEnterCapture]);
|
|
result[Offset::PointerMoveCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerMoveCapture",
|
|
sourceValue[Offset::PointerMoveCapture],
|
|
defaultValue[Offset::PointerMoveCapture]);
|
|
result[Offset::PointerLeaveCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerLeaveCapture",
|
|
sourceValue[Offset::PointerLeaveCapture],
|
|
defaultValue[Offset::PointerLeaveCapture]);
|
|
result[Offset::PointerOver] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerOver",
|
|
sourceValue[Offset::PointerOver],
|
|
defaultValue[Offset::PointerOver]);
|
|
result[Offset::PointerOverCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerOverCapture",
|
|
sourceValue[Offset::PointerOverCapture],
|
|
defaultValue[Offset::PointerOverCapture]);
|
|
result[Offset::PointerOut] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerOut",
|
|
sourceValue[Offset::PointerOut],
|
|
defaultValue[Offset::PointerOut]);
|
|
result[Offset::PointerOutCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerOutCapture",
|
|
sourceValue[Offset::PointerOutCapture],
|
|
defaultValue[Offset::PointerOutCapture]);
|
|
result[Offset::Click] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onClick",
|
|
sourceValue[Offset::Click],
|
|
defaultValue[Offset::Click]);
|
|
result[Offset::ClickCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onClickCapture",
|
|
sourceValue[Offset::ClickCapture],
|
|
defaultValue[Offset::ClickCapture]);
|
|
result[Offset::PointerDown] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerDown",
|
|
sourceValue[Offset::PointerDown],
|
|
defaultValue[Offset::PointerDown]);
|
|
result[Offset::PointerDownCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerDownCapture",
|
|
sourceValue[Offset::PointerDownCapture],
|
|
defaultValue[Offset::PointerDownCapture]);
|
|
result[Offset::PointerUp] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerUp",
|
|
sourceValue[Offset::PointerUp],
|
|
defaultValue[Offset::PointerUp]);
|
|
result[Offset::PointerUpCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onPointerUpCapture",
|
|
sourceValue[Offset::PointerUpCapture],
|
|
defaultValue[Offset::PointerUpCapture]);
|
|
result[Offset::MoveShouldSetResponder] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onMoveShouldSetResponder",
|
|
sourceValue[Offset::MoveShouldSetResponder],
|
|
defaultValue[Offset::MoveShouldSetResponder]);
|
|
result[Offset::MoveShouldSetResponderCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onMoveShouldSetResponderCapture",
|
|
sourceValue[Offset::MoveShouldSetResponderCapture],
|
|
defaultValue[Offset::MoveShouldSetResponderCapture]);
|
|
result[Offset::StartShouldSetResponder] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onStartShouldSetResponder",
|
|
sourceValue[Offset::StartShouldSetResponder],
|
|
defaultValue[Offset::StartShouldSetResponder]);
|
|
result[Offset::StartShouldSetResponderCapture] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onStartShouldSetResponderCapture",
|
|
sourceValue[Offset::StartShouldSetResponderCapture],
|
|
defaultValue[Offset::StartShouldSetResponderCapture]);
|
|
result[Offset::ResponderGrant] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderGrant",
|
|
sourceValue[Offset::ResponderGrant],
|
|
defaultValue[Offset::ResponderGrant]);
|
|
result[Offset::ResponderReject] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderReject",
|
|
sourceValue[Offset::ResponderReject],
|
|
defaultValue[Offset::ResponderReject]);
|
|
result[Offset::ResponderStart] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderStart",
|
|
sourceValue[Offset::ResponderStart],
|
|
defaultValue[Offset::ResponderStart]);
|
|
result[Offset::ResponderEnd] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderEnd",
|
|
sourceValue[Offset::ResponderEnd],
|
|
defaultValue[Offset::ResponderEnd]);
|
|
result[Offset::ResponderRelease] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderRelease",
|
|
sourceValue[Offset::ResponderRelease],
|
|
defaultValue[Offset::ResponderRelease]);
|
|
result[Offset::ResponderMove] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderMove",
|
|
sourceValue[Offset::ResponderMove],
|
|
defaultValue[Offset::ResponderMove]);
|
|
result[Offset::ResponderTerminate] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderTerminate",
|
|
sourceValue[Offset::ResponderTerminate],
|
|
defaultValue[Offset::ResponderTerminate]);
|
|
result[Offset::ResponderTerminationRequest] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onResponderTerminationRequest",
|
|
sourceValue[Offset::ResponderTerminationRequest],
|
|
defaultValue[Offset::ResponderTerminationRequest]);
|
|
result[Offset::ShouldBlockNativeResponder] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onShouldBlockNativeResponder",
|
|
sourceValue[Offset::ShouldBlockNativeResponder],
|
|
defaultValue[Offset::ShouldBlockNativeResponder]);
|
|
result[Offset::TouchStart] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onTouchStart",
|
|
sourceValue[Offset::TouchStart],
|
|
defaultValue[Offset::TouchStart]);
|
|
result[Offset::TouchMove] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onTouchMove",
|
|
sourceValue[Offset::TouchMove],
|
|
defaultValue[Offset::TouchMove]);
|
|
result[Offset::TouchEnd] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onTouchEnd",
|
|
sourceValue[Offset::TouchEnd],
|
|
defaultValue[Offset::TouchEnd]);
|
|
result[Offset::TouchCancel] = convertRawProp(
|
|
context,
|
|
rawProps,
|
|
"onTouchCancel",
|
|
sourceValue[Offset::TouchCancel],
|
|
defaultValue[Offset::TouchCancel]);
|
|
return result;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/virtualview/VirtualViewComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using VirtualViewComponentDescriptor =
|
|
ConcreteComponentDescriptor<VirtualViewShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/virtualview/VirtualViewShadowNode.h}:
|
|
namespace facebook::react {
|
|
constexpr const char VirtualViewComponentName[] = "VirtualView";
|
|
class VirtualViewShadowNode final : public ConcreteViewShadowNode<
|
|
VirtualViewComponentName,
|
|
VirtualViewProps,
|
|
VirtualViewEventEmitter> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::Unstable_uncullableView);
|
|
return traits;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/virtualviewexperimental/VirtualViewExperimentalComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using VirtualViewExperimentalComponentDescriptor =
|
|
ConcreteComponentDescriptor<VirtualViewExperimentalShadowNode>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/components/virtualviewexperimental/VirtualViewExperimentalShadowNode.h}:
|
|
namespace facebook::react {
|
|
constexpr const char VirtualViewExperimentalComponentName[] =
|
|
"VirtualViewExperimental";
|
|
class VirtualViewExperimentalShadowNode final
|
|
: public ConcreteViewShadowNode<
|
|
VirtualViewExperimentalComponentName,
|
|
VirtualViewExperimentalProps,
|
|
VirtualViewEventEmitter> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
static ShadowNodeTraits BaseTraits() {
|
|
auto traits = ConcreteViewShadowNode::BaseTraits();
|
|
traits.set(ShadowNodeTraits::Trait::Unstable_uncullableView);
|
|
return traits;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/consistency/ScopedShadowTreeRevisionLock.h}:
|
|
namespace facebook::react {
|
|
class ScopedShadowTreeRevisionLock {
|
|
public:
|
|
explicit ScopedShadowTreeRevisionLock(
|
|
ShadowTreeRevisionConsistencyManager* consistencyManager) noexcept
|
|
: consistencyManager_(consistencyManager) {
|
|
if (consistencyManager_ != nullptr) {
|
|
consistencyManager_->lockRevisions();
|
|
}
|
|
}
|
|
ScopedShadowTreeRevisionLock(const ScopedShadowTreeRevisionLock&) = delete;
|
|
ScopedShadowTreeRevisionLock(ScopedShadowTreeRevisionLock&&) = delete;
|
|
ScopedShadowTreeRevisionLock& operator=(const ScopedShadowTreeRevisionLock&) =
|
|
delete;
|
|
ScopedShadowTreeRevisionLock& operator=(ScopedShadowTreeRevisionLock&&) =
|
|
delete;
|
|
~ScopedShadowTreeRevisionLock() noexcept {
|
|
if (consistencyManager_ != nullptr) {
|
|
consistencyManager_->unlockRevisions();
|
|
}
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/consistency/ShadowTreeRevisionConsistencyManager.h}:
|
|
namespace facebook::react {
|
|
class ShadowTreeRevisionConsistencyManager {
|
|
public:
|
|
virtual ~ShadowTreeRevisionConsistencyManager() = default;
|
|
virtual void lockRevisions() = 0;
|
|
virtual void unlockRevisions() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
using SharedComponentDescriptor = std::shared_ptr<const ComponentDescriptor>;
|
|
class ComponentDescriptor {
|
|
public:
|
|
using Shared = std::shared_ptr<const ComponentDescriptor>;
|
|
using Unique = std::unique_ptr<const ComponentDescriptor>;
|
|
using Flavor = std::shared_ptr<const void>;
|
|
explicit ComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters,
|
|
RawPropsParser&& rawPropsParser = {});
|
|
virtual ~ComponentDescriptor() = default;
|
|
const std::shared_ptr<const ContextContainer>& getContextContainer() const;
|
|
virtual ComponentHandle getComponentHandle() const = 0;
|
|
virtual ComponentName getComponentName() const = 0;
|
|
virtual ShadowNodeTraits getTraits() const = 0;
|
|
virtual std::shared_ptr<ShadowNode> createShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family) const = 0;
|
|
virtual std::shared_ptr<ShadowNode> cloneShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment) const = 0;
|
|
virtual void appendChild(
|
|
const std::shared_ptr<const ShadowNode>& parentShadowNode,
|
|
const std::shared_ptr<const ShadowNode>& childShadowNode) const = 0;
|
|
virtual Props::Shared cloneProps(
|
|
const PropsParserContext& context,
|
|
const Props::Shared& props,
|
|
RawProps rawProps) const = 0;
|
|
virtual State::Shared createInitialState(
|
|
const Props::Shared& props,
|
|
const ShadowNodeFamily::Shared& family) const = 0;
|
|
virtual State::Shared createState(
|
|
const ShadowNodeFamily& family,
|
|
const StateData::Shared& data) const = 0;
|
|
virtual ShadowNodeFamily::Shared createFamily(
|
|
const ShadowNodeFamilyFragment& fragment) const = 0;
|
|
|
|
protected:
|
|
friend ShadowNode;
|
|
EventDispatcher::Weak eventDispatcher_;
|
|
std::shared_ptr<const ContextContainer> contextContainer_;
|
|
Flavor flavor_;
|
|
RawPropsParser rawPropsParser_;
|
|
virtual void adopt(ShadowNode& shadowNode) const = 0;
|
|
};
|
|
class ComponentDescriptorParameters {
|
|
public:
|
|
EventDispatcher::Weak eventDispatcher;
|
|
std::shared_ptr<const ContextContainer> contextContainer;
|
|
ComponentDescriptor::Flavor flavor;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ConcreteComponentDescriptor.h}:
|
|
namespace facebook::react {
|
|
template <typename ShadowNodeT>
|
|
class ConcreteComponentDescriptor : public ComponentDescriptor {
|
|
static_assert(
|
|
std::is_base_of<ShadowNode, ShadowNodeT>::value,
|
|
"ShadowNodeT must be a descendant of ShadowNode");
|
|
using SharedShadowNodeT = std::shared_ptr<const ShadowNodeT>;
|
|
|
|
public:
|
|
using ConcreteShadowNode = ShadowNodeT;
|
|
using ConcreteProps = typename ShadowNodeT::ConcreteProps;
|
|
using SharedConcreteProps = typename ShadowNodeT::SharedConcreteProps;
|
|
using ConcreteEventEmitter = typename ShadowNodeT::ConcreteEventEmitter;
|
|
using SharedConcreteEventEmitter =
|
|
typename ShadowNodeT::SharedConcreteEventEmitter;
|
|
using ConcreteState = typename ShadowNodeT::ConcreteState;
|
|
using ConcreteStateData = typename ShadowNodeT::ConcreteState::Data;
|
|
explicit ConcreteComponentDescriptor(
|
|
const ComponentDescriptorParameters& parameters,
|
|
RawPropsParser&& rawPropsParser = {})
|
|
: ComponentDescriptor(parameters, std::move(rawPropsParser)) {
|
|
rawPropsParser_.prepare<ConcreteProps>();
|
|
}
|
|
ComponentHandle getComponentHandle() const override {
|
|
return ShadowNodeT::Handle();
|
|
}
|
|
ComponentName getComponentName() const override {
|
|
return ShadowNodeT::Name();
|
|
}
|
|
ShadowNodeTraits getTraits() const override {
|
|
return ShadowNodeT::BaseTraits();
|
|
}
|
|
std::shared_ptr<ShadowNode> createShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family) const override {
|
|
auto shadowNode =
|
|
std::make_shared<ShadowNodeT>(fragment, family, getTraits());
|
|
adopt(*shadowNode);
|
|
return shadowNode;
|
|
}
|
|
std::shared_ptr<ShadowNode> cloneShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment) const override {
|
|
auto shadowNode = std::make_shared<ShadowNodeT>(sourceShadowNode, fragment);
|
|
shadowNode->completeClone(sourceShadowNode, fragment);
|
|
sourceShadowNode.transferRuntimeShadowNodeReference(shadowNode, fragment);
|
|
adopt(*shadowNode);
|
|
return shadowNode;
|
|
}
|
|
void appendChild(
|
|
const std::shared_ptr<const ShadowNode>& parentShadowNode,
|
|
const std::shared_ptr<const ShadowNode>& childShadowNode) const override {
|
|
auto& concreteParentShadowNode =
|
|
static_cast<const ShadowNodeT&>(*parentShadowNode);
|
|
const_cast<ShadowNodeT&>(concreteParentShadowNode)
|
|
.appendChild(childShadowNode);
|
|
}
|
|
virtual Props::Shared cloneProps(
|
|
const PropsParserContext& context,
|
|
const Props::Shared& props,
|
|
RawProps rawProps) const override {
|
|
if (!props && rawProps.isEmpty()) {
|
|
return ShadowNodeT::defaultSharedProps();
|
|
}
|
|
if constexpr (RawPropsFilterable<ShadowNodeT>) {
|
|
ShadowNodeT::filterRawProps(rawProps);
|
|
}
|
|
rawProps.parse(rawPropsParser_);
|
|
auto shadowNodeProps = ShadowNodeT::Props(context, rawProps, props);
|
|
if (ReactNativeFeatureFlags::enableCppPropsIteratorSetter()) {
|
|
const auto& dynamic = static_cast<folly::dynamic>(rawProps);
|
|
for (const auto& pair : dynamic.items()) {
|
|
const auto& name = pair.first.getString();
|
|
shadowNodeProps->setProp(
|
|
context,
|
|
RAW_PROPS_KEY_HASH(name),
|
|
name.c_str(),
|
|
RawValue(pair.second));
|
|
}
|
|
}
|
|
return shadowNodeProps;
|
|
};
|
|
virtual State::Shared createInitialState(
|
|
const Props::Shared& props,
|
|
const ShadowNodeFamily::Shared& family) const override {
|
|
if (std::is_same<ConcreteStateData, StateData>::value) {
|
|
return nullptr;
|
|
}
|
|
return std::make_shared<ConcreteState>(
|
|
std::make_shared<const ConcreteStateData>(
|
|
ConcreteShadowNode::initialStateData(props, family, *this)),
|
|
family);
|
|
}
|
|
virtual State::Shared createState(
|
|
const ShadowNodeFamily& family,
|
|
const StateData::Shared& data) const override {
|
|
if (std::is_same<ConcreteStateData, StateData>::value) {
|
|
return nullptr;
|
|
}
|
|
react_native_assert(data && "Provided `data` is nullptr.");
|
|
return std::make_shared<const ConcreteState>(
|
|
std::static_pointer_cast<const ConcreteStateData>(data),
|
|
*family.getMostRecentState());
|
|
}
|
|
ShadowNodeFamily::Shared createFamily(
|
|
const ShadowNodeFamilyFragment& fragment) const override {
|
|
auto eventEmitter = std::make_shared<const ConcreteEventEmitter>(
|
|
std::make_shared<EventTarget>(
|
|
fragment.instanceHandle, fragment.surfaceId),
|
|
eventDispatcher_);
|
|
auto family = std::make_shared<ShadowNodeFamily>(
|
|
fragment, eventEmitter, eventDispatcher_, *this);
|
|
eventEmitter->setShadowNodeFamily(family);
|
|
return family;
|
|
}
|
|
|
|
protected:
|
|
virtual void adopt(ShadowNode& shadowNode) const override {
|
|
react_native_assert(
|
|
shadowNode.getComponentHandle() == getComponentHandle());
|
|
}
|
|
};
|
|
template <typename TManager>
|
|
std::shared_ptr<TManager> getManagerByName(
|
|
std::shared_ptr<const ContextContainer>& contextContainer,
|
|
const char name[]) {
|
|
if (contextContainer) {
|
|
if (auto manager = contextContainer->find<std::shared_ptr<TManager>>(name);
|
|
manager.has_value()) {
|
|
return manager.value();
|
|
}
|
|
}
|
|
return std::make_shared<TManager>(contextContainer);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ConcreteShadowNode.h}:
|
|
namespace facebook::react {
|
|
template <
|
|
ComponentName concreteComponentName,
|
|
typename BaseShadowNodeT,
|
|
typename PropsT,
|
|
typename EventEmitterT = EventEmitter,
|
|
typename StateDataT = StateData>
|
|
class ConcreteShadowNode : public BaseShadowNodeT {
|
|
static_assert(
|
|
std::is_base_of<ShadowNode, BaseShadowNodeT>::value,
|
|
"BaseShadowNodeT must be a descendant of ShadowNode");
|
|
static_assert(
|
|
std::is_base_of<Props, PropsT>::value,
|
|
"PropsT must be a descendant of Props");
|
|
|
|
protected:
|
|
using ShadowNode::props_;
|
|
using ShadowNode::state_;
|
|
|
|
public:
|
|
using BaseShadowNodeT::BaseShadowNodeT;
|
|
using ConcreteProps = PropsT;
|
|
using SharedConcreteProps = std::shared_ptr<const PropsT>;
|
|
using UnsharedConcreteProps = std::shared_ptr<PropsT>;
|
|
using ConcreteEventEmitter = EventEmitterT;
|
|
using SharedConcreteEventEmitter = std::shared_ptr<const EventEmitterT>;
|
|
using SharedConcreteShadowNode = std::shared_ptr<const ConcreteShadowNode>;
|
|
using ConcreteState = ConcreteState<StateDataT>;
|
|
using ConcreteStateData = StateDataT;
|
|
static ComponentName Name() {
|
|
return ComponentName(concreteComponentName);
|
|
}
|
|
static ComponentHandle Handle() {
|
|
return ComponentHandle(concreteComponentName);
|
|
}
|
|
static ShadowNodeTraits BaseTraits() {
|
|
return BaseShadowNodeT::BaseTraits();
|
|
}
|
|
static UnsharedConcreteProps Props(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const Props::Shared& baseProps = nullptr) {
|
|
return std::make_shared<PropsT>(
|
|
context,
|
|
baseProps ? static_cast<const PropsT&>(*baseProps)
|
|
: *defaultSharedProps(),
|
|
rawProps);
|
|
}
|
|
static const SharedConcreteProps& defaultSharedProps() {
|
|
static const SharedConcreteProps defaultSharedProps =
|
|
std::make_shared<const PropsT>();
|
|
return defaultSharedProps;
|
|
}
|
|
static ConcreteStateData initialStateData(
|
|
const Props::Shared&,
|
|
const ShadowNodeFamily::Shared&,
|
|
const ComponentDescriptor&) {
|
|
return {};
|
|
}
|
|
const ConcreteProps& getConcreteProps() const {
|
|
react_native_assert(
|
|
BaseShadowNodeT::props_ && "Props must not be `nullptr`.");
|
|
return static_cast<const ConcreteProps&>(*props_);
|
|
}
|
|
const std::shared_ptr<const ConcreteProps>& getConcreteSharedProps() const {
|
|
react_native_assert(
|
|
BaseShadowNodeT::props_ && "Props must not be `nullptr`.");
|
|
return std::static_pointer_cast<const ConcreteProps>(props_);
|
|
}
|
|
const ConcreteEventEmitter& getConcreteEventEmitter() const {
|
|
return static_cast<const ConcreteEventEmitter&>(
|
|
*BaseShadowNodeT::getEventEmitter());
|
|
}
|
|
const ConcreteStateData& getStateData() const {
|
|
react_native_assert(state_ && "State must not be `nullptr`.");
|
|
return static_cast<const ConcreteState*>(state_.get())->getData();
|
|
}
|
|
void setStateData(ConcreteStateData&& data) {
|
|
Sealable::ensureUnsealed();
|
|
state_ = std::make_shared<const ConcreteState>(
|
|
std::make_shared<const ConcreteStateData>(std::move(data)), *state_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ConcreteState.h}:
|
|
namespace facebook::react {
|
|
template <typename DataT>
|
|
class ConcreteState : public State {
|
|
public:
|
|
using Shared = std::shared_ptr<const ConcreteState>;
|
|
using Data = DataT;
|
|
using SharedData = std::shared_ptr<const Data>;
|
|
explicit ConcreteState(SharedData data, const State& previousState)
|
|
: State(std::move(data), previousState) {}
|
|
explicit ConcreteState(SharedData data, ShadowNodeFamily::Weak family)
|
|
: State(std::move(data), std::move(family)) {}
|
|
~ConcreteState() override = default;
|
|
const Data& getData() const {
|
|
return *static_cast<const Data*>(data_.get());
|
|
}
|
|
void updateState(
|
|
Data&& newData,
|
|
EventQueue::UpdateMode updateMode =
|
|
EventQueue::UpdateMode::Asynchronous) const {
|
|
updateState(
|
|
[data{std::move(newData)}](const Data&) -> SharedData {
|
|
return std::make_shared<const Data>(data);
|
|
},
|
|
updateMode);
|
|
}
|
|
void updateState(
|
|
std::function<StateData::Shared(const Data& oldData)> callback,
|
|
EventQueue::UpdateMode updateMode =
|
|
EventQueue::UpdateMode::Asynchronous) const {
|
|
auto family = family_.lock();
|
|
if (!family) {
|
|
return;
|
|
}
|
|
auto stateUpdate = StateUpdate{
|
|
family, [=](const StateData::Shared& oldData) -> StateData::Shared {
|
|
react_native_assert(oldData);
|
|
return callback(*static_cast<const Data*>(oldData.get()));
|
|
}};
|
|
family->dispatchRawState(std::move(stateUpdate), updateMode);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/DynamicEventPayload.h}:
|
|
namespace facebook::react {
|
|
struct DynamicEventPayload : public EventPayload {
|
|
explicit DynamicEventPayload(folly::dynamic&& payload);
|
|
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
|
|
EventPayloadType getType() const override;
|
|
std::optional<double> extractValue(
|
|
const std::vector<std::string>& path) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/DynamicPropsUtilities.h}:
|
|
namespace facebook::react {
|
|
enum class NullValueStrategy { Override, Ignore };
|
|
folly::dynamic mergeDynamicProps(
|
|
const folly::dynamic& source,
|
|
const folly::dynamic& patch,
|
|
NullValueStrategy nullValueStrategy);
|
|
folly::dynamic diffDynamicProps(
|
|
const folly::dynamic& oldProps,
|
|
const folly::dynamic& newProps);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventBeat.h}:
|
|
namespace facebook::react {
|
|
}
|
|
namespace facebook::jsi {
|
|
}
|
|
namespace facebook::react {
|
|
class EventBeat {
|
|
public:
|
|
struct OwnerBox {
|
|
std::weak_ptr<const void> owner;
|
|
};
|
|
using Factory = std::function<std::unique_ptr<EventBeat>(
|
|
std::shared_ptr<OwnerBox> ownerBox)>;
|
|
using BeatCallback = std::function<void(jsi::Runtime& runtime)>;
|
|
explicit EventBeat(
|
|
std::shared_ptr<OwnerBox> ownerBox,
|
|
RuntimeScheduler& runtimeScheduler);
|
|
virtual ~EventBeat() = default;
|
|
EventBeat(const EventBeat& other) = delete;
|
|
EventBeat& operator=(const EventBeat& other) = delete;
|
|
virtual void request() const;
|
|
virtual void requestSynchronous() const;
|
|
void setBeatCallback(BeatCallback beatCallback);
|
|
void unstable_setInduceCallback(std::function<void()> callback);
|
|
|
|
protected:
|
|
void induce() const;
|
|
BeatCallback beatCallback_;
|
|
std::function<void()> induceCallback_;
|
|
std::shared_ptr<OwnerBox> ownerBox_;
|
|
mutable std::atomic<bool> isEventBeatRequested_{false};
|
|
};
|
|
mutable std::atomic<bool> isSynchronousRequested_{false};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventDispatcher.h}:
|
|
namespace facebook::react {
|
|
class EventDispatcher {
|
|
public:
|
|
using Shared = std::shared_ptr<const EventDispatcher>;
|
|
using Weak = std::weak_ptr<const EventDispatcher>;
|
|
EventDispatcher(
|
|
const EventQueueProcessor& eventProcessor,
|
|
std::unique_ptr<EventBeat> eventBeat,
|
|
StatePipe statePipe,
|
|
std::weak_ptr<EventLogger> eventLogger);
|
|
void dispatchEvent(RawEvent&& rawEvent) const;
|
|
void experimental_flushSync() const;
|
|
void dispatchUniqueEvent(RawEvent&& rawEvent) const;
|
|
void dispatchStateUpdate(
|
|
StateUpdate&& stateUpdate,
|
|
EventQueue::UpdateMode updateMode) const;
|
|
void addListener(std::shared_ptr<const EventListener> listener) const;
|
|
void removeListener(
|
|
const std::shared_ptr<const EventListener>& listener) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventEmitter.h}:
|
|
namespace facebook::react {
|
|
using SharedEventEmitter = std::shared_ptr<const EventEmitter>;
|
|
class EventEmitter {
|
|
public:
|
|
using Shared = std::shared_ptr<const EventEmitter>;
|
|
static std::string normalizeEventType(std::string type);
|
|
static std::mutex& DispatchMutex();
|
|
static ValueFactory defaultPayloadFactory();
|
|
EventEmitter(
|
|
SharedEventTarget eventTarget,
|
|
EventDispatcher::Weak eventDispatcher);
|
|
virtual ~EventEmitter() = default;
|
|
void setEnabled(bool enabled) const;
|
|
void setShadowNodeFamily(
|
|
std::weak_ptr<const ShadowNodeFamily> shadowNodeFamily) const;
|
|
const SharedEventTarget& getEventTarget() const;
|
|
template <typename Lambda>
|
|
void experimental_flushSync(Lambda syncFunc) const {
|
|
auto eventDispatcher = eventDispatcher_.lock();
|
|
if (!eventDispatcher) {
|
|
return;
|
|
}
|
|
syncFunc();
|
|
eventDispatcher->experimental_flushSync();
|
|
}
|
|
void dispatchEvent(
|
|
std::string type,
|
|
const ValueFactory& payloadFactory =
|
|
EventEmitter::defaultPayloadFactory(),
|
|
RawEvent::Category category = RawEvent::Category::Unspecified) const;
|
|
void dispatchEvent(
|
|
std::string type,
|
|
folly::dynamic&& payload,
|
|
RawEvent::Category category = RawEvent::Category::Unspecified) const;
|
|
void dispatchEvent(
|
|
std::string type,
|
|
SharedEventPayload payload,
|
|
RawEvent::Category category = RawEvent::Category::Unspecified) const;
|
|
void dispatchUniqueEvent(std::string type, folly::dynamic&& payload) const;
|
|
void dispatchUniqueEvent(
|
|
std::string type,
|
|
const ValueFactory& payloadFactory =
|
|
EventEmitter::defaultPayloadFactory()) const;
|
|
void dispatchUniqueEvent(std::string type, SharedEventPayload payload) const;
|
|
};
|
|
mutable bool isEnabled_{false};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventListener.h}:
|
|
namespace facebook::react {
|
|
using EventListener = std::function<bool(const RawEvent& event)>;
|
|
class EventListenerContainer {
|
|
public:
|
|
bool willDispatchEvent(const RawEvent& event);
|
|
void addListener(std::shared_ptr<const EventListener> listener);
|
|
void removeListener(const std::shared_ptr<const EventListener>& listener);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventLogger.h}:
|
|
namespace facebook::react {
|
|
using EventTag = unsigned int;
|
|
const EventTag EMPTY_EVENT_TAG = 0;
|
|
class EventLogger {
|
|
public:
|
|
virtual ~EventLogger() = default;
|
|
virtual EventTag onEventStart(
|
|
std::string_view name,
|
|
SharedEventTarget target,
|
|
std::optional<HighResTimeStamp> eventStartTimeStamp = std::nullopt) = 0;
|
|
virtual void onEventProcessingStart(EventTag tag) = 0;
|
|
virtual void onEventProcessingEnd(EventTag tag) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventPayload.h}:
|
|
namespace facebook::react {
|
|
struct EventPayload {
|
|
virtual ~EventPayload() = default;
|
|
EventPayload() = default;
|
|
EventPayload(const EventPayload&) = default;
|
|
EventPayload& operator=(const EventPayload&) = default;
|
|
EventPayload(EventPayload&&) = default;
|
|
EventPayload& operator=(EventPayload&&) = default;
|
|
virtual jsi::Value asJSIValue(jsi::Runtime& runtime) const = 0;
|
|
virtual EventPayloadType getType() const = 0;
|
|
virtual std::optional<double> extractValue(
|
|
const std::vector<std::string>&) const {
|
|
return std::nullopt;
|
|
}
|
|
};
|
|
using SharedEventPayload = std::shared_ptr<const EventPayload>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventPayloadType.h}:
|
|
namespace facebook::react {
|
|
enum class EventPayloadType { ValueFactory, PointerEvent, ScrollEvent };
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventPipe.h}:
|
|
namespace facebook::react {
|
|
using EventPipe = std::function<void(
|
|
jsi::Runtime& runtime,
|
|
const EventTarget* eventTarget,
|
|
const std::string& type,
|
|
ReactEventPriority priority,
|
|
const EventPayload& payload)>;
|
|
using EventPipeConclusion = std::function<void(jsi::Runtime& runtime)>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventQueue.h}:
|
|
namespace facebook::react {
|
|
class EventQueue {
|
|
public:
|
|
enum class UpdateMode {
|
|
Asynchronous,
|
|
unstable_Immediate,
|
|
};
|
|
EventQueue(
|
|
EventQueueProcessor eventProcessor,
|
|
std::unique_ptr<EventBeat> eventBeat);
|
|
void enqueueEvent(RawEvent&& rawEvent) const;
|
|
void enqueueUniqueEvent(RawEvent&& rawEvent) const;
|
|
void enqueueStateUpdate(
|
|
StateUpdate&& stateUpdate,
|
|
UpdateMode updateMode = UpdateMode::Asynchronous) const;
|
|
void experimental_flushSync() const;
|
|
|
|
protected:
|
|
void onEnqueue() const;
|
|
void onBeat(jsi::Runtime& runtime) const;
|
|
void flushEvents(jsi::Runtime& runtime) const;
|
|
void flushStateUpdates() const;
|
|
EventQueueProcessor eventProcessor_;
|
|
const std::unique_ptr<EventBeat> eventBeat_;
|
|
mutable std::vector<RawEvent> eventQueue_;
|
|
mutable std::vector<StateUpdate> stateUpdateQueue_;
|
|
mutable std::mutex queueMutex_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventQueueProcessor.h}:
|
|
namespace facebook::react {
|
|
class EventQueueProcessor {
|
|
public:
|
|
EventQueueProcessor(
|
|
EventPipe eventPipe,
|
|
EventPipeConclusion eventPipeConclusion,
|
|
StatePipe statePipe,
|
|
std::weak_ptr<EventLogger> eventLogger);
|
|
void flushEvents(jsi::Runtime& runtime, std::vector<RawEvent>&& events) const;
|
|
void flushStateUpdates(std::vector<StateUpdate>&& states) const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/EventTarget.h}:
|
|
namespace facebook::react {
|
|
class EventTarget {
|
|
public:
|
|
using Tag = int32_t;
|
|
explicit EventTarget(
|
|
InstanceHandle::Shared instanceHandle,
|
|
SurfaceId surfaceId);
|
|
void setEnabled(bool enabled) const;
|
|
void retain(jsi::Runtime& runtime) const;
|
|
void release(jsi::Runtime& runtime) const;
|
|
jsi::Value getInstanceHandle(jsi::Runtime& runtime) const;
|
|
SurfaceId getSurfaceId() const;
|
|
Tag getTag() const;
|
|
};
|
|
mutable jsi::Value strongInstanceHandle_;
|
|
mutable size_t retainCount_{0};
|
|
};
|
|
using SharedEventTarget = std::shared_ptr<const EventTarget>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/InstanceHandle.h}:
|
|
namespace facebook::react {
|
|
class InstanceHandle {
|
|
public:
|
|
using Shared = std::shared_ptr<const InstanceHandle>;
|
|
InstanceHandle(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& instanceHandle,
|
|
Tag tag);
|
|
jsi::Value getInstanceHandle(jsi::Runtime& runtime) const;
|
|
Tag getTag() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/LayoutConstraints.h}:
|
|
namespace facebook::react {
|
|
struct LayoutConstraints {
|
|
Size minimumSize{0, 0};
|
|
Size maximumSize{
|
|
std::numeric_limits<Float>::infinity(),
|
|
std::numeric_limits<Float>::infinity()};
|
|
LayoutDirection layoutDirection{LayoutDirection::Undefined};
|
|
Size clamp(const Size& size) const;
|
|
};
|
|
inline bool operator==(
|
|
const LayoutConstraints& lhs,
|
|
const LayoutConstraints& rhs) {
|
|
return std::tie(lhs.minimumSize, lhs.maximumSize, lhs.layoutDirection) ==
|
|
std::tie(rhs.minimumSize, rhs.maximumSize, rhs.layoutDirection);
|
|
}
|
|
inline bool operator!=(
|
|
const LayoutConstraints& lhs,
|
|
const LayoutConstraints& rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::LayoutConstraints> {
|
|
size_t operator()(
|
|
const facebook::react::LayoutConstraints& constraints) const {
|
|
return facebook::react::hash_combine(
|
|
constraints.minimumSize,
|
|
constraints.maximumSize,
|
|
constraints.layoutDirection);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/LayoutContext.h}:
|
|
namespace facebook::react {
|
|
struct LayoutContext {
|
|
Float pointScaleFactor{1.0};
|
|
std::vector<const LayoutableShadowNode*>* affectedNodes{};
|
|
bool swapLeftAndRightInRTL{false};
|
|
Float fontSizeMultiplier{1.0};
|
|
Point viewportOffset{};
|
|
};
|
|
inline bool operator==(const LayoutContext& lhs, const LayoutContext& rhs) {
|
|
return std::tie(
|
|
lhs.pointScaleFactor,
|
|
lhs.affectedNodes,
|
|
lhs.swapLeftAndRightInRTL,
|
|
lhs.fontSizeMultiplier,
|
|
lhs.viewportOffset) ==
|
|
std::tie(
|
|
rhs.pointScaleFactor,
|
|
rhs.affectedNodes,
|
|
rhs.swapLeftAndRightInRTL,
|
|
rhs.fontSizeMultiplier,
|
|
rhs.viewportOffset);
|
|
}
|
|
inline bool operator!=(const LayoutContext& lhs, const LayoutContext& rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/LayoutMetrics.h}:
|
|
namespace facebook::react {
|
|
struct LayoutMetrics {
|
|
Rect frame;
|
|
EdgeInsets contentInsets{0};
|
|
EdgeInsets borderWidth{0};
|
|
DisplayType displayType{DisplayType::Flex};
|
|
PositionType positionType{PositionType::Relative};
|
|
LayoutDirection layoutDirection{LayoutDirection::Undefined};
|
|
bool wasLeftAndRightSwapped{false};
|
|
Float pointScaleFactor{1.0};
|
|
EdgeInsets overflowInset{};
|
|
Rect getContentFrame() const {
|
|
return Rect{
|
|
Point{contentInsets.left, contentInsets.top},
|
|
Size{
|
|
frame.size.width - contentInsets.left - contentInsets.right,
|
|
frame.size.height - contentInsets.top - contentInsets.bottom}};
|
|
}
|
|
Rect getOverflowInsetFrame() const {
|
|
return Rect{
|
|
Point{
|
|
frame.origin.x + std::min(Float{0}, overflowInset.left),
|
|
frame.origin.y + std::min(Float{0}, overflowInset.top)},
|
|
Size{
|
|
frame.size.width - std::min(Float{0}, overflowInset.left) +
|
|
-std::min(Float{0}, overflowInset.right),
|
|
frame.size.height - std::min(Float{0}, overflowInset.top) +
|
|
-std::min(Float{0}, overflowInset.bottom)}};
|
|
}
|
|
Rect getPaddingFrame() const {
|
|
return Rect{
|
|
Point{borderWidth.left, borderWidth.top},
|
|
Size{
|
|
frame.size.width - borderWidth.left - borderWidth.right,
|
|
frame.size.height - borderWidth.top - borderWidth.bottom}};
|
|
}
|
|
bool operator==(const LayoutMetrics& rhs) const = default;
|
|
bool operator!=(const LayoutMetrics& rhs) const = default;
|
|
};
|
|
static const LayoutMetrics EmptyLayoutMetrics = {{{0, 0}, {-1.0, -1.0}}};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::LayoutMetrics> {
|
|
size_t operator()(const facebook::react::LayoutMetrics& layoutMetrics) const {
|
|
return facebook::react::hash_combine(
|
|
layoutMetrics.frame,
|
|
layoutMetrics.contentInsets,
|
|
layoutMetrics.borderWidth,
|
|
layoutMetrics.displayType,
|
|
layoutMetrics.layoutDirection,
|
|
layoutMetrics.pointScaleFactor,
|
|
layoutMetrics.overflowInset);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/LayoutPrimitives.h}:
|
|
namespace facebook::react {
|
|
enum class DisplayType {
|
|
None = 0,
|
|
Flex = 1,
|
|
Contents = 2,
|
|
};
|
|
enum class PositionType {
|
|
Static = 0,
|
|
Relative = 1,
|
|
Absolute = 2,
|
|
};
|
|
enum class LayoutDirection {
|
|
Undefined = 0,
|
|
LeftToRight = 1,
|
|
RightToLeft = 2,
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/LayoutableShadowNode.h}:
|
|
namespace facebook::react {
|
|
class LayoutableShadowNode : public ShadowNode {
|
|
public:
|
|
LayoutableShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
const ShadowNodeFamily::Shared& family,
|
|
ShadowNodeTraits traits);
|
|
LayoutableShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment);
|
|
struct LayoutInspectingPolicy {
|
|
bool includeTransform{true};
|
|
bool includeViewportOffset{false};
|
|
bool enableOverflowClipping{false};
|
|
};
|
|
using UnsharedList = std::vector<LayoutableShadowNode*>;
|
|
static LayoutMetrics computeLayoutMetricsFromRoot(
|
|
const ShadowNodeFamily& descendantNodeFamily,
|
|
const LayoutableShadowNode& rootNode,
|
|
LayoutInspectingPolicy policy);
|
|
static LayoutMetrics computeRelativeLayoutMetrics(
|
|
const ShadowNodeFamily& descendantNodeFamily,
|
|
const LayoutableShadowNode& ancestorNode,
|
|
LayoutInspectingPolicy policy);
|
|
static LayoutMetrics computeRelativeLayoutMetrics(
|
|
const AncestorList& ancestors,
|
|
LayoutInspectingPolicy policy);
|
|
virtual void layoutTree(
|
|
LayoutContext layoutContext,
|
|
LayoutConstraints layoutConstraints) = 0;
|
|
virtual Size measureContent(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
virtual Size measure(
|
|
const LayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
virtual void layout(LayoutContext layoutContext) = 0;
|
|
LayoutMetrics getLayoutMetrics() const;
|
|
virtual Transform getTransform() const;
|
|
virtual Point getContentOriginOffset(bool includeTransform) const;
|
|
void setLayoutMetrics(LayoutMetrics layoutMetrics);
|
|
static std::shared_ptr<const ShadowNode> findNodeAtPoint(
|
|
const std::shared_ptr<const ShadowNode>& node,
|
|
Point point);
|
|
virtual void dirtyLayout() = 0;
|
|
virtual bool getIsLayoutClean() const = 0;
|
|
virtual Float baseline(const LayoutContext& layoutContext, Size size) const;
|
|
virtual bool canBeTouchTarget() const;
|
|
virtual bool canChildrenBeTouchTarget() const;
|
|
LayoutableShadowNode::UnsharedList getLayoutableChildNodes() const;
|
|
LayoutMetrics layoutMetrics_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/Props.h}:
|
|
namespace facebook::react {
|
|
class Props : public virtual Sealable, public virtual DebugStringConvertible {
|
|
public:
|
|
using Shared = std::shared_ptr<const Props>;
|
|
Props() = default;
|
|
Props(
|
|
const PropsParserContext& context,
|
|
const Props& sourceProps,
|
|
const RawProps& rawProps,
|
|
const std::function<bool(const std::string&)>& filterObjectKeys =
|
|
nullptr);
|
|
virtual ~Props() = default;
|
|
Props(const Props& other) = delete;
|
|
Props& operator=(const Props& other) = delete;
|
|
void setProp(
|
|
const PropsParserContext& context,
|
|
RawPropsPropNameHash hash,
|
|
const char* propName,
|
|
const RawValue& value);
|
|
std::string nativeId;
|
|
|
|
protected:
|
|
void initialize(
|
|
const PropsParserContext& context,
|
|
const Props& sourceProps,
|
|
const RawProps& rawProps,
|
|
const std::function<bool(const std::string&)>& filterObjectKeys =
|
|
nullptr);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/PropsMacros.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/PropsParserContext.h}:
|
|
namespace facebook::react {
|
|
struct PropsParserContext {
|
|
PropsParserContext(
|
|
const SurfaceId surfaceId,
|
|
const ContextContainer& contextContainer)
|
|
: surfaceId(surfaceId), contextContainer(contextContainer) {}
|
|
PropsParserContext(const PropsParserContext&) = delete;
|
|
PropsParserContext& operator=(const PropsParserContext&) = delete;
|
|
const SurfaceId surfaceId;
|
|
const ContextContainer& contextContainer;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawEvent.h}:
|
|
namespace facebook::react {
|
|
struct RawEvent {
|
|
enum class Category {
|
|
ContinuousStart = 0,
|
|
ContinuousEnd = 1,
|
|
Unspecified = 2,
|
|
Discrete = 3,
|
|
Continuous = 4,
|
|
Idle = 5,
|
|
};
|
|
RawEvent(
|
|
std::string type,
|
|
SharedEventPayload eventPayload,
|
|
SharedEventTarget eventTarget,
|
|
std::weak_ptr<const ShadowNodeFamily> shadowNodeFamily,
|
|
Category category = Category::Unspecified,
|
|
bool isUnique = false);
|
|
std::string type;
|
|
SharedEventPayload eventPayload;
|
|
SharedEventTarget eventTarget;
|
|
std::weak_ptr<const ShadowNodeFamily> shadowNodeFamily;
|
|
Category category;
|
|
EventTag loggingTag{0};
|
|
bool isUnique{false};
|
|
std::optional<HighResTimeStamp> eventStartTimeStamp = std::nullopt;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawProps.h}:
|
|
namespace facebook::react {
|
|
class RawProps final {
|
|
public:
|
|
enum class Mode { Empty, JSI, Dynamic };
|
|
RawProps() : mode_(Mode::Empty) {}
|
|
RawProps(jsi::Runtime& runtime, const jsi::Value& value) noexcept;
|
|
explicit RawProps(const RawProps& rawProps) noexcept;
|
|
RawProps(RawProps&& other) noexcept = default;
|
|
RawProps& operator=(const RawProps& other) noexcept = delete;
|
|
RawProps& operator=(RawProps&& other) noexcept = delete;
|
|
explicit RawProps(folly::dynamic dynamic) noexcept;
|
|
void parse(const RawPropsParser& parser) noexcept;
|
|
explicit operator folly::dynamic() const;
|
|
folly::dynamic toDynamic(
|
|
const std::function<bool(const std::string&)>& filterObjectKeys =
|
|
nullptr) const;
|
|
bool isEmpty() const noexcept;
|
|
const RawValue* at(const char* name, const char* prefix, const char* suffix)
|
|
const noexcept;
|
|
};
|
|
Mode mode_;
|
|
jsi::Runtime* runtime_{};
|
|
jsi::Value value_;
|
|
folly::dynamic dynamic_;
|
|
mutable int keyIndexCursor_{0};
|
|
mutable std::vector<RawPropsValueIndex> keyIndexToValueIndex_;
|
|
mutable std::vector<RawValue> values_;
|
|
};
|
|
template <typename T>
|
|
concept RawPropsFilterable = requires(RawProps& rawProps) {
|
|
{ T::filterRawProps(rawProps) } -> std::same_as<void>;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawPropsKey.h}:
|
|
namespace facebook::react {
|
|
class RawPropsKey final {
|
|
public:
|
|
const char* prefix{};
|
|
const char* name{};
|
|
const char* suffix{};
|
|
explicit operator std::string() const noexcept;
|
|
void render(char* buffer, RawPropsPropNameLength* length) const noexcept;
|
|
};
|
|
bool operator==(const RawPropsKey& lhs, const RawPropsKey& rhs) noexcept;
|
|
bool operator!=(const RawPropsKey& lhs, const RawPropsKey& rhs) noexcept;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawPropsKeyMap.h}:
|
|
namespace facebook::react {
|
|
class RawPropsKeyMap final {
|
|
public:
|
|
void insert(const RawPropsKey& key, RawPropsValueIndex value) noexcept;
|
|
void reindex() noexcept;
|
|
RawPropsValueIndex at(
|
|
const char* name,
|
|
RawPropsPropNameLength length) noexcept;
|
|
};
|
|
static bool shouldFirstOneBeBeforeSecondOne(
|
|
const Item& lhs,
|
|
const Item& rhs) noexcept;
|
|
static bool hasSameName(const Item& lhs, const Item& rhs) noexcept;
|
|
std::vector<Item> items_{};
|
|
std::vector<RawPropsPropNameLength> buckets_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawPropsParser.h}:
|
|
namespace facebook::react {
|
|
class RawPropsParser final {
|
|
public:
|
|
RawPropsParser(
|
|
bool useRawPropsJsiValue = ReactNativeFeatureFlags::useRawPropsJsiValue())
|
|
: useRawPropsJsiValue_(useRawPropsJsiValue) {};
|
|
template <typename PropsT>
|
|
void prepare() noexcept {
|
|
static_assert(
|
|
std::is_base_of<Props, PropsT>::value,
|
|
"PropsT must be a descendant of Props");
|
|
RawProps emptyRawProps{};
|
|
ContextContainer contextContainer{};
|
|
PropsParserContext parserContext{-1, contextContainer};
|
|
emptyRawProps.parse(*this);
|
|
PropsT(parserContext, {}, emptyRawProps);
|
|
postPrepare();
|
|
}
|
|
};
|
|
void preparse(const RawProps& rawProps) const noexcept;
|
|
void postPrepare() noexcept;
|
|
const RawValue* at(const RawProps& rawProps, const RawPropsKey& key)
|
|
const noexcept;
|
|
mutable std::vector<RawPropsKey> keys_{};
|
|
mutable RawPropsKeyMap nameToIndex_{};
|
|
mutable bool ready_{false};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawPropsPrimitives.h}:
|
|
namespace facebook::react {
|
|
using RawPropsValueIndex = uint16_t;
|
|
static_assert(
|
|
sizeof(RawPropsValueIndex) == 2,
|
|
"RawPropsValueIndex must be two byte size.");
|
|
using RawPropsPropNameLength = uint16_t;
|
|
using RawPropsPropNameHash = uint32_t;
|
|
constexpr static RawPropsValueIndex kRawPropsValueIndexEmpty =
|
|
std::numeric_limits<RawPropsValueIndex>::max();
|
|
constexpr static auto kPropNameLengthHardCap = 64;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/RawValue.h}:
|
|
namespace facebook::react {
|
|
class RawValue {
|
|
public:
|
|
RawValue() noexcept : value_(folly::dynamic(nullptr)) {}
|
|
RawValue(RawValue&& other) noexcept : value_(std::move(other.value_)) {}
|
|
RawValue& operator=(RawValue&& other) noexcept {
|
|
if (this != &other) {
|
|
value_ = std::move(other.value_);
|
|
}
|
|
return *this;
|
|
}
|
|
explicit RawValue(jsi::Runtime& runtime, const jsi::Value& value) noexcept
|
|
: value_(std::make_pair(&runtime, jsi::Value(runtime, value))) {}
|
|
explicit RawValue(jsi::Runtime& runtime, jsi::Value&& value) noexcept
|
|
: value_(std::make_pair(&runtime, std::move(value))) {}
|
|
explicit RawValue(const folly::dynamic& dynamic) noexcept : value_(dynamic) {}
|
|
explicit RawValue(folly::dynamic&& dynamic) noexcept
|
|
: value_(std::move(dynamic)) {}
|
|
public:
|
|
template <typename T>
|
|
explicit operator T() const {
|
|
if (std::holds_alternative<folly::dynamic>(value_)) {
|
|
auto& dynamic = std::get<folly::dynamic>(value_);
|
|
return castValue(dynamic, (T*)nullptr);
|
|
} else {
|
|
const auto& [runtime, value] = std::get<JsiValuePair>(value_);
|
|
return castValue(runtime, value, (T*)nullptr);
|
|
}
|
|
}
|
|
inline explicit operator folly::dynamic() const {
|
|
if (std::holds_alternative<folly::dynamic>(value_)) {
|
|
return std::get<folly::dynamic>(value_);
|
|
} else {
|
|
const auto& [runtime, value] = std::get<JsiValuePair>(value_);
|
|
return jsi::dynamicFromValue(*runtime, value);
|
|
}
|
|
}
|
|
template <typename T>
|
|
bool hasType() const {
|
|
if (std::holds_alternative<folly::dynamic>(value_)) {
|
|
auto& dynamic = std::get<folly::dynamic>(value_);
|
|
return checkValueType(dynamic, (T*)nullptr);
|
|
} else {
|
|
const auto& [runtime, value] = std::get<JsiValuePair>(value_);
|
|
return checkValueType(runtime, value, (T*)nullptr);
|
|
}
|
|
}
|
|
bool hasValue() const {
|
|
if (std::holds_alternative<folly::dynamic>(value_)) {
|
|
auto& dynamic = std::get<folly::dynamic>(value_);
|
|
return !dynamic.isNull();
|
|
} else {
|
|
const auto& [runtime, value] = std::get<JsiValuePair>(value_);
|
|
return !value.isNull() && !value.isUndefined();
|
|
}
|
|
}
|
|
};
|
|
}
|
|
template <typename T>
|
|
static std::vector<T> castValue(
|
|
const folly::dynamic& dynamic,
|
|
std::vector<T>*) {
|
|
react_native_assert(dynamic.isArray());
|
|
auto result = std::vector<T>{};
|
|
result.reserve(dynamic.size());
|
|
for (const auto& item : dynamic) {
|
|
result.push_back(castValue(item, (T*)nullptr));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
static std::vector<T>
|
|
castValue(jsi::Runtime* runtime, const jsi::Value& value, std::vector<T>*) {
|
|
react_native_assert(value.isObject());
|
|
jsi::Object object = value.getObject(*runtime);
|
|
react_native_assert(object.isArray(*runtime));
|
|
jsi::Array array = object.getArray(*runtime);
|
|
size_t size = array.size(*runtime);
|
|
std::vector<T> result;
|
|
result.reserve(size);
|
|
for (size_t i = 0; i < size; i++) {
|
|
jsi::Value itemValue = array.getValueAtIndex(*runtime, i);
|
|
T item = castValue(runtime, itemValue, (T*)nullptr);
|
|
result.push_back(std::move(item));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
static std::vector<std::vector<T>> castValue(
|
|
const folly::dynamic& dynamic,
|
|
std::vector<std::vector<T>>*) {
|
|
react_native_assert(dynamic.isArray());
|
|
auto result = std::vector<std::vector<T>>{};
|
|
result.reserve(dynamic.size());
|
|
for (const auto& item : dynamic) {
|
|
result.push_back(castValue(item, (std::vector<T>*)nullptr));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
static std::vector<std::vector<T>> castValue(
|
|
jsi::Runtime* runtime,
|
|
const jsi::Value& value,
|
|
std::vector<std::vector<T>>*) {
|
|
react_native_assert(value.isObject());
|
|
jsi::Object object = value.getObject(*runtime);
|
|
react_native_assert(object.isArray(*runtime));
|
|
jsi::Array array = std::move(object).getArray(*runtime);
|
|
size_t size = array.size(*runtime);
|
|
std::vector<std::vector<T>> result;
|
|
result.reserve(size);
|
|
for (size_t i = 0; i < size; i++) {
|
|
jsi::Value itemValue = array.getValueAtIndex(*runtime, i);
|
|
std::vector<T> item =
|
|
castValue(runtime, itemValue, (std::vector<T>*)nullptr);
|
|
result.push_back(std::move(item));
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
static std::unordered_map<std::string, T> castValue(
|
|
const folly::dynamic& dynamic,
|
|
std::unordered_map<std::string, T>*) {
|
|
react_native_assert(dynamic.isObject());
|
|
auto result = std::unordered_map<std::string, T>{};
|
|
for (const auto& item : dynamic.items()) {
|
|
react_native_assert(item.first.isString());
|
|
result[item.first.getString()] = castValue(item.second, (T*)nullptr);
|
|
}
|
|
return result;
|
|
}
|
|
template <typename T>
|
|
static std::unordered_map<std::string, T> castValue(
|
|
jsi::Runtime* runtime,
|
|
const jsi::Value& value,
|
|
std::unordered_map<std::string, T>*) {
|
|
react_native_assert(value.isObject());
|
|
jsi::Object object = value.getObject(*runtime);
|
|
jsi::Array propertyNames = object.getPropertyNames(*runtime);
|
|
size_t size = propertyNames.size(*runtime);
|
|
std::unordered_map<std::string, T> result;
|
|
for (size_t i = 0; i < size; i++) {
|
|
jsi::Value propertyNameValue = propertyNames.getValueAtIndex(*runtime, i);
|
|
jsi::String propertyName = propertyNameValue.getString(*runtime);
|
|
jsi::Value propertyValue = object.getProperty(*runtime, propertyName);
|
|
if (propertyValue.isUndefined()) {
|
|
continue;
|
|
}
|
|
std::string propertyNameString = propertyName.utf8(*runtime);
|
|
T property = castValue(runtime, propertyValue, (T*)nullptr);
|
|
result.emplace(propertyNameString, std::move(property));
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ReactEventPriority.h}:
|
|
namespace facebook::react {
|
|
enum class ReactEventPriority {
|
|
Default,
|
|
Discrete,
|
|
Continuous,
|
|
Idle,
|
|
};
|
|
static constexpr std::underlying_type<ReactEventPriority>::type serialize(
|
|
ReactEventPriority reactEventPriority) {
|
|
return static_cast<std::underlying_type<ReactEventPriority>::type>(
|
|
reactEventPriority);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ReactPrimitives.h}:
|
|
namespace facebook::react {
|
|
using Tag = int32_t;
|
|
using SurfaceId = int32_t;
|
|
using ComponentHandle = int64_t;
|
|
using ComponentName = const char*;
|
|
enum class DisplayMode {
|
|
Visible = 0,
|
|
Suspended = 1,
|
|
Hidden = 2,
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ReactRootViewTagGenerator.h}:
|
|
namespace facebook::react {
|
|
SurfaceId getNextRootViewTag() noexcept;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/Sealable.h}:
|
|
namespace facebook::react {
|
|
class Sealable {
|
|
public:
|
|
inline void seal() const {}
|
|
inline bool getSealed() const {
|
|
return true;
|
|
}
|
|
inline void ensureUnsealed() const {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ShadowNode.h}:
|
|
namespace facebook::react {
|
|
class ShadowNode : public Sealable,
|
|
public DebugStringConvertible,
|
|
public jsi::NativeState {
|
|
public:
|
|
using Shared [[deprecated("Use std::shared_ptr<const ShadowNode> instead")]] =
|
|
std::shared_ptr<const ShadowNode>;
|
|
using Weak [[deprecated("Use std::weak_ptr<const ShadowNode> instead")]] =
|
|
std::weak_ptr<const ShadowNode>;
|
|
using Unshared [[deprecated("Use std::shared_ptr<ShadowNode> instead")]] =
|
|
std::shared_ptr<ShadowNode>;
|
|
using ListOfShared [[deprecated(
|
|
"Use std::vector<std::shared_ptr<const ShadowNode>> instead")]] =
|
|
std::vector<std::shared_ptr<const ShadowNode>>;
|
|
using ListOfWeak [[deprecated(
|
|
"Use std::vector<std::weak_ptr<const ShadowNode>> instead")]] =
|
|
std::vector<std::weak_ptr<const ShadowNode>>;
|
|
using SharedListOfShared =
|
|
std::shared_ptr<const std::vector<std::shared_ptr<const ShadowNode>>>;
|
|
using UnsharedListOfShared =
|
|
std::shared_ptr<std::vector<std::shared_ptr<const ShadowNode>>>;
|
|
using UnsharedListOfWeak =
|
|
std::shared_ptr<std::vector<std::weak_ptr<const ShadowNode>>>;
|
|
using AncestorList =
|
|
std::vector<std::pair<std::reference_wrapper<const ShadowNode>, int>>;
|
|
static SharedListOfShared emptySharedShadowNodeSharedList();
|
|
static bool sameFamily(const ShadowNode& first, const ShadowNode& second);
|
|
static ShadowNodeTraits BaseTraits() {
|
|
return ShadowNodeTraits{};
|
|
}
|
|
static void setUseRuntimeShadowNodeReferenceUpdateOnThread(bool isEnabled);
|
|
ShadowNode(
|
|
const ShadowNodeFragment& fragment,
|
|
ShadowNodeFamily::Shared family,
|
|
ShadowNodeTraits traits);
|
|
ShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment);
|
|
ShadowNode(const ShadowNode& shadowNode) noexcept = delete;
|
|
ShadowNode& operator=(const ShadowNode& other) noexcept = delete;
|
|
virtual ~ShadowNode() override = default;
|
|
std::shared_ptr<ShadowNode> clone(const ShadowNodeFragment& fragment) const;
|
|
std::shared_ptr<ShadowNode> cloneTree(
|
|
const ShadowNodeFamily& shadowNodeFamily,
|
|
const std::function<std::shared_ptr<ShadowNode>(
|
|
const ShadowNode& oldShadowNode)>& callback) const;
|
|
std::shared_ptr<ShadowNode> cloneMultiple(
|
|
const std::unordered_set<const ShadowNodeFamily*>& familiesToUpdate,
|
|
const std::function<std::shared_ptr<ShadowNode>(
|
|
const ShadowNode& oldShadowNode,
|
|
const ShadowNodeFragment& fragment)>& callback) const;
|
|
virtual void completeClone(
|
|
const ShadowNode& sourceShadowNode,
|
|
const ShadowNodeFragment& fragment) {}
|
|
ComponentName getComponentName() const;
|
|
ComponentHandle getComponentHandle() const;
|
|
ShadowNodeTraits getTraits() const;
|
|
const Props::Shared& getProps() const;
|
|
const std::vector<std::shared_ptr<const ShadowNode>>& getChildren() const;
|
|
const SharedEventEmitter& getEventEmitter() const;
|
|
jsi::Value getInstanceHandle(jsi::Runtime& runtime) const;
|
|
Tag getTag() const;
|
|
SurfaceId getSurfaceId() const;
|
|
const ComponentDescriptor& getComponentDescriptor() const;
|
|
std::shared_ptr<const ContextContainer> getContextContainer() const;
|
|
const State::Shared& getState() const;
|
|
State::Shared getMostRecentState() const;
|
|
int getOrderIndex() const;
|
|
void sealRecursive() const;
|
|
const ShadowNodeFamily& getFamily() const;
|
|
ShadowNodeFamily::Shared getFamilyShared() const;
|
|
virtual void appendChild(const std::shared_ptr<const ShadowNode>& child);
|
|
virtual void replaceChild(
|
|
const ShadowNode& oldChild,
|
|
const std::shared_ptr<const ShadowNode>& newChild,
|
|
size_t suggestedIndex = std::numeric_limits<size_t>::max());
|
|
void setMounted(bool mounted) const;
|
|
bool getHasBeenPromoted() const;
|
|
void setRuntimeShadowNodeReference(const std::shared_ptr<ShadowNodeWrapper>&
|
|
runtimeShadowNodeReference) const;
|
|
void updateRuntimeShadowNodeReference(
|
|
const std::shared_ptr<const ShadowNode>& destinationShadowNode) const;
|
|
void transferRuntimeShadowNodeReference(
|
|
const std::shared_ptr<const ShadowNode>& destinationShadowNode,
|
|
const ShadowNodeFragment& fragment) const;
|
|
|
|
protected:
|
|
Props::Shared props_;
|
|
SharedListOfShared children_;
|
|
State::Shared state_;
|
|
int orderIndex_;
|
|
};
|
|
mutable bool hasBeenPromoted_{false};
|
|
static Props::Shared propsForClonedShadowNode(
|
|
const ShadowNode& sourceShadowNode,
|
|
const Props::Shared& props);
|
|
|
|
protected:
|
|
ShadowNodeTraits traits_;
|
|
mutable std::weak_ptr<ShadowNodeWrapper> runtimeShadowNodeReference_{};
|
|
};
|
|
static_assert(
|
|
std::has_virtual_destructor<ShadowNode>::value,
|
|
"ShadowNode must have a virtual destructor");
|
|
struct ShadowNodeWrapper : public jsi::NativeState {
|
|
explicit ShadowNodeWrapper(std::shared_ptr<const ShadowNode> shadowNode)
|
|
: shadowNode(std::move(shadowNode)) {}
|
|
~ShadowNodeWrapper() override;
|
|
std::shared_ptr<const ShadowNode> shadowNode;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFamily.h}:
|
|
namespace facebook::react {
|
|
struct ShadowNodeFamilyFragment {
|
|
const Tag tag;
|
|
const SurfaceId surfaceId;
|
|
const std::shared_ptr<const InstanceHandle> instanceHandle;
|
|
};
|
|
class ShadowNodeFamily final : public jsi::NativeState {
|
|
public:
|
|
using Shared = std::shared_ptr<const ShadowNodeFamily>;
|
|
using Weak = std::weak_ptr<const ShadowNodeFamily>;
|
|
using AncestorList =
|
|
std::vector<std::pair<std::reference_wrapper<const ShadowNode>, int>>;
|
|
ShadowNodeFamily(
|
|
const ShadowNodeFamilyFragment& fragment,
|
|
SharedEventEmitter eventEmitter,
|
|
EventDispatcher::Weak eventDispatcher,
|
|
const ComponentDescriptor& componentDescriptor);
|
|
void setParent(const ShadowNodeFamily::Shared& parent) const;
|
|
ComponentHandle getComponentHandle() const;
|
|
ComponentName getComponentName() const;
|
|
const ComponentDescriptor& getComponentDescriptor() const;
|
|
AncestorList getAncestors(const ShadowNode& ancestorShadowNode) const;
|
|
SurfaceId getSurfaceId() const;
|
|
SharedEventEmitter getEventEmitter() const;
|
|
void onUnmountedFamilyDestroyed(
|
|
std::function<void(const ShadowNodeFamily& family)> callback) const;
|
|
std::shared_ptr<const State> getMostRecentState() const;
|
|
void setMostRecentState(const std::shared_ptr<const State>& state) const;
|
|
void setMounted() const;
|
|
void dispatchRawState(
|
|
StateUpdate&& stateUpdate,
|
|
EventQueue::UpdateMode updateMode) const;
|
|
mutable std::unique_ptr<folly::dynamic> nativeProps_DEPRECATED;
|
|
Tag getTag() const;
|
|
jsi::Value getInstanceHandle(jsi::Runtime& runtime) const;
|
|
InstanceHandle::Shared getInstanceHandle() const;
|
|
void setInstanceHandle(InstanceHandle::Shared& instanceHandle) const;
|
|
~ShadowNodeFamily();
|
|
};
|
|
mutable bool hasParent_{false};
|
|
mutable bool hasBeenMounted_{false};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ShadowNodeFragment.h}:
|
|
namespace facebook::react {
|
|
struct ShadowNodeFragment {
|
|
const Props::Shared& props = propsPlaceholder();
|
|
const ShadowNode::SharedListOfShared& children = childrenPlaceholder();
|
|
const State::Shared& state = statePlaceholder();
|
|
const bool runtimeShadowNodeReference = true;
|
|
static const Props::Shared& propsPlaceholder();
|
|
static const ShadowNode::SharedListOfShared& childrenPlaceholder();
|
|
static const State::Shared& statePlaceholder();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ShadowNodeTraits.h}:
|
|
namespace facebook::react {
|
|
class ShadowNodeTraits {
|
|
public:
|
|
enum Trait : int32_t {
|
|
None = 0,
|
|
ViewKind = 1 << 0,
|
|
RootNodeKind = 1 << 1,
|
|
Hidden = 1 << 2,
|
|
LeafYogaNode = 1 << 3,
|
|
MeasurableYogaNode = 1 << 4,
|
|
FormsStackingContext = 1 << 5,
|
|
FormsView = 1 << 6,
|
|
ChildrenAreShared = 1 << 7,
|
|
ChildrenFormStackingContext = 1 << 8,
|
|
BaselineYogaNode = 1 << 9,
|
|
ForceFlattenView = 1 << 10,
|
|
KeyboardFocusable = 1 << 11,
|
|
Unstable_uncullableView = 1 << 12,
|
|
Unstable_uncullableTrace = 1 << 13,
|
|
DirtyYogaNode = 1 << 14,
|
|
};
|
|
inline void set(Trait trait) {
|
|
traits_ = ShadowNodeTraits::Trait(traits_ | trait);
|
|
}
|
|
inline void unset(Trait trait) {
|
|
traits_ = ShadowNodeTraits::Trait(traits_ & ~trait);
|
|
}
|
|
inline bool check(Trait traits) const {
|
|
return ShadowNodeTraits::Trait(traits_ & traits) == traits;
|
|
}
|
|
inline Trait get() const {
|
|
return traits_;
|
|
}
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/State.h}:
|
|
namespace facebook::react {
|
|
class State {
|
|
public:
|
|
using Shared = std::shared_ptr<const State>;
|
|
static size_t constexpr initialRevisionValue = 1;
|
|
|
|
protected:
|
|
explicit State(StateData::Shared data, const State& previousState);
|
|
explicit State(StateData::Shared data, ShadowNodeFamily::Weak family);
|
|
|
|
public:
|
|
virtual ~State() = default;
|
|
State::Shared getMostRecentState() const;
|
|
State::Shared getMostRecentStateIfObsolete() const;
|
|
size_t getRevision() const;
|
|
|
|
protected:
|
|
friend
|
|
friend
|
|
const StateData::Shared& getDataPointer() const {
|
|
return data_;
|
|
}
|
|
ShadowNodeFamily::Weak family_;
|
|
StateData::Shared data_;
|
|
mutable bool isObsolete_{false};
|
|
size_t revision_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/StateData.h}:
|
|
namespace facebook::react {
|
|
struct StateData final {
|
|
using Shared = std::shared_ptr<const void>;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/StatePipe.h}:
|
|
namespace facebook::react {
|
|
using StatePipe = std::function<void(const StateUpdate& stateUpdate)>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/StateUpdate.h}:
|
|
namespace facebook::react {
|
|
using SharedShadowNodeFamily = std::shared_ptr<const ShadowNodeFamily>;
|
|
class StateUpdate {
|
|
public:
|
|
using Callback =
|
|
std::function<StateData::Shared(const StateData::Shared& data)>;
|
|
using FailureCallback = std::function<void()>;
|
|
SharedShadowNodeFamily family;
|
|
Callback callback;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ValueFactory.h}:
|
|
namespace facebook::react {
|
|
using ValueFactory = std::function<jsi::Value(jsi::Runtime& runtime)>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/ValueFactoryEventPayload.h}:
|
|
namespace facebook::react {
|
|
class ValueFactoryEventPayload : public EventPayload {
|
|
public:
|
|
explicit ValueFactoryEventPayload(ValueFactory factory);
|
|
jsi::Value asJSIValue(jsi::Runtime& runtime) const override;
|
|
EventPayloadType getType() const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/conversions.h}:
|
|
namespace facebook::react {
|
|
inline std::string toString(const LayoutDirection& layoutDirection) {
|
|
switch (layoutDirection) {
|
|
case LayoutDirection::Undefined:
|
|
return "undefined";
|
|
case LayoutDirection::LeftToRight:
|
|
return "ltr";
|
|
case LayoutDirection::RightToLeft:
|
|
return "rtl";
|
|
}
|
|
}
|
|
inline int toInt(const LayoutDirection& layoutDirection) {
|
|
switch (layoutDirection) {
|
|
case LayoutDirection::Undefined:
|
|
return 0;
|
|
case LayoutDirection::LeftToRight:
|
|
return 1;
|
|
case LayoutDirection::RightToLeft:
|
|
return 2;
|
|
}
|
|
}
|
|
inline int toInt(const DisplayType& displayType) {
|
|
switch (displayType) {
|
|
case DisplayType::None:
|
|
return 0;
|
|
case DisplayType::Flex:
|
|
return 1;
|
|
case DisplayType::Contents:
|
|
return 2;
|
|
}
|
|
}
|
|
inline std::string toString(const DisplayType& displayType) {
|
|
switch (displayType) {
|
|
case DisplayType::None:
|
|
return "none";
|
|
case DisplayType::Flex:
|
|
return "flex";
|
|
case DisplayType::Contents:
|
|
return "contents";
|
|
}
|
|
}
|
|
inline Size yogaMeassureToSize(int64_t value) {
|
|
static_assert(
|
|
sizeof(value) == 8,
|
|
"Expected measureResult to be 8 bytes, or two 32 bit ints");
|
|
int32_t wBits = 0xFFFFFFFF & (value >> 32);
|
|
int32_t hBits = 0xFFFFFFFF & value;
|
|
float* measuredWidth = reinterpret_cast<float*>(&wBits);
|
|
float* measuredHeight = reinterpret_cast<float*>(&hBits);
|
|
return {*measuredWidth, *measuredHeight};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/graphicsConversions.h}:
|
|
namespace facebook::react {
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
SharedColor& result) {
|
|
fromRawValue(context.contextContainer, context.surfaceId, value, result);
|
|
}
|
|
inline std::string toString(const SharedColor& value) {
|
|
ColorComponents components = colorComponentsFromColor(value);
|
|
std::array<char, 255> buffer{};
|
|
std::snprintf(
|
|
buffer.data(),
|
|
buffer.size(),
|
|
"rgba(%.0f, %.0f, %.0f, %g)",
|
|
components.red * 255.f,
|
|
components.green * 255.f,
|
|
components.blue * 255.f,
|
|
components.alpha);
|
|
return buffer.data();
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Point& result) {
|
|
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
|
auto map = (std::unordered_map<std::string, Float>)value;
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "x") {
|
|
result.x = pair.second;
|
|
} else if (pair.first == "y") {
|
|
result.y = pair.second;
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
react_native_expect(value.hasType<std::vector<Float>>());
|
|
if (value.hasType<std::vector<Float>>()) {
|
|
auto array = (std::vector<Float>)value;
|
|
react_native_expect(array.size() == 2);
|
|
if (array.size() >= 2) {
|
|
result = {array.at(0), array.at(1)};
|
|
} else {
|
|
result = {0, 0};
|
|
LOG(ERROR) << "Unsupported Point vector size: " << array.size();
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Point type";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
Size& result) {
|
|
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
|
auto map = (std::unordered_map<std::string, Float>)value;
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "width") {
|
|
result.width = pair.second;
|
|
} else if (pair.first == "height") {
|
|
result.height = pair.second;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Size map key: " << pair.first;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
react_native_expect(value.hasType<std::vector<Float>>());
|
|
if (value.hasType<std::vector<Float>>()) {
|
|
auto array = (std::vector<Float>)value;
|
|
react_native_expect(array.size() == 2);
|
|
if (array.size() >= 2) {
|
|
result = {array.at(0), array.at(1)};
|
|
} else {
|
|
result = {0, 0};
|
|
LOG(ERROR) << "Unsupported Size vector size: " << array.size();
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported Size type";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
EdgeInsets& result) {
|
|
if (value.hasType<Float>()) {
|
|
auto number = (Float)value;
|
|
result = {number, number, number, number};
|
|
return;
|
|
}
|
|
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
|
auto map = (std::unordered_map<std::string, Float>)value;
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "top") {
|
|
result.top = pair.second;
|
|
} else if (pair.first == "left") {
|
|
result.left = pair.second;
|
|
} else if (pair.first == "bottom") {
|
|
result.bottom = pair.second;
|
|
} else if (pair.first == "right") {
|
|
result.right = pair.second;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported EdgeInsets map key: " << pair.first;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
react_native_expect(value.hasType<std::vector<Float>>());
|
|
if (value.hasType<std::vector<Float>>()) {
|
|
auto array = (std::vector<Float>)value;
|
|
react_native_expect(array.size() == 4);
|
|
if (array.size() >= 4) {
|
|
result = {array.at(0), array.at(1), array.at(2), array.at(3)};
|
|
} else {
|
|
result = {0, 0, 0, 0};
|
|
LOG(ERROR) << "Unsupported EdgeInsets vector size: " << array.size();
|
|
}
|
|
} else {
|
|
LOG(ERROR) << "Unsupported EdgeInsets type";
|
|
}
|
|
}
|
|
inline void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& value,
|
|
CornerInsets& result) {
|
|
if (value.hasType<Float>()) {
|
|
auto number = (Float)value;
|
|
result = {number, number, number, number};
|
|
return;
|
|
}
|
|
if (value.hasType<std::unordered_map<std::string, Float>>()) {
|
|
auto map = (std::unordered_map<std::string, Float>)value;
|
|
for (const auto& pair : map) {
|
|
if (pair.first == "topLeft") {
|
|
result.topLeft = pair.second;
|
|
} else if (pair.first == "topRight") {
|
|
result.topRight = pair.second;
|
|
} else if (pair.first == "bottomLeft") {
|
|
result.bottomLeft = pair.second;
|
|
} else if (pair.first == "bottomRight") {
|
|
result.bottomRight = pair.second;
|
|
} else {
|
|
LOG(ERROR) << "Unsupported CornerInsets map key: " << pair.first;
|
|
react_native_expect(false);
|
|
}
|
|
}
|
|
return;
|
|
}
|
|
react_native_expect(value.hasType<std::vector<Float>>());
|
|
if (value.hasType<std::vector<Float>>()) {
|
|
auto array = (std::vector<Float>)value;
|
|
react_native_expect(array.size() == 4);
|
|
if (array.size() >= 4) {
|
|
result = {array.at(0), array.at(1), array.at(2), array.at(3)};
|
|
} else {
|
|
LOG(ERROR) << "Unsupported CornerInsets vector size: " << array.size();
|
|
}
|
|
}
|
|
result = {0, 0, 0, 0};
|
|
LOG(ERROR) << "Unsupported CornerInsets type";
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/propsConversions.h}:
|
|
namespace facebook::react {
|
|
template <typename T>
|
|
void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& rawValue,
|
|
T& result,
|
|
T defaultValue) {
|
|
if (!rawValue.hasValue()) {
|
|
result = std::move(defaultValue);
|
|
return;
|
|
}
|
|
fromRawValue(context, rawValue, result);
|
|
}
|
|
template <typename T>
|
|
void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& rawValue,
|
|
T& result) {
|
|
result = (T)rawValue;
|
|
}
|
|
template <typename T>
|
|
void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& rawValue,
|
|
std::optional<T>& result) {
|
|
T resultValue;
|
|
fromRawValue(context, rawValue, resultValue);
|
|
result = std::optional<T>{std::move(resultValue)};
|
|
}
|
|
template <typename T>
|
|
void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& rawValue,
|
|
std::vector<T>& result) {
|
|
if (rawValue.hasType<std::vector<RawValue>>()) {
|
|
auto items = (std::vector<RawValue>)rawValue;
|
|
auto length = items.size();
|
|
result.clear();
|
|
result.reserve(length);
|
|
for (auto& item : items) {
|
|
T itemResult;
|
|
fromRawValue(context, item, itemResult);
|
|
result.push_back(itemResult);
|
|
}
|
|
return;
|
|
}
|
|
result.clear();
|
|
result.reserve(1);
|
|
T itemResult;
|
|
fromRawValue(context, rawValue, itemResult);
|
|
result.push_back(itemResult);
|
|
}
|
|
template <typename T>
|
|
void fromRawValue(
|
|
const PropsParserContext& context,
|
|
const RawValue& rawValue,
|
|
std::vector<std::vector<T>>& result) {
|
|
if (rawValue.hasType<std::vector<std::vector<RawValue>>>()) {
|
|
auto items = (std::vector<std::vector<RawValue>>)rawValue;
|
|
auto length = items.size();
|
|
result.clear();
|
|
result.reserve(length);
|
|
for (auto& item : items) {
|
|
T itemResult;
|
|
fromRawValue(context, item, itemResult);
|
|
result.push_back(itemResult);
|
|
}
|
|
return;
|
|
}
|
|
result.clear();
|
|
result.reserve(1);
|
|
T itemResult;
|
|
fromRawValue(context, rawValue, itemResult);
|
|
result.push_back(itemResult);
|
|
}
|
|
template <typename T, typename U = T>
|
|
T convertRawProp(
|
|
const PropsParserContext& context,
|
|
const RawProps& rawProps,
|
|
const char* name,
|
|
const T& sourceValue,
|
|
const U& defaultValue,
|
|
const char* namePrefix = nullptr,
|
|
const char* nameSuffix = nullptr) {
|
|
const auto* rawValue = rawProps.at(name, namePrefix, nameSuffix);
|
|
if (rawValue == nullptr) [[likely]] {
|
|
return sourceValue;
|
|
}
|
|
if (!rawValue->hasValue()) [[unlikely]] {
|
|
return defaultValue;
|
|
}
|
|
try {
|
|
T result;
|
|
fromRawValue(context, *rawValue, result);
|
|
return result;
|
|
} catch (const std::exception& e) {
|
|
RawPropsKey key{namePrefix, name, nameSuffix};
|
|
LOG(ERROR) << "Error while converting prop '"
|
|
<< static_cast<std::string>(key) << "': " << e.what();
|
|
return defaultValue;
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/core/tests/TestComponent.h}:
|
|
namespace facebook::react {
|
|
struct TestState {
|
|
TestState() = default;
|
|
};
|
|
static const char TestComponentName[] = "Test";
|
|
class TestProps : public ViewProps {
|
|
public:
|
|
TestProps() = default;
|
|
TestProps(
|
|
const PropsParserContext& context,
|
|
const TestProps& sourceProps,
|
|
const RawProps& rawProps)
|
|
: ViewProps(context, sourceProps, rawProps) {}
|
|
};
|
|
using SharedTestProps = std::shared_ptr<const TestProps>;
|
|
using SharedTestShadowNode = std::shared_ptr<const TestShadowNode>;
|
|
class TestShadowNode final : public ConcreteViewShadowNode<
|
|
TestComponentName,
|
|
TestProps,
|
|
ViewEventEmitter,
|
|
TestState> {
|
|
public:
|
|
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
|
Transform _transform{Transform::Identity()};
|
|
Transform getTransform() const override {
|
|
return _transform;
|
|
}
|
|
facebook::react::Point _contentOriginOffset{};
|
|
facebook::react::Point getContentOriginOffset(bool) const override {
|
|
return _contentOriginOffset;
|
|
}
|
|
};
|
|
class TestComponentDescriptor
|
|
: public ConcreteComponentDescriptor<TestShadowNode> {
|
|
public:
|
|
using ConcreteComponentDescriptor::ConcreteComponentDescriptor;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSAngle.h}:
|
|
namespace facebook::react {
|
|
struct CSSAngle {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSAngle& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSAngle> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<CSSAngle> {
|
|
if (token.type() == CSSTokenType::Dimension) {
|
|
if (auto unit = parseCSSAngleUnit(token.unit())) {
|
|
return CSSAngle{canonicalize(token.numericValue(), *unit)};
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSAngle>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSAngleUnit.h}:
|
|
namespace facebook::react {
|
|
enum class CSSAngleUnit : uint8_t {
|
|
Deg,
|
|
Grad,
|
|
Rad,
|
|
Turn,
|
|
};
|
|
constexpr std::optional<CSSAngleUnit> parseCSSAngleUnit(std::string_view unit) {
|
|
switch (fnv1aLowercase(unit)) {
|
|
case fnv1a("deg"):
|
|
return CSSAngleUnit::Deg;
|
|
case fnv1a("grad"):
|
|
return CSSAngleUnit::Grad;
|
|
case fnv1a("rad"):
|
|
return CSSAngleUnit::Rad;
|
|
case fnv1a("turn"):
|
|
return CSSAngleUnit::Turn;
|
|
default:
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
constexpr float canonicalize(float value, CSSAngleUnit unit) {
|
|
switch (unit) {
|
|
case CSSAngleUnit::Deg:
|
|
return value;
|
|
case CSSAngleUnit::Grad:
|
|
return value * 0.9f;
|
|
case CSSAngleUnit::Rad:
|
|
return value * 57.295779513f;
|
|
case CSSAngleUnit::Turn:
|
|
return value * 360.0f;
|
|
default:
|
|
return std::numeric_limits<float>::quiet_NaN();
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSColor.h}:
|
|
namespace facebook::react {
|
|
struct CSSColor {
|
|
uint8_t r{};
|
|
uint8_t g{};
|
|
uint8_t b{};
|
|
uint8_t a{};
|
|
constexpr bool operator==(const CSSColor& rhs) const = default;
|
|
static constexpr CSSColor black() {
|
|
return {0, 0, 0, 255};
|
|
}
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSColor> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<CSSColor> {
|
|
switch (token.type()) {
|
|
case CSSTokenType::Ident:
|
|
return parseCSSNamedColor<CSSColor>(token.stringValue());
|
|
case CSSTokenType::Hash:
|
|
return parseCSSHexColor<CSSColor>(token.stringValue());
|
|
default:
|
|
return {};
|
|
}
|
|
}
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSColor> {
|
|
return parseCSSColorFunction<CSSColor>(func.name, parser);
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSColor>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSColorFunction.h}:
|
|
namespace facebook::react {
|
|
namespace detail {
|
|
constexpr uint8_t clamp255Component(float f) {
|
|
auto i = static_cast<int32_t>(f);
|
|
auto ceiled = f > i ? i + 1 : i;
|
|
return static_cast<uint8_t>(std::clamp(ceiled, 0, 255));
|
|
}
|
|
constexpr std::optional<float> normalizeNumberComponent(
|
|
const std::variant<std::monostate, CSSNumber>& component) {
|
|
if (std::holds_alternative<CSSNumber>(component)) {
|
|
return std::get<CSSNumber>(component).value;
|
|
}
|
|
return {};
|
|
}
|
|
constexpr uint8_t clampAlpha(std::optional<float> alpha) {
|
|
return alpha.has_value() ? clamp255Component(*alpha * 255.0f)
|
|
: static_cast<uint8_t>(255u);
|
|
}
|
|
inline float normalizeHue(float hue) {
|
|
auto rem = std::remainder(hue, 360.0f);
|
|
return (rem < 0 ? rem + 360 : rem) / 360.0f;
|
|
}
|
|
inline std::optional<float> normalizeHueComponent(
|
|
const std::variant<std::monostate, CSSNumber, CSSAngle>& component) {
|
|
if (std::holds_alternative<CSSNumber>(component)) {
|
|
return normalizeHue(std::get<CSSNumber>(component).value);
|
|
} else if (std::holds_alternative<CSSAngle>(component)) {
|
|
return normalizeHue(std::get<CSSAngle>(component).degrees);
|
|
}
|
|
return {};
|
|
}
|
|
constexpr float hueToRgb(float p, float q, float t) {
|
|
if (t < 0.0f) {
|
|
t += 1.0f;
|
|
}
|
|
if (t > 1.0f) {
|
|
t -= 1.0f;
|
|
}
|
|
if (t < 1.0f / 6.0f) {
|
|
return p + (q - p) * 6 * t;
|
|
}
|
|
if (t < 1.0f / 2.0f) {
|
|
return q;
|
|
}
|
|
if (t < 2.0f / 3.0f) {
|
|
return p + (q - p) * (2.0f / 3.0f - t) * 6.0f;
|
|
}
|
|
return p;
|
|
}
|
|
inline std::tuple<uint8_t, uint8_t, uint8_t>
|
|
hslToRgb(float h, float s, float l) {
|
|
s = std::clamp(s / 100.0f, 0.0f, 1.0f);
|
|
l = std::clamp(l / 100.0f, 0.0f, 1.0f);
|
|
auto q = l < 0.5f ? l * (1.0f + s) : l + s - l * s;
|
|
auto p = 2.0f * l - q;
|
|
auto r = hueToRgb(p, q, h + 1.0f / 3.0f);
|
|
auto g = hueToRgb(p, q, h);
|
|
auto b = hueToRgb(p, q, h - 1.0f / 3.0f);
|
|
return {
|
|
static_cast<uint8_t>(std::round(r * 255.0f)),
|
|
static_cast<uint8_t>(std::round(g * 255.0f)),
|
|
static_cast<uint8_t>(std::round(b * 255.0f)),
|
|
};
|
|
}
|
|
inline std::tuple<uint8_t, uint8_t, uint8_t>
|
|
hwbToRgb(float h, float w, float b) {
|
|
w = std::clamp(w / 100.0f, 0.0f, 1.0f);
|
|
b = std::clamp(b / 100.0f, 0.0f, 1.0f);
|
|
if (w + b >= 1.0f) {
|
|
auto gray = w / (w + b);
|
|
return {
|
|
static_cast<uint8_t>(std::round(gray * 255.0f)),
|
|
static_cast<uint8_t>(std::round(gray * 255.0f)),
|
|
static_cast<uint8_t>(std::round(gray * 255.0f)),
|
|
};
|
|
}
|
|
auto red = hueToRgb(0.0f, 1.0f, h + 1.0f / 3.0f) * (1.0f - w - b) + w;
|
|
auto green = hueToRgb(0.0f, 1.0f, h) * (1.0f - w - b) + w;
|
|
auto blue = hueToRgb(0.0f, 1.0f, h - 1.0f / 3.0f) * (1.0f - w - b) + w;
|
|
return {
|
|
static_cast<uint8_t>(std::round(red * 255.0f)),
|
|
static_cast<uint8_t>(std::round(green * 255.0f)),
|
|
static_cast<uint8_t>(std::round(blue * 255.0f)),
|
|
};
|
|
}
|
|
template <typename... ComponentT>
|
|
requires(
|
|
(std::is_same_v<CSSNumber, ComponentT> ||
|
|
std::is_same_v<CSSPercentage, ComponentT>) &&
|
|
...)
|
|
constexpr std::optional<float> normalizeComponent(
|
|
const std::variant<std::monostate, ComponentT...>& component,
|
|
float baseValue) {
|
|
if constexpr (traits::containsType<CSSPercentage, ComponentT...>()) {
|
|
if (std::holds_alternative<CSSPercentage>(component)) {
|
|
return std::get<CSSPercentage>(component).value / 100.0f * baseValue;
|
|
}
|
|
}
|
|
if constexpr (traits::containsType<CSSNumber, ComponentT...>()) {
|
|
if (std::holds_alternative<CSSNumber>(component)) {
|
|
return std::get<CSSNumber>(component).value;
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
template <CSSDataType... FirstComponentAllowedTypesT>
|
|
constexpr bool isLegacyColorFunction(CSSSyntaxParser& parser) {
|
|
auto lookahead = parser;
|
|
auto next = parseNextCSSValue<FirstComponentAllowedTypesT...>(lookahead);
|
|
if (std::holds_alternative<std::monostate>(next)) {
|
|
return false;
|
|
}
|
|
return lookahead.consumeComponentValue<bool>(
|
|
CSSDelimiter::OptionalWhitespace, [](CSSPreservedToken token) {
|
|
return token.type() == CSSTokenType::Comma;
|
|
});
|
|
}
|
|
template <typename CSSColor>
|
|
constexpr std::optional<CSSColor> parseLegacyRgbFunction(
|
|
CSSSyntaxParser& parser) {
|
|
auto rawRed = parseNextCSSValue<CSSNumber, CSSPercentage>(parser);
|
|
bool usesNumber = std::holds_alternative<CSSNumber>(rawRed);
|
|
auto red = normalizeComponent(rawRed, 255.0f);
|
|
if (!red.has_value()) {
|
|
return {};
|
|
}
|
|
auto green = usesNumber
|
|
? normalizeNumberComponent(
|
|
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::Comma))
|
|
: normalizeComponent(
|
|
parseNextCSSValue<CSSPercentage>(parser, CSSDelimiter::Comma),
|
|
255.0f);
|
|
if (!green.has_value()) {
|
|
return {};
|
|
}
|
|
auto blue = usesNumber
|
|
? normalizeNumberComponent(
|
|
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::Comma))
|
|
: normalizeComponent(
|
|
parseNextCSSValue<CSSPercentage>(parser, CSSDelimiter::Comma),
|
|
255.0f);
|
|
if (!blue.has_value()) {
|
|
return {};
|
|
}
|
|
auto alpha = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(parser, CSSDelimiter::Comma),
|
|
1.0f);
|
|
return CSSColor{
|
|
.r = clamp255Component(*red),
|
|
.g = clamp255Component(*green),
|
|
.b = clamp255Component(*blue),
|
|
.a = clampAlpha(alpha),
|
|
};
|
|
}
|
|
template <typename CSSColor>
|
|
constexpr std::optional<CSSColor> parseModernRgbFunction(
|
|
CSSSyntaxParser& parser) {
|
|
auto red = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(parser), 255.0f);
|
|
if (!red.has_value()) {
|
|
return {};
|
|
}
|
|
auto green = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Whitespace),
|
|
255.0f);
|
|
if (!green.has_value()) {
|
|
return {};
|
|
}
|
|
auto blue = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Whitespace),
|
|
255.0f);
|
|
if (!blue.has_value()) {
|
|
return {};
|
|
}
|
|
auto alpha = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::SolidusOrWhitespace),
|
|
1.0f);
|
|
return CSSColor{
|
|
.r = clamp255Component(*red),
|
|
.g = clamp255Component(*green),
|
|
.b = clamp255Component(*blue),
|
|
.a = clampAlpha(alpha),
|
|
};
|
|
}
|
|
template <typename CSSColor>
|
|
constexpr std::optional<CSSColor> parseRgbFunction(CSSSyntaxParser& parser) {
|
|
if (isLegacyColorFunction<CSSNumber, CSSPercentage>(parser)) {
|
|
return parseLegacyRgbFunction<CSSColor>(parser);
|
|
} else {
|
|
return parseModernRgbFunction<CSSColor>(parser);
|
|
}
|
|
}
|
|
template <typename CSSColor>
|
|
inline std::optional<CSSColor> parseLegacyHslFunction(CSSSyntaxParser& parser) {
|
|
auto h =
|
|
normalizeHueComponent(parseNextCSSValue<CSSNumber, CSSAngle>(parser));
|
|
if (!h.has_value()) {
|
|
return {};
|
|
}
|
|
auto s = normalizeComponent(
|
|
parseNextCSSValue<CSSPercentage>(parser, CSSDelimiter::Comma), 100.0f);
|
|
if (!s.has_value()) {
|
|
return {};
|
|
}
|
|
auto l = normalizeComponent(
|
|
parseNextCSSValue<CSSPercentage>(parser, CSSDelimiter::Comma), 100.0f);
|
|
if (!l.has_value()) {
|
|
return {};
|
|
}
|
|
auto a = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(parser, CSSDelimiter::Comma),
|
|
1.0f);
|
|
auto [r, g, b] = hslToRgb(*h, *s, *l);
|
|
return CSSColor{
|
|
.r = r,
|
|
.g = g,
|
|
.b = b,
|
|
.a = clampAlpha(a),
|
|
};
|
|
}
|
|
template <typename CSSColor>
|
|
inline std::optional<CSSColor> parseModernHslFunction(CSSSyntaxParser& parser) {
|
|
auto h =
|
|
normalizeHueComponent(parseNextCSSValue<CSSNumber, CSSAngle>(parser));
|
|
if (!h.has_value()) {
|
|
return {};
|
|
}
|
|
auto s = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Whitespace),
|
|
100.0f);
|
|
if (!s.has_value()) {
|
|
return {};
|
|
}
|
|
auto l = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Whitespace),
|
|
100.0f);
|
|
if (!l.has_value()) {
|
|
return {};
|
|
}
|
|
auto a = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::SolidusOrWhitespace),
|
|
1.0f);
|
|
auto [r, g, b] = hslToRgb(*h, *s, *l);
|
|
return CSSColor{
|
|
.r = r,
|
|
.g = g,
|
|
.b = b,
|
|
.a = clampAlpha(a),
|
|
};
|
|
}
|
|
template <typename CSSColor>
|
|
inline std::optional<CSSColor> parseHslFunction(CSSSyntaxParser& parser) {
|
|
if (isLegacyColorFunction<CSSNumber, CSSAngle>(parser)) {
|
|
return parseLegacyHslFunction<CSSColor>(parser);
|
|
} else {
|
|
return parseModernHslFunction<CSSColor>(parser);
|
|
}
|
|
}
|
|
template <typename CSSColor>
|
|
inline std::optional<CSSColor> parseHwbFunction(CSSSyntaxParser& parser) {
|
|
auto h =
|
|
normalizeHueComponent(parseNextCSSValue<CSSNumber, CSSAngle>(parser));
|
|
if (!h.has_value()) {
|
|
return {};
|
|
}
|
|
auto w = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Whitespace),
|
|
100.0f);
|
|
if (!w.has_value()) {
|
|
return {};
|
|
}
|
|
auto b = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Whitespace),
|
|
100.0f);
|
|
if (!b.has_value()) {
|
|
return {};
|
|
}
|
|
auto a = normalizeComponent(
|
|
parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::SolidusOrWhitespace),
|
|
1.0f);
|
|
auto [red, green, blue] = hwbToRgb(*h, *w, *b);
|
|
return CSSColor{
|
|
.r = red,
|
|
.g = green,
|
|
.b = blue,
|
|
.a = clampAlpha(a),
|
|
};
|
|
}
|
|
} // namespace detail
|
|
template <typename CSSColor>
|
|
constexpr std::optional<CSSColor> parseCSSColorFunction(
|
|
std::string_view colorFunction,
|
|
CSSSyntaxParser& parser) {
|
|
switch (fnv1aLowercase(colorFunction)) {
|
|
case fnv1a("rgb"):
|
|
case fnv1a("rgba"):
|
|
return detail::parseRgbFunction<CSSColor>(parser);
|
|
break;
|
|
case fnv1a("hsl"):
|
|
case fnv1a("hsla"):
|
|
return detail::parseHslFunction<CSSColor>(parser);
|
|
break;
|
|
case fnv1a("hwb"):
|
|
return detail::parseHwbFunction<CSSColor>(parser);
|
|
break;
|
|
default:
|
|
return {};
|
|
}
|
|
return {};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSCompoundDataType.h}:
|
|
namespace facebook::react {
|
|
namespace detail {
|
|
struct CSSCompoundDataTypeMarker {};
|
|
} // namespace detail
|
|
template <CSSDataType... AllowedTypesT>
|
|
struct CSSCompoundDataType : public detail::CSSCompoundDataTypeMarker {};
|
|
template <typename T>
|
|
concept CSSValidCompoundDataType =
|
|
std::is_base_of_v<detail::CSSCompoundDataTypeMarker, T>;
|
|
template <typename T>
|
|
concept CSSMaybeCompoundDataType =
|
|
CSSDataType<T> || CSSValidCompoundDataType<T>;
|
|
namespace detail {
|
|
template <CSSMaybeCompoundDataType... AllowedTypesT>
|
|
template <
|
|
CSSDataType... AlllowedTypes1T,
|
|
CSSDataType... AlllowedTypes2T,
|
|
CSSMaybeCompoundDataType... RestT>
|
|
struct merge_data_types<
|
|
CSSCompoundDataType<AlllowedTypes1T...>,
|
|
CSSCompoundDataType<AlllowedTypes2T...>,
|
|
RestT...> {
|
|
using type = typename merge_data_types<
|
|
CSSCompoundDataType<AlllowedTypes1T..., AlllowedTypes2T...>,
|
|
RestT...>::type;
|
|
};
|
|
template <
|
|
CSSDataType AlllowedType1T,
|
|
CSSDataType... AlllowedTypes2T,
|
|
CSSMaybeCompoundDataType... RestT>
|
|
struct merge_data_types<
|
|
AlllowedType1T,
|
|
CSSCompoundDataType<AlllowedTypes2T...>,
|
|
RestT...> {
|
|
using type = typename merge_data_types<
|
|
CSSCompoundDataType<AlllowedType1T, AlllowedTypes2T...>,
|
|
RestT...>::type;
|
|
};
|
|
template <
|
|
CSSDataType AlllowedType2T,
|
|
CSSDataType... AlllowedTypes1T,
|
|
CSSMaybeCompoundDataType... RestT>
|
|
struct merge_data_types<
|
|
CSSCompoundDataType<AlllowedTypes1T...>,
|
|
AlllowedType2T,
|
|
RestT...> {
|
|
using type = typename merge_data_types<
|
|
CSSCompoundDataType<AlllowedTypes1T..., AlllowedType2T>,
|
|
RestT...>::type;
|
|
};
|
|
template <
|
|
CSSDataType AlllowedType1T,
|
|
CSSDataType AlllowedType2T,
|
|
CSSMaybeCompoundDataType... RestT>
|
|
struct merge_data_types<AlllowedType1T, AlllowedType2T, RestT...> {
|
|
using type = typename merge_data_types<
|
|
CSSCompoundDataType<AlllowedType1T, AlllowedType2T>,
|
|
RestT...>::type;
|
|
};
|
|
template <CSSDataType... AllowedTypesT>
|
|
struct merge_data_types<CSSCompoundDataType<AllowedTypesT...>> {
|
|
using type = CSSCompoundDataType<AllowedTypesT...>;
|
|
};
|
|
template <CSSDataType AllowedTypeT>
|
|
struct merge_data_types<AllowedTypeT> {
|
|
using type = CSSCompoundDataType<AllowedTypeT>;
|
|
};
|
|
template <typename... T>
|
|
template <CSSDataType... AllowedTypesT, typename... RestT>
|
|
struct merge_variant<CSSCompoundDataType<AllowedTypesT...>, RestT...> {
|
|
using type = std::variant<RestT..., AllowedTypesT...>;
|
|
};
|
|
} // namespace detail
|
|
template <CSSMaybeCompoundDataType... T>
|
|
using CSSMergedDataTypes = typename detail::merge_data_types<T...>::type;
|
|
template <typename MergedTypeT, typename... RestT>
|
|
using CSSVariantWithTypes =
|
|
typename detail::merge_variant<MergedTypeT, RestT...>::type;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSDataType.h}:
|
|
namespace facebook::react {
|
|
template <typename CSSDataTypeT>
|
|
struct CSSDataTypeParser {};
|
|
template <typename T, typename ReturnT = std::any>
|
|
concept CSSFunctionBlockSink =
|
|
requires(const CSSFunctionBlock& func, CSSSyntaxParser& parser) {
|
|
{ T::consumeFunctionBlock(func, parser) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT = std::any>
|
|
concept CSSSimpleBlockSink =
|
|
requires(const CSSSimpleBlock& block, CSSSyntaxParser& parser) {
|
|
{ T::consumeSimpleBlock(block, parser) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT = std::any>
|
|
concept CSSPreservedTokenSink = requires(const CSSPreservedToken& token) {
|
|
{ T::consumePreservedToken(token) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT = std::any>
|
|
concept CSSParserSink = requires(CSSSyntaxParser& parser) {
|
|
{ T::consume(parser) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT = std::any>
|
|
concept CSSValidDataTypeParser =
|
|
((CSSFunctionBlockSink<T, ReturnT> || CSSSimpleBlockSink<T, ReturnT> ||
|
|
CSSPreservedTokenSink<T, ReturnT>) &&
|
|
!CSSParserSink<T, ReturnT>) ||
|
|
CSSParserSink<T, ReturnT>;
|
|
template <typename T>
|
|
concept CSSDataType =
|
|
CSSValidDataTypeParser<CSSDataTypeParser<T>, std::optional<T>> &&
|
|
std::equality_comparable<T>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSFilter.h}:
|
|
namespace facebook::react {
|
|
namespace detail {
|
|
template <typename DataT, TemplateStringLiteral Name>
|
|
requires(std::is_same_v<decltype(DataT::amount), float>)
|
|
struct CSSFilterSimpleAmountParser {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<DataT> {
|
|
if (!iequals(func.name, Name)) {
|
|
return {};
|
|
}
|
|
auto amount = parseNextCSSValue<CSSNumber, CSSPercentage>(parser);
|
|
if (std::holds_alternative<CSSNumber>(amount)) {
|
|
if (std::get<CSSNumber>(amount).value < 0.0f) {
|
|
return {};
|
|
}
|
|
return DataT{std::get<CSSNumber>(amount).value};
|
|
} else if (std::holds_alternative<CSSPercentage>(amount)) {
|
|
if (std::get<CSSPercentage>(amount).value < 0.0f) {
|
|
return {};
|
|
}
|
|
return DataT{std::get<CSSPercentage>(amount).value / 100.0f};
|
|
} else {
|
|
return DataT{};
|
|
}
|
|
}
|
|
};
|
|
} // namespace detail
|
|
struct CSSBlurFilter {
|
|
CSSLength amount{};
|
|
constexpr bool operator==(const CSSBlurFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSBlurFilter> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSBlurFilter> {
|
|
if (!iequals(func.name, "blur")) {
|
|
return {};
|
|
}
|
|
auto len = parseNextCSSValue<CSSLength>(parser);
|
|
return CSSBlurFilter{
|
|
std::holds_alternative<CSSLength>(len) ? std::get<CSSLength>(len)
|
|
: CSSLength{}};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSBlurFilter>);
|
|
struct CSSBrightnessFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSBrightnessFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSBrightnessFilter>
|
|
: public detail::
|
|
CSSFilterSimpleAmountParser<CSSBrightnessFilter, "brightness"> {};
|
|
static_assert(CSSDataType<CSSBrightnessFilter>);
|
|
struct CSSContrastFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSContrastFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSContrastFilter>
|
|
: public detail::
|
|
CSSFilterSimpleAmountParser<CSSContrastFilter, "contrast"> {};
|
|
static_assert(CSSDataType<CSSContrastFilter>);
|
|
struct CSSDropShadowFilter {
|
|
CSSLength offsetX{};
|
|
CSSLength offsetY{};
|
|
CSSLength standardDeviation{};
|
|
CSSColor color{};
|
|
constexpr bool operator==(const CSSDropShadowFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSDropShadowFilter> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSDropShadowFilter> {
|
|
if (!iequals(func.name, "drop-shadow")) {
|
|
return {};
|
|
}
|
|
std::optional<CSSColor> color{};
|
|
std::optional<std::array<CSSLength, 3>> lengths{};
|
|
auto firstVal = parseNextCSSValue<CSSColor, CSSLength>(parser);
|
|
if (std::holds_alternative<std::monostate>(firstVal)) {
|
|
return {};
|
|
}
|
|
if (std::holds_alternative<CSSColor>(firstVal)) {
|
|
color = std::get<CSSColor>(firstVal);
|
|
} else {
|
|
lengths = parseLengths(std::get<CSSLength>(firstVal), parser);
|
|
if (!lengths.has_value()) {
|
|
return {};
|
|
}
|
|
}
|
|
auto secondVal = parseNextCSSValue<CSSColor, CSSLength>(
|
|
parser, CSSDelimiter::Whitespace);
|
|
if (std::holds_alternative<CSSColor>(secondVal)) {
|
|
if (color.has_value()) {
|
|
return {};
|
|
}
|
|
color = std::get<CSSColor>(secondVal);
|
|
} else if (std::holds_alternative<CSSLength>(secondVal)) {
|
|
if (lengths.has_value()) {
|
|
return {};
|
|
}
|
|
lengths = parseLengths(std::get<CSSLength>(secondVal), parser);
|
|
}
|
|
if (!lengths.has_value()) {
|
|
return {};
|
|
}
|
|
return CSSDropShadowFilter{
|
|
.offsetX = (*lengths)[0],
|
|
.offsetY = (*lengths)[1],
|
|
.standardDeviation = (*lengths)[2],
|
|
.color = color.value_or(CSSColor::black()),
|
|
};
|
|
}
|
|
};
|
|
}
|
|
auto standardDeviation =
|
|
parseNextCSSValue<CSSLength>(parser, CSSDelimiter::Whitespace);
|
|
if (std::holds_alternative<CSSLength>(standardDeviation) &&
|
|
std::get<CSSLength>(standardDeviation).value < 0.0f) {
|
|
return {};
|
|
}
|
|
return std::array<CSSLength, 3>{
|
|
offsetX,
|
|
std::get<CSSLength>(offsetY),
|
|
std::holds_alternative<CSSLength>(standardDeviation)
|
|
? std::get<CSSLength>(standardDeviation)
|
|
: CSSLength{}};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSDropShadowFilter>);
|
|
struct CSSGrayscaleFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSGrayscaleFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSGrayscaleFilter>
|
|
: public detail::
|
|
CSSFilterSimpleAmountParser<CSSGrayscaleFilter, "grayscale"> {};
|
|
static_assert(CSSDataType<CSSGrayscaleFilter>);
|
|
struct CSSHueRotateFilter {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSHueRotateFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSHueRotateFilter> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSHueRotateFilter> {
|
|
if (!iequals(func.name, "hue-rotate")) {
|
|
return {};
|
|
}
|
|
auto angle = parseNextCSSValue<CSSAngle, CSSZero>(parser);
|
|
return CSSHueRotateFilter{
|
|
std::holds_alternative<CSSAngle>(angle)
|
|
? std::get<CSSAngle>(angle).degrees
|
|
: 0.0f};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSHueRotateFilter>);
|
|
struct CSSInvertFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSInvertFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSInvertFilter>
|
|
: public detail::CSSFilterSimpleAmountParser<CSSInvertFilter, "invert"> {};
|
|
static_assert(CSSDataType<CSSInvertFilter>);
|
|
struct CSSOpacityFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSOpacityFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSOpacityFilter>
|
|
: public detail::CSSFilterSimpleAmountParser<CSSOpacityFilter, "opacity"> {
|
|
};
|
|
static_assert(CSSDataType<CSSOpacityFilter>);
|
|
struct CSSSaturateFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSSaturateFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSSaturateFilter>
|
|
: public detail::
|
|
CSSFilterSimpleAmountParser<CSSSaturateFilter, "saturate"> {};
|
|
static_assert(CSSDataType<CSSSaturateFilter>);
|
|
struct CSSSepiaFilter {
|
|
float amount{1.0f};
|
|
constexpr bool operator==(const CSSSepiaFilter& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSSepiaFilter>
|
|
: public detail::CSSFilterSimpleAmountParser<CSSSepiaFilter, "sepia"> {};
|
|
static_assert(CSSDataType<CSSSepiaFilter>);
|
|
using CSSFilterFunction = CSSCompoundDataType<
|
|
CSSBlurFilter,
|
|
CSSBrightnessFilter,
|
|
CSSContrastFilter,
|
|
CSSDropShadowFilter,
|
|
CSSGrayscaleFilter,
|
|
CSSHueRotateFilter,
|
|
CSSInvertFilter,
|
|
CSSOpacityFilter,
|
|
CSSSaturateFilter,
|
|
CSSSepiaFilter>;
|
|
using CSSFilterFunctionVariant = CSSVariantWithTypes<CSSFilterFunction>;
|
|
using CSSFilterList = CSSWhitespaceSeparatedList<CSSFilterFunction>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSFontVariant.h}:
|
|
namespace facebook::react {
|
|
enum class CSSFontVariant : std::underlying_type_t<CSSKeyword> {
|
|
SmallCaps = to_underlying(CSSKeyword::SmallCaps),
|
|
OldstyleNums = to_underlying(CSSKeyword::OldstyleNums),
|
|
LiningNums = to_underlying(CSSKeyword::LiningNums),
|
|
TabularNums = to_underlying(CSSKeyword::TabularNums),
|
|
CommonLigatures = to_underlying(CSSKeyword::CommonLigatures),
|
|
NoCommonLigatures = to_underlying(CSSKeyword::NoCommonLigatures),
|
|
DiscretionaryLigatures = to_underlying(CSSKeyword::DiscretionaryLigatures),
|
|
NoDiscretionaryLigatures =
|
|
to_underlying(CSSKeyword::NoDiscretionaryLigatures),
|
|
HistoricalLigatures = to_underlying(CSSKeyword::HistoricalLigatures),
|
|
NoHistoricalLigatures = to_underlying(CSSKeyword::NoHistoricalLigatures),
|
|
Contextual = to_underlying(CSSKeyword::Contextual),
|
|
NoContextual = to_underlying(CSSKeyword::NoContextual),
|
|
ProportionalNums = to_underlying(CSSKeyword::ProportionalNums),
|
|
StylisticOne = to_underlying(CSSKeyword::StylisticOne),
|
|
StylisticTwo = to_underlying(CSSKeyword::StylisticTwo),
|
|
StylisticThree = to_underlying(CSSKeyword::StylisticThree),
|
|
StylisticFour = to_underlying(CSSKeyword::StylisticFour),
|
|
StylisticFive = to_underlying(CSSKeyword::StylisticFive),
|
|
StylisticSix = to_underlying(CSSKeyword::StylisticSix),
|
|
StylisticSeven = to_underlying(CSSKeyword::StylisticSeven),
|
|
StylisticEight = to_underlying(CSSKeyword::StylisticEight),
|
|
StylisticNine = to_underlying(CSSKeyword::StylisticNine),
|
|
StylisticTen = to_underlying(CSSKeyword::StylisticTen),
|
|
StylisticEleven = to_underlying(CSSKeyword::StylisticEleven),
|
|
StylisticTwelve = to_underlying(CSSKeyword::StylisticTwelve),
|
|
StylisticThirteen = to_underlying(CSSKeyword::StylisticThirteen),
|
|
StylisticFourteen = to_underlying(CSSKeyword::StylisticFourteen),
|
|
StylisticFifteen = to_underlying(CSSKeyword::StylisticFifteen),
|
|
StylisticSixteen = to_underlying(CSSKeyword::StylisticSixteen),
|
|
StylisticSeventeen = to_underlying(CSSKeyword::StylisticSeventeen),
|
|
StylisticEighteen = to_underlying(CSSKeyword::StylisticEighteen),
|
|
StylisticNineteen = to_underlying(CSSKeyword::StylisticNineteen),
|
|
StylisticTwenty = to_underlying(CSSKeyword::StylisticTwenty),
|
|
};
|
|
static_assert(CSSDataType<CSSFontVariant>);
|
|
using CSSFontVariantList = CSSWhitespaceSeparatedList<CSSFontVariant>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSHexColor.h}:
|
|
namespace facebook::react {
|
|
namespace detail {
|
|
enum class HexColorType {
|
|
Long,
|
|
Short,
|
|
};
|
|
constexpr uint8_t hexToNumeric(std::string_view hex, HexColorType hexType) {
|
|
int result = 0;
|
|
for (char c : hex) {
|
|
int value = 0;
|
|
if (c >= '0' && c <= '9') {
|
|
value = c - '0';
|
|
} else {
|
|
value = toLower(c) - 'a' + 10;
|
|
}
|
|
result *= 16;
|
|
result += value;
|
|
}
|
|
if (hexType == HexColorType::Short) {
|
|
return static_cast<uint8_t>(result * 16 + result);
|
|
} else {
|
|
return static_cast<uint8_t>(result);
|
|
}
|
|
}
|
|
constexpr bool isHexDigit(char c) {
|
|
return (c >= '0' && c <= '9') || (toLower(c) >= 'a' && toLower(c) <= 'f');
|
|
}
|
|
constexpr bool isValidHexColor(std::string_view hex) {
|
|
if (hex.size() != 3 && hex.size() != 4 && hex.size() != 6 &&
|
|
hex.size() != 8) {
|
|
return false;
|
|
}
|
|
for (auto c : hex) {
|
|
if (!isHexDigit(c)) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
} // namespace detail
|
|
template <typename CSSColor>
|
|
constexpr std::optional<CSSColor> parseCSSHexColor(
|
|
std::string_view hexColorValue) {
|
|
if (detail::isValidHexColor(hexColorValue)) {
|
|
if (hexColorValue.length() == 3) {
|
|
return CSSColor{
|
|
hexToNumeric(hexColorValue.substr(0, 1), detail::HexColorType::Short),
|
|
hexToNumeric(hexColorValue.substr(1, 1), detail::HexColorType::Short),
|
|
hexToNumeric(hexColorValue.substr(2, 1), detail::HexColorType::Short),
|
|
255u};
|
|
} else if (hexColorValue.length() == 4) {
|
|
return CSSColor{
|
|
hexToNumeric(hexColorValue.substr(0, 1), detail::HexColorType::Short),
|
|
hexToNumeric(hexColorValue.substr(1, 1), detail::HexColorType::Short),
|
|
hexToNumeric(hexColorValue.substr(2, 1), detail::HexColorType::Short),
|
|
hexToNumeric(
|
|
hexColorValue.substr(3, 1), detail::HexColorType::Short)};
|
|
} else if (hexColorValue.length() == 6) {
|
|
return CSSColor{
|
|
hexToNumeric(hexColorValue.substr(0, 2), detail::HexColorType::Long),
|
|
hexToNumeric(hexColorValue.substr(2, 2), detail::HexColorType::Long),
|
|
hexToNumeric(hexColorValue.substr(4, 2), detail::HexColorType::Long),
|
|
255u};
|
|
} else if (hexColorValue.length() == 8) {
|
|
return CSSColor{
|
|
hexToNumeric(hexColorValue.substr(0, 2), detail::HexColorType::Long),
|
|
hexToNumeric(hexColorValue.substr(2, 2), detail::HexColorType::Long),
|
|
hexToNumeric(hexColorValue.substr(4, 2), detail::HexColorType::Long),
|
|
hexToNumeric(hexColorValue.substr(6, 2), detail::HexColorType::Long)};
|
|
}
|
|
}
|
|
return {};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSKeyword.h}:
|
|
namespace facebook::react {
|
|
enum class CSSKeyword : uint8_t {
|
|
Absolute,
|
|
Auto,
|
|
Baseline,
|
|
Block,
|
|
Bottom,
|
|
Center,
|
|
Clip,
|
|
Column,
|
|
ColumnReverse,
|
|
CommonLigatures,
|
|
Content,
|
|
Contents,
|
|
Contextual,
|
|
Dashed,
|
|
DiscretionaryLigatures,
|
|
Dotted,
|
|
Double,
|
|
End,
|
|
Fixed,
|
|
Flex,
|
|
FlexEnd,
|
|
FlexStart,
|
|
Grid,
|
|
Groove,
|
|
Hidden,
|
|
HistoricalLigatures,
|
|
Inherit,
|
|
Initial,
|
|
Inline,
|
|
InlineBlock,
|
|
InlineFlex,
|
|
InlineGrid,
|
|
Inset,
|
|
Left,
|
|
LiningNums,
|
|
Ltr,
|
|
MaxContent,
|
|
Medium,
|
|
MinContent,
|
|
NoCommonLigatures,
|
|
NoContextual,
|
|
NoDiscretionaryLigatures,
|
|
NoHistoricalLigatures,
|
|
None,
|
|
Normal,
|
|
NoWrap,
|
|
OldstyleNums,
|
|
Outset,
|
|
ProportionalNums,
|
|
Relative,
|
|
Ridge,
|
|
Right,
|
|
Row,
|
|
RowReverse,
|
|
Rtl,
|
|
Scroll,
|
|
SmallCaps,
|
|
Solid,
|
|
SpaceAround,
|
|
SpaceBetween,
|
|
SpaceEvenly,
|
|
Start,
|
|
Static,
|
|
Sticky,
|
|
Stretch,
|
|
StylisticEight,
|
|
StylisticEighteen,
|
|
StylisticEleven,
|
|
StylisticFifteen,
|
|
StylisticFive,
|
|
StylisticFour,
|
|
StylisticFourteen,
|
|
StylisticNine,
|
|
StylisticNineteen,
|
|
StylisticOne,
|
|
StylisticSeven,
|
|
StylisticSeventeen,
|
|
StylisticSix,
|
|
StylisticSixteen,
|
|
StylisticTen,
|
|
StylisticThirteen,
|
|
StylisticThree,
|
|
StylisticTwelve,
|
|
StylisticTwenty,
|
|
StylisticTwo,
|
|
TabularNums,
|
|
Thick,
|
|
Thin,
|
|
Top,
|
|
Unset,
|
|
Visible,
|
|
Wrap,
|
|
WrapReverse,
|
|
};
|
|
template <typename T>
|
|
concept CSSKeywordSet = std::is_enum_v<T> &&
|
|
std::is_same_v<std::underlying_type_t<T>,
|
|
std::underlying_type_t<CSSKeyword>>;
|
|
enum class CSSWideKeyword : std::underlying_type_t<CSSKeyword> {
|
|
Inherit = to_underlying(CSSKeyword::Inherit),
|
|
Initial = to_underlying(CSSKeyword::Initial),
|
|
Unset = to_underlying(CSSKeyword::Unset),
|
|
};
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasAbsolute = (CSSKeywordSet<T> && requires() { T::Absolute; });
|
|
constexpr std::string_view Absolute{"absolute"};
|
|
static_assert(hasAbsolute<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasAuto = (CSSKeywordSet<T> && requires() { T::Auto; });
|
|
constexpr std::string_view Auto{"auto"};
|
|
static_assert(hasAuto<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasBaseline = (CSSKeywordSet<T> && requires() { T::Baseline; });
|
|
constexpr std::string_view Baseline{"baseline"};
|
|
static_assert(hasBaseline<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasBlock = (CSSKeywordSet<T> && requires() { T::Block; });
|
|
constexpr std::string_view Block{"block"};
|
|
static_assert(hasBlock<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasBottom = (CSSKeywordSet<T> && requires() { T::Bottom; });
|
|
constexpr std::string_view Bottom{"bottom"};
|
|
static_assert(hasBottom<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasCenter = (CSSKeywordSet<T> && requires() { T::Center; });
|
|
constexpr std::string_view Center{"center"};
|
|
static_assert(hasCenter<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasClip = (CSSKeywordSet<T> && requires() { T::Clip; });
|
|
constexpr std::string_view Clip{"clip"};
|
|
static_assert(hasClip<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasColumn = (CSSKeywordSet<T> && requires() { T::Column; });
|
|
constexpr std::string_view Column{"column"};
|
|
static_assert(hasColumn<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasColumnReverse =
|
|
(CSSKeywordSet<T> && requires() { T::ColumnReverse; });
|
|
constexpr std::string_view ColumnReverse{"column-reverse"};
|
|
static_assert(hasColumnReverse<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasCommonLigatures =
|
|
(CSSKeywordSet<T> && requires() { T::CommonLigatures; });
|
|
constexpr std::string_view CommonLigatures{"common-ligatures"};
|
|
static_assert(hasCommonLigatures<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasContent = (CSSKeywordSet<T> && requires() { T::Content; });
|
|
constexpr std::string_view Content{"content"};
|
|
static_assert(hasContent<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasContents = (CSSKeywordSet<T> && requires() { T::Contents; });
|
|
constexpr std::string_view Contents{"contents"};
|
|
static_assert(hasContents<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasContextual = (CSSKeywordSet<T> && requires() { T::Contextual; });
|
|
constexpr std::string_view Contextual{"contextual"};
|
|
static_assert(hasContextual<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasDashed = (CSSKeywordSet<T> && requires() { T::Dashed; });
|
|
constexpr std::string_view Dashed{"dashed"};
|
|
static_assert(hasDashed<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasDiscretionaryLigatures =
|
|
(CSSKeywordSet<T> && requires() { T::DiscretionaryLigatures; });
|
|
constexpr std::string_view DiscretionaryLigatures{"discretionary-ligatures"};
|
|
static_assert(hasDiscretionaryLigatures<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasDotted = (CSSKeywordSet<T> && requires() { T::Dotted; });
|
|
constexpr std::string_view Dotted{"dotted"};
|
|
static_assert(hasDotted<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasDouble = (CSSKeywordSet<T> && requires() { T::Double; });
|
|
constexpr std::string_view Double{"double"};
|
|
static_assert(hasDouble<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasEnd = (CSSKeywordSet<T> && requires() { T::End; });
|
|
constexpr std::string_view End{"end"};
|
|
static_assert(hasEnd<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasFixed = (CSSKeywordSet<T> && requires() { T::Fixed; });
|
|
constexpr std::string_view Fixed{"fixed"};
|
|
static_assert(hasFixed<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasFlex = (CSSKeywordSet<T> && requires() { T::Flex; });
|
|
constexpr std::string_view Flex{"flex"};
|
|
static_assert(hasFlex<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasFlexEnd = (CSSKeywordSet<T> && requires() { T::FlexEnd; });
|
|
constexpr std::string_view FlexEnd{"flex-end"};
|
|
static_assert(hasFlexEnd<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasFlexStart = (CSSKeywordSet<T> && requires() { T::FlexStart; });
|
|
constexpr std::string_view FlexStart{"flex-start"};
|
|
static_assert(hasFlexStart<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasGrid = (CSSKeywordSet<T> && requires() { T::Grid; });
|
|
constexpr std::string_view Grid{"grid"};
|
|
static_assert(hasGrid<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasGroove = (CSSKeywordSet<T> && requires() { T::Groove; });
|
|
constexpr std::string_view Groove{"groove"};
|
|
static_assert(hasGroove<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasHidden = (CSSKeywordSet<T> && requires() { T::Hidden; });
|
|
constexpr std::string_view Hidden{"hidden"};
|
|
static_assert(hasHidden<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasHistoricalLigatures =
|
|
(CSSKeywordSet<T> && requires() { T::HistoricalLigatures; });
|
|
constexpr std::string_view HistoricalLigatures{"historical-ligatures"};
|
|
static_assert(hasHistoricalLigatures<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInherit = (CSSKeywordSet<T> && requires() { T::Inherit; });
|
|
constexpr std::string_view Inherit{"inherit"};
|
|
static_assert(hasInherit<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInitial = (CSSKeywordSet<T> && requires() { T::Initial; });
|
|
constexpr std::string_view Initial{"initial"};
|
|
static_assert(hasInitial<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInline = (CSSKeywordSet<T> && requires() { T::Inline; });
|
|
constexpr std::string_view Inline{"inline"};
|
|
static_assert(hasInline<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInlineBlock = (CSSKeywordSet<T> && requires() { T::InlineBlock; });
|
|
constexpr std::string_view InlineBlock{"inline-block"};
|
|
static_assert(hasInlineBlock<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInlineFlex = (CSSKeywordSet<T> && requires() { T::InlineFlex; });
|
|
constexpr std::string_view InlineFlex{"inline-flex"};
|
|
static_assert(hasInlineFlex<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInlineGrid = (CSSKeywordSet<T> && requires() { T::InlineGrid; });
|
|
constexpr std::string_view InlineGrid{"inline-grid"};
|
|
static_assert(hasInlineGrid<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasInset = (CSSKeywordSet<T> && requires() { T::Inset; });
|
|
constexpr std::string_view Inset{"inset"};
|
|
static_assert(hasInset<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasLeft = (CSSKeywordSet<T> && requires() { T::Left; });
|
|
constexpr std::string_view Left{"left"};
|
|
static_assert(hasLeft<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasLiningNums = (CSSKeywordSet<T> && requires() { T::LiningNums; });
|
|
constexpr std::string_view LiningNums{"lining-nums"};
|
|
static_assert(hasLiningNums<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasLtr = (CSSKeywordSet<T> && requires() { T::Ltr; });
|
|
constexpr std::string_view Ltr{"ltr"};
|
|
static_assert(hasLtr<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasMaxContent = (CSSKeywordSet<T> && requires() { T::MaxContent; });
|
|
constexpr std::string_view MaxContent{"max-content"};
|
|
static_assert(hasMaxContent<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasMedium = (CSSKeywordSet<T> && requires() { T::Medium; });
|
|
constexpr std::string_view Medium{"medium"};
|
|
static_assert(hasMedium<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasMinContent = (CSSKeywordSet<T> && requires() { T::MinContent; });
|
|
constexpr std::string_view MinContent{"min-content"};
|
|
static_assert(hasMinContent<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNoCommonLigatures =
|
|
(CSSKeywordSet<T> && requires() { T::NoCommonLigatures; });
|
|
constexpr std::string_view NoCommonLigatures{"no-common-ligatures"};
|
|
static_assert(hasNoCommonLigatures<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNoContextual = (CSSKeywordSet<T> && requires() { T::NoContextual; });
|
|
constexpr std::string_view NoContextual{"no-contextual"};
|
|
static_assert(hasNoContextual<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNoDiscretionaryLigatures =
|
|
(CSSKeywordSet<T> && requires() { T::NoDiscretionaryLigatures; });
|
|
constexpr std::string_view NoDiscretionaryLigatures{
|
|
"no-discretionary-ligatures"};
|
|
static_assert(hasNoDiscretionaryLigatures<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNoHistoricalLigatures =
|
|
(CSSKeywordSet<T> && requires() { T::NoHistoricalLigatures; });
|
|
constexpr std::string_view NoHistoricalLigatures{"no-historical-ligatures"};
|
|
static_assert(hasNoHistoricalLigatures<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNone = (CSSKeywordSet<T> && requires() { T::None; });
|
|
constexpr std::string_view None{"none"};
|
|
static_assert(hasNone<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNormal = (CSSKeywordSet<T> && requires() { T::Normal; });
|
|
constexpr std::string_view Normal{"normal"};
|
|
static_assert(hasNormal<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasNoWrap = (CSSKeywordSet<T> && requires() { T::NoWrap; });
|
|
constexpr std::string_view NoWrap{"nowrap"};
|
|
static_assert(hasNoWrap<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasOldstyleNums = (CSSKeywordSet<T> && requires() { T::OldstyleNums; });
|
|
constexpr std::string_view OldstyleNums{"oldstyle-nums"};
|
|
static_assert(hasOldstyleNums<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasOutset = (CSSKeywordSet<T> && requires() { T::Outset; });
|
|
constexpr std::string_view Outset{"outset"};
|
|
static_assert(hasOutset<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasProportionalNums =
|
|
(CSSKeywordSet<T> && requires() { T::ProportionalNums; });
|
|
constexpr std::string_view ProportionalNums{"proportional-nums"};
|
|
static_assert(hasProportionalNums<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasRelative = (CSSKeywordSet<T> && requires() { T::Relative; });
|
|
constexpr std::string_view Relative{"relative"};
|
|
static_assert(hasRelative<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasRidge = (CSSKeywordSet<T> && requires() { T::Ridge; });
|
|
constexpr std::string_view Ridge{"ridge"};
|
|
static_assert(hasRidge<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasRight = (CSSKeywordSet<T> && requires() { T::Right; });
|
|
constexpr std::string_view Right{"right"};
|
|
static_assert(hasRight<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasRow = (CSSKeywordSet<T> && requires() { T::Row; });
|
|
constexpr std::string_view Row{"row"};
|
|
static_assert(hasRow<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasRowReverse = (CSSKeywordSet<T> && requires() { T::RowReverse; });
|
|
constexpr std::string_view RowReverse{"row-reverse"};
|
|
static_assert(hasRowReverse<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasRtl = (CSSKeywordSet<T> && requires() { T::Rtl; });
|
|
constexpr std::string_view Rtl{"rtl"};
|
|
static_assert(hasRtl<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasScroll = (CSSKeywordSet<T> && requires() { T::Scroll; });
|
|
constexpr std::string_view Scroll{"scroll"};
|
|
static_assert(hasScroll<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasSmallCaps = (CSSKeywordSet<T> && requires() { T::SmallCaps; });
|
|
constexpr std::string_view SmallCaps{"small-caps"};
|
|
static_assert(hasSmallCaps<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasSolid = (CSSKeywordSet<T> && requires() { T::Solid; });
|
|
constexpr std::string_view Solid{"solid"};
|
|
static_assert(hasSolid<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasSpaceAround = (CSSKeywordSet<T> && requires() { T::SpaceAround; });
|
|
constexpr std::string_view SpaceAround{"space-around"};
|
|
static_assert(hasSpaceAround<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasSpaceBetween = (CSSKeywordSet<T> && requires() { T::SpaceBetween; });
|
|
constexpr std::string_view SpaceBetween{"space-between"};
|
|
static_assert(hasSpaceBetween<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasSpaceEvenly = (CSSKeywordSet<T> && requires() { T::SpaceEvenly; });
|
|
constexpr std::string_view SpaceEvenly{"space-evenly"};
|
|
static_assert(hasSpaceEvenly<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStart = (CSSKeywordSet<T> && requires() { T::Start; });
|
|
constexpr std::string_view Start{"start"};
|
|
static_assert(hasStart<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStatic = (CSSKeywordSet<T> && requires() { T::Static; });
|
|
constexpr std::string_view Static{"static"};
|
|
static_assert(hasStatic<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasSticky = (CSSKeywordSet<T> && requires() { T::Sticky; });
|
|
constexpr std::string_view Sticky{"sticky"};
|
|
static_assert(hasSticky<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStretch = (CSSKeywordSet<T> && requires() { T::Stretch; });
|
|
constexpr std::string_view Stretch{"stretch"};
|
|
static_assert(hasStretch<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticEight =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticEight; });
|
|
constexpr std::string_view StylisticEight{"stylistic-eight"};
|
|
static_assert(hasStylisticEight<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticEighteen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticEighteen; });
|
|
constexpr std::string_view StylisticEighteen{"stylistic-eighteen"};
|
|
static_assert(hasStylisticEighteen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticEleven =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticEleven; });
|
|
constexpr std::string_view StylisticEleven{"stylistic-eleven"};
|
|
static_assert(hasStylisticEleven<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticFifteen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticFifteen; });
|
|
constexpr std::string_view StylisticFifteen{"stylistic-fifteen"};
|
|
static_assert(hasStylisticFifteen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticFive =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticFive; });
|
|
constexpr std::string_view StylisticFive{"stylistic-five"};
|
|
static_assert(hasStylisticFive<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticFour =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticFour; });
|
|
constexpr std::string_view StylisticFour{"stylistic-four"};
|
|
static_assert(hasStylisticFour<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticFourteen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticFourteen; });
|
|
constexpr std::string_view StylisticFourteen{"stylistic-fourteen"};
|
|
static_assert(hasStylisticFourteen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticNine =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticNine; });
|
|
constexpr std::string_view StylisticNine{"stylistic-nine"};
|
|
static_assert(hasStylisticNine<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticNineteen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticNineteen; });
|
|
constexpr std::string_view StylisticNineteen{"stylistic-nineteen"};
|
|
static_assert(hasStylisticNineteen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticOne = (CSSKeywordSet<T> && requires() { T::StylisticOne; });
|
|
constexpr std::string_view StylisticOne{"stylistic-one"};
|
|
static_assert(hasStylisticOne<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticSeven =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticSeven; });
|
|
constexpr std::string_view StylisticSeven{"stylistic-seven"};
|
|
static_assert(hasStylisticSeven<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticSeventeen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticSeventeen; });
|
|
constexpr std::string_view StylisticSeventeen{"stylistic-seventeen"};
|
|
static_assert(hasStylisticSeventeen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticSix = (CSSKeywordSet<T> && requires() { T::StylisticSix; });
|
|
constexpr std::string_view StylisticSix{"stylistic-six"};
|
|
static_assert(hasStylisticSix<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticSixteen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticSixteen; });
|
|
constexpr std::string_view StylisticSixteen{"stylistic-sixteen"};
|
|
static_assert(hasStylisticSixteen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticTen = (CSSKeywordSet<T> && requires() { T::StylisticTen; });
|
|
constexpr std::string_view StylisticTen{"stylistic-ten"};
|
|
static_assert(hasStylisticTen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticThirteen =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticThirteen; });
|
|
constexpr std::string_view StylisticThirteen{"stylistic-thirteen"};
|
|
static_assert(hasStylisticThirteen<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticThree =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticThree; });
|
|
constexpr std::string_view StylisticThree{"stylistic-three"};
|
|
static_assert(hasStylisticThree<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticTwelve =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticTwelve; });
|
|
constexpr std::string_view StylisticTwelve{"stylistic-twelve"};
|
|
static_assert(hasStylisticTwelve<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticTwenty =
|
|
(CSSKeywordSet<T> && requires() { T::StylisticTwenty; });
|
|
constexpr std::string_view StylisticTwenty{"stylistic-twenty"};
|
|
static_assert(hasStylisticTwenty<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasStylisticTwo = (CSSKeywordSet<T> && requires() { T::StylisticTwo; });
|
|
constexpr std::string_view StylisticTwo{"stylistic-two"};
|
|
static_assert(hasStylisticTwo<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasTabularNums = (CSSKeywordSet<T> && requires() { T::TabularNums; });
|
|
constexpr std::string_view TabularNums{"tabular-nums"};
|
|
static_assert(hasTabularNums<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasThick = (CSSKeywordSet<T> && requires() { T::Thick; });
|
|
constexpr std::string_view Thick{"thick"};
|
|
static_assert(hasThick<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasThin = (CSSKeywordSet<T> && requires() { T::Thin; });
|
|
constexpr std::string_view Thin{"thin"};
|
|
static_assert(hasThin<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasTop = (CSSKeywordSet<T> && requires() { T::Top; });
|
|
constexpr std::string_view Top{"top"};
|
|
static_assert(hasTop<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasUnset = (CSSKeywordSet<T> && requires() { T::Unset; });
|
|
constexpr std::string_view Unset{"unset"};
|
|
static_assert(hasUnset<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasVisible = (CSSKeywordSet<T> && requires() { T::Visible; });
|
|
constexpr std::string_view Visible{"visible"};
|
|
static_assert(hasVisible<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasWrap = (CSSKeywordSet<T> && requires() { T::Wrap; });
|
|
constexpr std::string_view Wrap{"wrap"};
|
|
static_assert(hasWrap<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
namespace detail::css::keywords {
|
|
template <typename T>
|
|
concept hasWrapReverse = (CSSKeywordSet<T> && requires() { T::WrapReverse; });
|
|
constexpr std::string_view WrapReverse{"wrap-reverse"};
|
|
static_assert(hasWrapReverse<CSSKeyword>);
|
|
} // namespace detail::css::keywords
|
|
template <CSSKeywordSet KeywordT>
|
|
constexpr std::optional<KeywordT> parseCSSKeyword(std::string_view ident) {
|
|
switch (fnv1aLowercase(ident)) {
|
|
case fnv1a(detail::css::keywords::Absolute):
|
|
if constexpr (detail::css::keywords::hasAbsolute<KeywordT>) {
|
|
return KeywordT::Absolute;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Auto):
|
|
if constexpr (detail::css::keywords::hasAuto<KeywordT>) {
|
|
return KeywordT::Auto;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Baseline):
|
|
if constexpr (detail::css::keywords::hasBaseline<KeywordT>) {
|
|
return KeywordT::Baseline;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Block):
|
|
if constexpr (detail::css::keywords::hasBlock<KeywordT>) {
|
|
return KeywordT::Block;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Bottom):
|
|
if constexpr (detail::css::keywords::hasBottom<KeywordT>) {
|
|
return KeywordT::Bottom;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Center):
|
|
if constexpr (detail::css::keywords::hasCenter<KeywordT>) {
|
|
return KeywordT::Center;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Clip):
|
|
if constexpr (detail::css::keywords::hasClip<KeywordT>) {
|
|
return KeywordT::Clip;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Column):
|
|
if constexpr (detail::css::keywords::hasColumn<KeywordT>) {
|
|
return KeywordT::Column;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::ColumnReverse):
|
|
if constexpr (detail::css::keywords::hasColumnReverse<KeywordT>) {
|
|
return KeywordT::ColumnReverse;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::CommonLigatures):
|
|
if constexpr (detail::css::keywords::hasCommonLigatures<KeywordT>) {
|
|
return KeywordT::CommonLigatures;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Content):
|
|
if constexpr (detail::css::keywords::hasContent<KeywordT>) {
|
|
return KeywordT::Content;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Contents):
|
|
if constexpr (detail::css::keywords::hasContents<KeywordT>) {
|
|
return KeywordT::Contents;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Contextual):
|
|
if constexpr (detail::css::keywords::hasContextual<KeywordT>) {
|
|
return KeywordT::Contextual;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Dashed):
|
|
if constexpr (detail::css::keywords::hasDashed<KeywordT>) {
|
|
return KeywordT::Dashed;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::DiscretionaryLigatures):
|
|
if constexpr (detail::css::keywords::hasDiscretionaryLigatures<
|
|
KeywordT>) {
|
|
return KeywordT::DiscretionaryLigatures;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Dotted):
|
|
if constexpr (detail::css::keywords::hasDotted<KeywordT>) {
|
|
return KeywordT::Dotted;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Double):
|
|
if constexpr (detail::css::keywords::hasDouble<KeywordT>) {
|
|
return KeywordT::Double;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::End):
|
|
if constexpr (detail::css::keywords::hasEnd<KeywordT>) {
|
|
return KeywordT::End;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Fixed):
|
|
if constexpr (detail::css::keywords::hasFixed<KeywordT>) {
|
|
return KeywordT::Fixed;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Flex):
|
|
if constexpr (detail::css::keywords::hasFlex<KeywordT>) {
|
|
return KeywordT::Flex;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::FlexEnd):
|
|
if constexpr (detail::css::keywords::hasFlexEnd<KeywordT>) {
|
|
return KeywordT::FlexEnd;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::FlexStart):
|
|
if constexpr (detail::css::keywords::hasFlexStart<KeywordT>) {
|
|
return KeywordT::FlexStart;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Grid):
|
|
if constexpr (detail::css::keywords::hasGrid<KeywordT>) {
|
|
return KeywordT::Grid;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Groove):
|
|
if constexpr (detail::css::keywords::hasGroove<KeywordT>) {
|
|
return KeywordT::Groove;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Hidden):
|
|
if constexpr (detail::css::keywords::hasHidden<KeywordT>) {
|
|
return KeywordT::Hidden;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::HistoricalLigatures):
|
|
if constexpr (detail::css::keywords::hasHistoricalLigatures<KeywordT>) {
|
|
return KeywordT::HistoricalLigatures;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Inherit):
|
|
if constexpr (detail::css::keywords::hasInherit<KeywordT>) {
|
|
return KeywordT::Inherit;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Initial):
|
|
if constexpr (detail::css::keywords::hasInitial<KeywordT>) {
|
|
return KeywordT::Initial;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Inline):
|
|
if constexpr (detail::css::keywords::hasInline<KeywordT>) {
|
|
return KeywordT::Inline;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::InlineBlock):
|
|
if constexpr (detail::css::keywords::hasInlineBlock<KeywordT>) {
|
|
return KeywordT::InlineBlock;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::InlineFlex):
|
|
if constexpr (detail::css::keywords::hasInlineFlex<KeywordT>) {
|
|
return KeywordT::InlineFlex;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::InlineGrid):
|
|
if constexpr (detail::css::keywords::hasInlineGrid<KeywordT>) {
|
|
return KeywordT::InlineGrid;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Inset):
|
|
if constexpr (detail::css::keywords::hasInset<KeywordT>) {
|
|
return KeywordT::Inset;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Left):
|
|
if constexpr (detail::css::keywords::hasLeft<KeywordT>) {
|
|
return KeywordT::Left;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::LiningNums):
|
|
if constexpr (detail::css::keywords::hasLiningNums<KeywordT>) {
|
|
return KeywordT::LiningNums;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Ltr):
|
|
if constexpr (detail::css::keywords::hasLtr<KeywordT>) {
|
|
return KeywordT::Ltr;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::MaxContent):
|
|
if constexpr (detail::css::keywords::hasMaxContent<KeywordT>) {
|
|
return KeywordT::MaxContent;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Medium):
|
|
if constexpr (detail::css::keywords::hasMedium<KeywordT>) {
|
|
return KeywordT::Medium;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::MinContent):
|
|
if constexpr (detail::css::keywords::hasMinContent<KeywordT>) {
|
|
return KeywordT::MinContent;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::NoCommonLigatures):
|
|
if constexpr (detail::css::keywords::hasNoCommonLigatures<KeywordT>) {
|
|
return KeywordT::NoCommonLigatures;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::NoContextual):
|
|
if constexpr (detail::css::keywords::hasNoContextual<KeywordT>) {
|
|
return KeywordT::NoContextual;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::NoDiscretionaryLigatures):
|
|
if constexpr (detail::css::keywords::hasNoDiscretionaryLigatures<
|
|
KeywordT>) {
|
|
return KeywordT::NoDiscretionaryLigatures;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::NoHistoricalLigatures):
|
|
if constexpr (detail::css::keywords::hasNoHistoricalLigatures<KeywordT>) {
|
|
return KeywordT::NoHistoricalLigatures;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::None):
|
|
if constexpr (detail::css::keywords::hasNone<KeywordT>) {
|
|
return KeywordT::None;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Normal):
|
|
if constexpr (detail::css::keywords::hasNormal<KeywordT>) {
|
|
return KeywordT::Normal;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::NoWrap):
|
|
if constexpr (detail::css::keywords::hasNoWrap<KeywordT>) {
|
|
return KeywordT::NoWrap;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::OldstyleNums):
|
|
if constexpr (detail::css::keywords::hasOldstyleNums<KeywordT>) {
|
|
return KeywordT::OldstyleNums;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Outset):
|
|
if constexpr (detail::css::keywords::hasOutset<KeywordT>) {
|
|
return KeywordT::Outset;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::ProportionalNums):
|
|
if constexpr (detail::css::keywords::hasProportionalNums<KeywordT>) {
|
|
return KeywordT::ProportionalNums;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Relative):
|
|
if constexpr (detail::css::keywords::hasRelative<KeywordT>) {
|
|
return KeywordT::Relative;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Ridge):
|
|
if constexpr (detail::css::keywords::hasRidge<KeywordT>) {
|
|
return KeywordT::Ridge;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Right):
|
|
if constexpr (detail::css::keywords::hasRight<KeywordT>) {
|
|
return KeywordT::Right;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Row):
|
|
if constexpr (detail::css::keywords::hasRow<KeywordT>) {
|
|
return KeywordT::Row;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::RowReverse):
|
|
if constexpr (detail::css::keywords::hasRowReverse<KeywordT>) {
|
|
return KeywordT::RowReverse;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Rtl):
|
|
if constexpr (detail::css::keywords::hasRtl<KeywordT>) {
|
|
return KeywordT::Rtl;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Scroll):
|
|
if constexpr (detail::css::keywords::hasScroll<KeywordT>) {
|
|
return KeywordT::Scroll;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::SmallCaps):
|
|
if constexpr (detail::css::keywords::hasSmallCaps<KeywordT>) {
|
|
return KeywordT::SmallCaps;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Solid):
|
|
if constexpr (detail::css::keywords::hasSolid<KeywordT>) {
|
|
return KeywordT::Solid;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::SpaceAround):
|
|
if constexpr (detail::css::keywords::hasSpaceAround<KeywordT>) {
|
|
return KeywordT::SpaceAround;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::SpaceBetween):
|
|
if constexpr (detail::css::keywords::hasSpaceBetween<KeywordT>) {
|
|
return KeywordT::SpaceBetween;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::SpaceEvenly):
|
|
if constexpr (detail::css::keywords::hasSpaceEvenly<KeywordT>) {
|
|
return KeywordT::SpaceEvenly;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Start):
|
|
if constexpr (detail::css::keywords::hasStart<KeywordT>) {
|
|
return KeywordT::Start;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Static):
|
|
if constexpr (detail::css::keywords::hasStatic<KeywordT>) {
|
|
return KeywordT::Static;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Sticky):
|
|
if constexpr (detail::css::keywords::hasSticky<KeywordT>) {
|
|
return KeywordT::Sticky;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Stretch):
|
|
if constexpr (detail::css::keywords::hasStretch<KeywordT>) {
|
|
return KeywordT::Stretch;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticEight):
|
|
if constexpr (detail::css::keywords::hasStylisticEight<KeywordT>) {
|
|
return KeywordT::StylisticEight;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticEighteen):
|
|
if constexpr (detail::css::keywords::hasStylisticEighteen<KeywordT>) {
|
|
return KeywordT::StylisticEighteen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticEleven):
|
|
if constexpr (detail::css::keywords::hasStylisticEleven<KeywordT>) {
|
|
return KeywordT::StylisticEleven;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticFifteen):
|
|
if constexpr (detail::css::keywords::hasStylisticFifteen<KeywordT>) {
|
|
return KeywordT::StylisticFifteen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticFive):
|
|
if constexpr (detail::css::keywords::hasStylisticFive<KeywordT>) {
|
|
return KeywordT::StylisticFive;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticFour):
|
|
if constexpr (detail::css::keywords::hasStylisticFour<KeywordT>) {
|
|
return KeywordT::StylisticFour;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticFourteen):
|
|
if constexpr (detail::css::keywords::hasStylisticFourteen<KeywordT>) {
|
|
return KeywordT::StylisticFourteen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticNine):
|
|
if constexpr (detail::css::keywords::hasStylisticNine<KeywordT>) {
|
|
return KeywordT::StylisticNine;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticNineteen):
|
|
if constexpr (detail::css::keywords::hasStylisticNineteen<KeywordT>) {
|
|
return KeywordT::StylisticNineteen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticOne):
|
|
if constexpr (detail::css::keywords::hasStylisticOne<KeywordT>) {
|
|
return KeywordT::StylisticOne;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticSeven):
|
|
if constexpr (detail::css::keywords::hasStylisticSeven<KeywordT>) {
|
|
return KeywordT::StylisticSeven;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticSeventeen):
|
|
if constexpr (detail::css::keywords::hasStylisticSeventeen<KeywordT>) {
|
|
return KeywordT::StylisticSeventeen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticSix):
|
|
if constexpr (detail::css::keywords::hasStylisticSix<KeywordT>) {
|
|
return KeywordT::StylisticSix;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticSixteen):
|
|
if constexpr (detail::css::keywords::hasStylisticSixteen<KeywordT>) {
|
|
return KeywordT::StylisticSixteen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticTen):
|
|
if constexpr (detail::css::keywords::hasStylisticTen<KeywordT>) {
|
|
return KeywordT::StylisticTen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticThirteen):
|
|
if constexpr (detail::css::keywords::hasStylisticThirteen<KeywordT>) {
|
|
return KeywordT::StylisticThirteen;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticThree):
|
|
if constexpr (detail::css::keywords::hasStylisticThree<KeywordT>) {
|
|
return KeywordT::StylisticThree;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticTwelve):
|
|
if constexpr (detail::css::keywords::hasStylisticTwelve<KeywordT>) {
|
|
return KeywordT::StylisticTwelve;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticTwenty):
|
|
if constexpr (detail::css::keywords::hasStylisticTwenty<KeywordT>) {
|
|
return KeywordT::StylisticTwenty;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::StylisticTwo):
|
|
if constexpr (detail::css::keywords::hasStylisticTwo<KeywordT>) {
|
|
return KeywordT::StylisticTwo;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::TabularNums):
|
|
if constexpr (detail::css::keywords::hasTabularNums<KeywordT>) {
|
|
return KeywordT::TabularNums;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Thick):
|
|
if constexpr (detail::css::keywords::hasThick<KeywordT>) {
|
|
return KeywordT::Thick;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Thin):
|
|
if constexpr (detail::css::keywords::hasThin<KeywordT>) {
|
|
return KeywordT::Thin;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Top):
|
|
if constexpr (detail::css::keywords::hasTop<KeywordT>) {
|
|
return KeywordT::Top;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Unset):
|
|
if constexpr (detail::css::keywords::hasUnset<KeywordT>) {
|
|
return KeywordT::Unset;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Visible):
|
|
if constexpr (detail::css::keywords::hasVisible<KeywordT>) {
|
|
return KeywordT::Visible;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::Wrap):
|
|
if constexpr (detail::css::keywords::hasWrap<KeywordT>) {
|
|
return KeywordT::Wrap;
|
|
}
|
|
break;
|
|
case fnv1a(detail::css::keywords::WrapReverse):
|
|
if constexpr (detail::css::keywords::hasWrapReverse<KeywordT>) {
|
|
return KeywordT::WrapReverse;
|
|
}
|
|
break;
|
|
}
|
|
return std::nullopt;
|
|
}
|
|
template <CSSKeywordSet KeywordT>
|
|
struct CSSDataTypeParser<KeywordT> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<KeywordT> {
|
|
if (token.type() == CSSTokenType::Ident) {
|
|
return parseCSSKeyword<KeywordT>(token.stringValue());
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSWideKeyword>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSLength.h}:
|
|
namespace facebook::react {
|
|
struct CSSLength {
|
|
float value{};
|
|
CSSLengthUnit unit{CSSLengthUnit::Px};
|
|
constexpr bool operator==(const CSSLength& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSLength> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<CSSLength> {
|
|
switch (token.type()) {
|
|
case CSSTokenType::Dimension:
|
|
if (auto unit = parseCSSLengthUnit(token.unit())) {
|
|
return CSSLength{token.numericValue(), *unit};
|
|
}
|
|
break;
|
|
case CSSTokenType::Number:
|
|
if (token.numericValue() == 0) {
|
|
return CSSLength{token.numericValue(), CSSLengthUnit::Px};
|
|
}
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSLength>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSLengthPercentage.h}:
|
|
namespace facebook::react {
|
|
using CSSLengthPercentage = CSSCompoundDataType<CSSLength, CSSPercentage>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSLengthUnit.h}:
|
|
namespace facebook::react {
|
|
enum class CSSLengthUnit : uint8_t {
|
|
Cap,
|
|
Ch,
|
|
Cm,
|
|
Dvb,
|
|
Dvh,
|
|
Dvi,
|
|
Dvmax,
|
|
Dvmin,
|
|
Dvw,
|
|
Em,
|
|
Ex,
|
|
Ic,
|
|
In,
|
|
Lh,
|
|
Lvb,
|
|
Lvh,
|
|
Lvi,
|
|
Lvmax,
|
|
Lvmin,
|
|
Lvw,
|
|
Mm,
|
|
Pc,
|
|
Pt,
|
|
Px,
|
|
Q,
|
|
Rcap,
|
|
Rch,
|
|
Rem,
|
|
Rex,
|
|
Ric,
|
|
Rlh,
|
|
Svb,
|
|
Svh,
|
|
Svi,
|
|
Svmax,
|
|
Svmin,
|
|
Svw,
|
|
Vb,
|
|
Vh,
|
|
Vi,
|
|
Vmax,
|
|
Vmin,
|
|
Vw,
|
|
};
|
|
constexpr std::optional<CSSLengthUnit> parseCSSLengthUnit(
|
|
std::string_view unit) {
|
|
switch (fnv1aLowercase(unit)) {
|
|
case fnv1a("cap"):
|
|
return CSSLengthUnit::Cap;
|
|
case fnv1a("ch"):
|
|
return CSSLengthUnit::Ch;
|
|
case fnv1a("cm"):
|
|
return CSSLengthUnit::Cm;
|
|
case fnv1a("dvb"):
|
|
return CSSLengthUnit::Dvb;
|
|
case fnv1a("dvh"):
|
|
return CSSLengthUnit::Dvh;
|
|
case fnv1a("dvi"):
|
|
return CSSLengthUnit::Dvi;
|
|
case fnv1a("dvmax"):
|
|
return CSSLengthUnit::Dvmax;
|
|
case fnv1a("dvmin"):
|
|
return CSSLengthUnit::Dvmin;
|
|
case fnv1a("dvw"):
|
|
return CSSLengthUnit::Dvw;
|
|
case fnv1a("em"):
|
|
return CSSLengthUnit::Em;
|
|
case fnv1a("ex"):
|
|
return CSSLengthUnit::Ex;
|
|
case fnv1a("ic"):
|
|
return CSSLengthUnit::Ic;
|
|
case fnv1a("in"):
|
|
return CSSLengthUnit::In;
|
|
case fnv1a("lh"):
|
|
return CSSLengthUnit::Lh;
|
|
case fnv1a("lvb"):
|
|
return CSSLengthUnit::Lvb;
|
|
case fnv1a("lvh"):
|
|
return CSSLengthUnit::Lvh;
|
|
case fnv1a("lvi"):
|
|
return CSSLengthUnit::Lvi;
|
|
case fnv1a("lvmax"):
|
|
return CSSLengthUnit::Lvmax;
|
|
case fnv1a("lvmin"):
|
|
return CSSLengthUnit::Lvmin;
|
|
case fnv1a("lvw"):
|
|
return CSSLengthUnit::Lvw;
|
|
case fnv1a("mm"):
|
|
return CSSLengthUnit::Mm;
|
|
case fnv1a("pc"):
|
|
return CSSLengthUnit::Pc;
|
|
case fnv1a("pt"):
|
|
return CSSLengthUnit::Pt;
|
|
case fnv1a("px"):
|
|
return CSSLengthUnit::Px;
|
|
case fnv1a("q"):
|
|
return CSSLengthUnit::Q;
|
|
case fnv1a("rcap"):
|
|
return CSSLengthUnit::Rcap;
|
|
case fnv1a("rch"):
|
|
return CSSLengthUnit::Rch;
|
|
case fnv1a("rem"):
|
|
return CSSLengthUnit::Rem;
|
|
case fnv1a("rex"):
|
|
return CSSLengthUnit::Rex;
|
|
case fnv1a("ric"):
|
|
return CSSLengthUnit::Ric;
|
|
case fnv1a("rlh"):
|
|
return CSSLengthUnit::Rlh;
|
|
case fnv1a("svb"):
|
|
return CSSLengthUnit::Svb;
|
|
case fnv1a("svh"):
|
|
return CSSLengthUnit::Svh;
|
|
case fnv1a("svi"):
|
|
return CSSLengthUnit::Svi;
|
|
case fnv1a("svmax"):
|
|
return CSSLengthUnit::Svmax;
|
|
case fnv1a("svmin"):
|
|
return CSSLengthUnit::Svmin;
|
|
case fnv1a("svw"):
|
|
return CSSLengthUnit::Svw;
|
|
case fnv1a("vb"):
|
|
return CSSLengthUnit::Vb;
|
|
case fnv1a("vh"):
|
|
return CSSLengthUnit::Vh;
|
|
case fnv1a("vi"):
|
|
return CSSLengthUnit::Vi;
|
|
case fnv1a("vmax"):
|
|
return CSSLengthUnit::Vmax;
|
|
case fnv1a("vmin"):
|
|
return CSSLengthUnit::Vmin;
|
|
case fnv1a("vw"):
|
|
return CSSLengthUnit::Vw;
|
|
default:
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSList.h}:
|
|
namespace facebook::react {
|
|
template <CSSMaybeCompoundDataType T, CSSDelimiter Delim>
|
|
template <CSSDataType AllowedTypeT, CSSDelimiter Delim>
|
|
struct CSSList<AllowedTypeT, Delim> : public std::vector<AllowedTypeT> {};
|
|
template <CSSValidCompoundDataType AllowedTypesT, CSSDelimiter Delim>
|
|
struct CSSList<AllowedTypesT, Delim>
|
|
: public std::vector<CSSVariantWithTypes<AllowedTypesT>> {};
|
|
template <CSSMaybeCompoundDataType AllowedTypeT, CSSDelimiter Delim>
|
|
struct CSSDataTypeParser<CSSList<AllowedTypeT, Delim>> {
|
|
static inline auto consume(CSSSyntaxParser& parser)
|
|
-> std::optional<CSSList<AllowedTypeT, Delim>> {
|
|
CSSList<AllowedTypeT, Delim> result;
|
|
for (auto nextValue = parseNextCSSValue<AllowedTypeT>(parser);
|
|
!std::holds_alternative<std::monostate>(nextValue);
|
|
nextValue = parseNextCSSValue<AllowedTypeT>(parser, Delim)) {
|
|
std::visit(
|
|
[&](auto&& v) {
|
|
if constexpr (!std::is_same_v<
|
|
std::remove_cvref_t<decltype(v)>,
|
|
std::monostate>) {
|
|
result.push_back(std::forward<decltype(v)>(v));
|
|
}
|
|
},
|
|
nextValue);
|
|
}
|
|
if (result.empty()) {
|
|
return {};
|
|
}
|
|
return result;
|
|
}
|
|
};
|
|
template <CSSMaybeCompoundDataType AllowedTypeT>
|
|
using CSSCommaSeparatedList = CSSList<AllowedTypeT, CSSDelimiter::Comma>;
|
|
template <CSSMaybeCompoundDataType AllowedTypeT>
|
|
using CSSWhitespaceSeparatedList =
|
|
CSSList<AllowedTypeT, CSSDelimiter::Whitespace>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSNamedColor.h}:
|
|
namespace facebook::react {
|
|
template <typename CSSColor>
|
|
constexpr std::optional<CSSColor> parseCSSNamedColor(std::string_view name) {
|
|
switch (fnv1aLowercase(name)) {
|
|
case fnv1a("aliceblue"):
|
|
return CSSColor{240, 248, 255, 255};
|
|
case fnv1a("antiquewhite"):
|
|
return CSSColor{250, 235, 215, 255};
|
|
case fnv1a("aqua"):
|
|
return CSSColor{0, 255, 255, 255};
|
|
case fnv1a("aquamarine"):
|
|
return CSSColor{127, 255, 212, 255};
|
|
case fnv1a("azure"):
|
|
return CSSColor{240, 255, 255, 255};
|
|
case fnv1a("beige"):
|
|
return CSSColor{245, 245, 220, 255};
|
|
case fnv1a("bisque"):
|
|
return CSSColor{255, 228, 196, 255};
|
|
case fnv1a("black"):
|
|
return CSSColor{0, 0, 0, 255};
|
|
case fnv1a("blanchedalmond"):
|
|
return CSSColor{255, 235, 205, 255};
|
|
case fnv1a("blue"):
|
|
return CSSColor{0, 0, 255, 255};
|
|
case fnv1a("blueviolet"):
|
|
return CSSColor{138, 43, 226, 255};
|
|
case fnv1a("brown"):
|
|
return CSSColor{165, 42, 42, 255};
|
|
case fnv1a("burlywood"):
|
|
return CSSColor{222, 184, 135, 255};
|
|
case fnv1a("cadetblue"):
|
|
return CSSColor{95, 158, 160, 255};
|
|
case fnv1a("chartreuse"):
|
|
return CSSColor{127, 255, 0, 255};
|
|
case fnv1a("chocolate"):
|
|
return CSSColor{210, 105, 30, 255};
|
|
case fnv1a("coral"):
|
|
return CSSColor{255, 127, 80, 255};
|
|
case fnv1a("cornflowerblue"):
|
|
return CSSColor{100, 149, 237, 255};
|
|
case fnv1a("cornsilk"):
|
|
return CSSColor{255, 248, 220, 255};
|
|
case fnv1a("crimson"):
|
|
return CSSColor{220, 20, 60, 255};
|
|
case fnv1a("cyan"):
|
|
return CSSColor{0, 255, 255, 255};
|
|
case fnv1a("darkblue"):
|
|
return CSSColor{0, 0, 139, 255};
|
|
case fnv1a("darkcyan"):
|
|
return CSSColor{0, 139, 139, 255};
|
|
case fnv1a("darkgoldenrod"):
|
|
return CSSColor{184, 134, 11, 255};
|
|
case fnv1a("darkgray"):
|
|
return CSSColor{169, 169, 169, 255};
|
|
case fnv1a("darkgreen"):
|
|
return CSSColor{0, 100, 0, 255};
|
|
case fnv1a("darkgrey"):
|
|
return CSSColor{169, 169, 169, 255};
|
|
case fnv1a("darkkhaki"):
|
|
return CSSColor{189, 183, 107, 255};
|
|
case fnv1a("darkmagenta"):
|
|
return CSSColor{139, 0, 139, 255};
|
|
case fnv1a("darkolivegreen"):
|
|
return CSSColor{85, 107, 47, 255};
|
|
case fnv1a("darkorange"):
|
|
return CSSColor{255, 140, 0, 255};
|
|
case fnv1a("darkorchid"):
|
|
return CSSColor{153, 50, 204, 255};
|
|
case fnv1a("darkred"):
|
|
return CSSColor{139, 0, 0, 255};
|
|
case fnv1a("darksalmon"):
|
|
return CSSColor{233, 150, 122, 255};
|
|
case fnv1a("darkseagreen"):
|
|
return CSSColor{143, 188, 143, 255};
|
|
case fnv1a("darkslateblue"):
|
|
return CSSColor{72, 61, 139, 255};
|
|
case fnv1a("darkslategray"):
|
|
return CSSColor{47, 79, 79, 255};
|
|
case fnv1a("darkslategrey"):
|
|
return CSSColor{47, 79, 79, 255};
|
|
case fnv1a("darkturquoise"):
|
|
return CSSColor{0, 206, 209, 255};
|
|
case fnv1a("darkviolet"):
|
|
return CSSColor{148, 0, 211, 255};
|
|
case fnv1a("deeppink"):
|
|
return CSSColor{255, 20, 147, 255};
|
|
case fnv1a("deepskyblue"):
|
|
return CSSColor{0, 191, 255, 255};
|
|
case fnv1a("dimgray"):
|
|
return CSSColor{105, 105, 105, 255};
|
|
case fnv1a("dimgrey"):
|
|
return CSSColor{105, 105, 105, 255};
|
|
case fnv1a("dodgerblue"):
|
|
return CSSColor{30, 144, 255, 255};
|
|
case fnv1a("firebrick"):
|
|
return CSSColor{178, 34, 34, 255};
|
|
case fnv1a("floralwhite"):
|
|
return CSSColor{255, 250, 240, 255};
|
|
case fnv1a("forestgreen"):
|
|
return CSSColor{34, 139, 34, 255};
|
|
case fnv1a("fuchsia"):
|
|
return CSSColor{255, 0, 255, 255};
|
|
case fnv1a("gainsboro"):
|
|
return CSSColor{220, 220, 220, 255};
|
|
case fnv1a("ghostwhite"):
|
|
return CSSColor{248, 248, 255, 255};
|
|
case fnv1a("gold"):
|
|
return CSSColor{255, 215, 0, 255};
|
|
case fnv1a("goldenrod"):
|
|
return CSSColor{218, 165, 32, 255};
|
|
case fnv1a("gray"):
|
|
return CSSColor{128, 128, 128, 255};
|
|
case fnv1a("green"):
|
|
return CSSColor{0, 128, 0, 255};
|
|
case fnv1a("greenyellow"):
|
|
return CSSColor{173, 255, 47, 255};
|
|
case fnv1a("grey"):
|
|
return CSSColor{128, 128, 128, 255};
|
|
case fnv1a("honeydew"):
|
|
return CSSColor{240, 255, 240, 255};
|
|
case fnv1a("hotpink"):
|
|
return CSSColor{255, 105, 180, 255};
|
|
case fnv1a("indianred"):
|
|
return CSSColor{205, 92, 92, 255};
|
|
case fnv1a("indigo"):
|
|
return CSSColor{75, 0, 130, 255};
|
|
case fnv1a("ivory"):
|
|
return CSSColor{255, 255, 240, 255};
|
|
case fnv1a("khaki"):
|
|
return CSSColor{240, 230, 140, 255};
|
|
case fnv1a("lavender"):
|
|
return CSSColor{230, 230, 250, 255};
|
|
case fnv1a("lavenderblush"):
|
|
return CSSColor{255, 240, 245, 255};
|
|
case fnv1a("lawngreen"):
|
|
return CSSColor{124, 252, 0, 255};
|
|
case fnv1a("lemonchiffon"):
|
|
return CSSColor{255, 250, 205, 255};
|
|
case fnv1a("lightblue"):
|
|
return CSSColor{173, 216, 230, 255};
|
|
case fnv1a("lightcoral"):
|
|
return CSSColor{240, 128, 128, 255};
|
|
case fnv1a("lightcyan"):
|
|
return CSSColor{224, 255, 255, 255};
|
|
case fnv1a("lightgoldenrodyellow"):
|
|
return CSSColor{250, 250, 210, 255};
|
|
case fnv1a("lightgray"):
|
|
return CSSColor{211, 211, 211, 255};
|
|
case fnv1a("lightgreen"):
|
|
return CSSColor{144, 238, 144, 255};
|
|
case fnv1a("lightgrey"):
|
|
return CSSColor{211, 211, 211, 255};
|
|
case fnv1a("lightpink"):
|
|
return CSSColor{255, 182, 193, 255};
|
|
case fnv1a("lightsalmon"):
|
|
return CSSColor{255, 160, 122, 255};
|
|
case fnv1a("lightseagreen"):
|
|
return CSSColor{32, 178, 170, 255};
|
|
case fnv1a("lightskyblue"):
|
|
return CSSColor{135, 206, 250, 255};
|
|
case fnv1a("lightslategray"):
|
|
return CSSColor{119, 136, 153, 255};
|
|
case fnv1a("lightslategrey"):
|
|
return CSSColor{119, 136, 153, 255};
|
|
case fnv1a("lightsteelblue"):
|
|
return CSSColor{176, 196, 222, 255};
|
|
case fnv1a("lightyellow"):
|
|
return CSSColor{255, 255, 224, 255};
|
|
case fnv1a("lime"):
|
|
return CSSColor{0, 255, 0, 255};
|
|
case fnv1a("limegreen"):
|
|
return CSSColor{50, 205, 50, 255};
|
|
case fnv1a("linen"):
|
|
return CSSColor{250, 240, 230, 255};
|
|
case fnv1a("magenta"):
|
|
return CSSColor{255, 0, 255, 255};
|
|
case fnv1a("maroon"):
|
|
return CSSColor{128, 0, 0, 255};
|
|
case fnv1a("mediumaquamarine"):
|
|
return CSSColor{102, 205, 170, 255};
|
|
case fnv1a("mediumblue"):
|
|
return CSSColor{0, 0, 205, 255};
|
|
case fnv1a("mediumorchid"):
|
|
return CSSColor{186, 85, 211, 255};
|
|
case fnv1a("mediumpurple"):
|
|
return CSSColor{147, 112, 219, 255};
|
|
case fnv1a("mediumseagreen"):
|
|
return CSSColor{60, 179, 113, 255};
|
|
case fnv1a("mediumslateblue"):
|
|
return CSSColor{123, 104, 238, 255};
|
|
case fnv1a("mediumspringgreen"):
|
|
return CSSColor{0, 250, 154, 255};
|
|
case fnv1a("mediumturquoise"):
|
|
return CSSColor{72, 209, 204, 255};
|
|
case fnv1a("mediumvioletred"):
|
|
return CSSColor{199, 21, 133, 255};
|
|
case fnv1a("midnightblue"):
|
|
return CSSColor{25, 25, 112, 255};
|
|
case fnv1a("mintcream"):
|
|
return CSSColor{245, 255, 250, 255};
|
|
case fnv1a("mistyrose"):
|
|
return CSSColor{255, 228, 225, 255};
|
|
case fnv1a("moccasin"):
|
|
return CSSColor{255, 228, 181, 255};
|
|
case fnv1a("navajowhite"):
|
|
return CSSColor{255, 222, 173, 255};
|
|
case fnv1a("navy"):
|
|
return CSSColor{0, 0, 128, 255};
|
|
case fnv1a("oldlace"):
|
|
return CSSColor{253, 245, 230, 255};
|
|
case fnv1a("olive"):
|
|
return CSSColor{128, 128, 0, 255};
|
|
case fnv1a("olivedrab"):
|
|
return CSSColor{107, 142, 35, 255};
|
|
case fnv1a("orange"):
|
|
return CSSColor{255, 165, 0, 255};
|
|
case fnv1a("orangered"):
|
|
return CSSColor{255, 69, 0, 255};
|
|
case fnv1a("orchid"):
|
|
return CSSColor{218, 112, 214, 255};
|
|
case fnv1a("palegoldenrod"):
|
|
return CSSColor{238, 232, 170, 255};
|
|
case fnv1a("palegreen"):
|
|
return CSSColor{152, 251, 152, 255};
|
|
case fnv1a("paleturquoise"):
|
|
return CSSColor{175, 238, 238, 255};
|
|
case fnv1a("palevioletred"):
|
|
return CSSColor{219, 112, 147, 255};
|
|
case fnv1a("papayawhip"):
|
|
return CSSColor{255, 239, 213, 255};
|
|
case fnv1a("peachpuff"):
|
|
return CSSColor{255, 218, 185, 255};
|
|
case fnv1a("peru"):
|
|
return CSSColor{205, 133, 63, 255};
|
|
case fnv1a("pink"):
|
|
return CSSColor{255, 192, 203, 255};
|
|
case fnv1a("plum"):
|
|
return CSSColor{221, 160, 221, 255};
|
|
case fnv1a("powderblue"):
|
|
return CSSColor{176, 224, 230, 255};
|
|
case fnv1a("purple"):
|
|
return CSSColor{128, 0, 128, 255};
|
|
case fnv1a("rebeccapurple"):
|
|
return CSSColor{102, 51, 153, 255};
|
|
case fnv1a("red"):
|
|
return CSSColor{255, 0, 0, 255};
|
|
case fnv1a("rosybrown"):
|
|
return CSSColor{188, 143, 143, 255};
|
|
case fnv1a("royalblue"):
|
|
return CSSColor{65, 105, 225, 255};
|
|
case fnv1a("saddlebrown"):
|
|
return CSSColor{139, 69, 19, 255};
|
|
case fnv1a("salmon"):
|
|
return CSSColor{250, 128, 114, 255};
|
|
case fnv1a("sandybrown"):
|
|
return CSSColor{244, 164, 96, 255};
|
|
case fnv1a("seagreen"):
|
|
return CSSColor{46, 139, 87, 255};
|
|
case fnv1a("seashell"):
|
|
return CSSColor{255, 245, 238, 255};
|
|
case fnv1a("sienna"):
|
|
return CSSColor{160, 82, 45, 255};
|
|
case fnv1a("silver"):
|
|
return CSSColor{192, 192, 192, 255};
|
|
case fnv1a("skyblue"):
|
|
return CSSColor{135, 206, 235, 255};
|
|
case fnv1a("slateblue"):
|
|
return CSSColor{106, 90, 205, 255};
|
|
case fnv1a("slategray"):
|
|
return CSSColor{112, 128, 144, 255};
|
|
case fnv1a("slategrey"):
|
|
return CSSColor{112, 128, 144, 255};
|
|
case fnv1a("snow"):
|
|
return CSSColor{255, 250, 250, 255};
|
|
case fnv1a("springgreen"):
|
|
return CSSColor{0, 255, 127, 255};
|
|
case fnv1a("steelblue"):
|
|
return CSSColor{70, 130, 180, 255};
|
|
case fnv1a("tan"):
|
|
return CSSColor{210, 180, 140, 255};
|
|
case fnv1a("teal"):
|
|
return CSSColor{0, 128, 128, 255};
|
|
case fnv1a("thistle"):
|
|
return CSSColor{216, 191, 216, 255};
|
|
case fnv1a("tomato"):
|
|
return CSSColor{255, 99, 71, 255};
|
|
case fnv1a("transparent"):
|
|
return CSSColor{0, 0, 0, 0};
|
|
case fnv1a("turquoise"):
|
|
return CSSColor{64, 224, 208, 255};
|
|
case fnv1a("violet"):
|
|
return CSSColor{238, 130, 238, 255};
|
|
case fnv1a("wheat"):
|
|
return CSSColor{245, 222, 179, 255};
|
|
case fnv1a("white"):
|
|
return CSSColor{255, 255, 255, 255};
|
|
case fnv1a("whitesmoke"):
|
|
return CSSColor{245, 245, 245, 255};
|
|
case fnv1a("yellow"):
|
|
return CSSColor{255, 255, 0, 255};
|
|
case fnv1a("yellowgreen"):
|
|
return CSSColor{154, 205, 50, 255};
|
|
default:
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSNumber.h}:
|
|
namespace facebook::react {
|
|
struct CSSNumber {
|
|
float value{};
|
|
constexpr bool operator==(const CSSNumber& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSNumber> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<CSSNumber> {
|
|
if (token.type() == CSSTokenType::Number) {
|
|
return CSSNumber{token.numericValue()};
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSNumber>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSPercentage.h}:
|
|
namespace facebook::react {
|
|
struct CSSPercentage {
|
|
float value{};
|
|
constexpr bool operator==(const CSSPercentage& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSPercentage> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<CSSPercentage> {
|
|
if (token.type() == CSSTokenType::Percentage) {
|
|
return CSSPercentage{token.numericValue()};
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSPercentage>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSRatio.h}:
|
|
namespace facebook::react {
|
|
struct CSSRatio {
|
|
float numerator{};
|
|
float denominator{};
|
|
constexpr bool operator==(const CSSRatio& rhs) const = default;
|
|
constexpr bool isDegenerate() const {
|
|
return numerator == 0.0f ||
|
|
numerator == std::numeric_limits<float>::infinity() ||
|
|
denominator == 0.0f ||
|
|
denominator == std::numeric_limits<float>::infinity();
|
|
}
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSRatio> {
|
|
static constexpr auto consume(CSSSyntaxParser& parser)
|
|
-> std::optional<CSSRatio> {
|
|
auto numerator = parseNextCSSValue<CSSNumber>(parser);
|
|
if (!std::holds_alternative<CSSNumber>(numerator)) {
|
|
return {};
|
|
}
|
|
auto numeratorValue = std::get<CSSNumber>(numerator).value;
|
|
if (numeratorValue >= 0) {
|
|
auto denominator =
|
|
peekNextCSSValue<CSSNumber>(parser, CSSDelimiter::Solidus);
|
|
if (std::holds_alternative<CSSNumber>(denominator) &&
|
|
std::get<CSSNumber>(denominator).value >= 0) {
|
|
parseNextCSSValue<CSSNumber>(parser, CSSDelimiter::Solidus);
|
|
return CSSRatio{numeratorValue, std::get<CSSNumber>(denominator).value};
|
|
}
|
|
return CSSRatio{numeratorValue, 1.0f};
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSRatio>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSShadow.h}:
|
|
namespace facebook::react {
|
|
struct CSSShadow {
|
|
CSSLength offsetX{};
|
|
CSSLength offsetY{};
|
|
CSSLength blurRadius{};
|
|
CSSLength spreadDistance{};
|
|
CSSColor color{CSSColor::black()};
|
|
bool inset{false};
|
|
constexpr bool operator==(const CSSShadow& rhs) const = default;
|
|
};
|
|
enum class CSSInsetShadowKeyword : std::underlying_type_t<CSSKeyword> {
|
|
Inset = to_underlying(CSSKeyword::Inset),
|
|
};
|
|
static_assert(CSSDataType<CSSInsetShadowKeyword>);
|
|
template <>
|
|
struct CSSDataTypeParser<CSSShadow> {
|
|
static constexpr auto consume(CSSSyntaxParser& parser)
|
|
-> std::optional<CSSShadow> {
|
|
std::optional<CSSColor> color{};
|
|
bool inset{false};
|
|
std::optional<std::tuple<CSSLength, CSSLength, CSSLength, CSSLength>>
|
|
lengths{};
|
|
for (auto nextValue =
|
|
parseNextCSSValue<CSSLength, CSSColor, CSSInsetShadowKeyword>(
|
|
parser);
|
|
!std::holds_alternative<std::monostate>(nextValue);
|
|
nextValue =
|
|
parseNextCSSValue<CSSLength, CSSColor, CSSInsetShadowKeyword>(
|
|
parser, CSSDelimiter::Whitespace)) {
|
|
if (std::holds_alternative<CSSLength>(nextValue)) {
|
|
if (lengths.has_value()) {
|
|
return {};
|
|
}
|
|
lengths = parseRestLengths(std::get<CSSLength>(nextValue), parser);
|
|
if (!lengths.has_value()) {
|
|
return {};
|
|
}
|
|
continue;
|
|
}
|
|
if (std::holds_alternative<CSSColor>(nextValue)) {
|
|
if (color.has_value()) {
|
|
return {};
|
|
}
|
|
color = std::get<CSSColor>(nextValue);
|
|
continue;
|
|
}
|
|
if (std::holds_alternative<CSSInsetShadowKeyword>(nextValue)) {
|
|
if (inset) {
|
|
return {};
|
|
}
|
|
inset = true;
|
|
continue;
|
|
}
|
|
}
|
|
if (!lengths.has_value()) {
|
|
return {};
|
|
}
|
|
return CSSShadow{
|
|
.offsetX = std::get<0>(*lengths),
|
|
.offsetY = std::get<1>(*lengths),
|
|
.blurRadius = std::get<2>(*lengths),
|
|
.spreadDistance = std::get<3>(*lengths),
|
|
.color = color.value_or(CSSColor::black()),
|
|
.inset = inset,
|
|
};
|
|
}
|
|
};
|
|
}
|
|
auto blurRadius =
|
|
parseNextCSSValue<CSSLength>(parser, CSSDelimiter::Whitespace);
|
|
if (std::holds_alternative<std::monostate>(blurRadius)) {
|
|
return std::make_tuple(
|
|
offsetX, std::get<CSSLength>(offsetY), CSSLength{}, CSSLength{});
|
|
}
|
|
if (std::get<CSSLength>(blurRadius).value < 0) {
|
|
return {};
|
|
}
|
|
auto spreadDistance =
|
|
parseNextCSSValue<CSSLength>(parser, CSSDelimiter::Whitespace);
|
|
if (std::holds_alternative<std::monostate>(spreadDistance)) {
|
|
return std::make_tuple(
|
|
offsetX,
|
|
std::get<CSSLength>(offsetY),
|
|
std::get<CSSLength>(blurRadius),
|
|
CSSLength{});
|
|
}
|
|
return std::make_tuple(
|
|
offsetX,
|
|
std::get<CSSLength>(offsetY),
|
|
std::get<CSSLength>(blurRadius),
|
|
std::get<CSSLength>(spreadDistance));
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSShadow>);
|
|
using CSSShadowList = CSSCommaSeparatedList<CSSShadow>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSSyntaxParser.h}:
|
|
namespace facebook::react {
|
|
struct CSSFunctionBlock {
|
|
std::string_view name{};
|
|
};
|
|
using CSSPreservedToken = CSSToken;
|
|
struct CSSSimpleBlock {
|
|
CSSTokenType openBracketType{};
|
|
};
|
|
template <typename T>
|
|
concept CSSSyntaxVisitorReturn =
|
|
std::is_default_constructible_v<T> && std::equality_comparable<T>;
|
|
template <typename T, typename ReturnT>
|
|
concept CSSFunctionVisitor = CSSSyntaxVisitorReturn<ReturnT> &&
|
|
requires(T visitor, CSSFunctionBlock func, CSSSyntaxParser& blockParser) {
|
|
{ visitor(func, blockParser) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT>
|
|
concept CSSPreservedTokenVisitor = CSSSyntaxVisitorReturn<ReturnT> &&
|
|
requires(T visitor, CSSPreservedToken token) {
|
|
{ visitor(token) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT>
|
|
concept CSSSimpleBlockVisitor = CSSSyntaxVisitorReturn<ReturnT> &&
|
|
requires(T visitor, CSSSimpleBlock block, CSSSyntaxParser& blockParser) {
|
|
{ visitor(block, blockParser) } -> std::convertible_to<ReturnT>;
|
|
};
|
|
template <typename T, typename ReturnT>
|
|
concept CSSComponentValueVisitor = CSSSyntaxVisitorReturn<ReturnT> &&
|
|
(CSSFunctionVisitor<T, ReturnT> || CSSPreservedTokenVisitor<T, ReturnT> ||
|
|
CSSSimpleBlockVisitor<T, ReturnT>);
|
|
template <typename ReturnT, typename... VisitorsT>
|
|
concept CSSUniqueComponentValueVisitors = CSSSyntaxVisitorReturn<ReturnT> &&
|
|
(CSSComponentValueVisitor<VisitorsT, ReturnT> && ...) &&
|
|
((CSSFunctionVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1 &&
|
|
((CSSPreservedTokenVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1 &&
|
|
((CSSSimpleBlockVisitor<VisitorsT, ReturnT> ? 1 : 0) + ... + 0) <= 1;
|
|
enum class CSSDelimiter {
|
|
Whitespace,
|
|
OptionalWhitespace,
|
|
Solidus,
|
|
SolidusOrWhitespace,
|
|
Comma,
|
|
CommaOrWhitespace,
|
|
None,
|
|
};
|
|
class CSSSyntaxParser {
|
|
template <
|
|
CSSSyntaxVisitorReturn ReturnT,
|
|
CSSComponentValueVisitor<ReturnT>... VisitorsT>
|
|
friend
|
|
|
|
public:
|
|
explicit constexpr CSSSyntaxParser(std::string_view css)
|
|
: tokenizer_{css}, currentToken_(tokenizer_.next()) {}
|
|
constexpr CSSSyntaxParser(const CSSSyntaxParser&) = default;
|
|
constexpr CSSSyntaxParser(CSSSyntaxParser&&) = default;
|
|
constexpr CSSSyntaxParser& operator=(const CSSSyntaxParser&) = default;
|
|
constexpr CSSSyntaxParser& operator=(CSSSyntaxParser&&) = default;
|
|
template <CSSSyntaxVisitorReturn ReturnT>
|
|
constexpr ReturnT consumeComponentValue(
|
|
CSSDelimiter delimiter,
|
|
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
|
|
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>);
|
|
template <CSSSyntaxVisitorReturn ReturnT>
|
|
constexpr ReturnT consumeComponentValue(
|
|
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
|
|
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>);
|
|
constexpr bool isFinished() const {
|
|
return currentToken_.type() == CSSTokenType::EndOfFile;
|
|
}
|
|
constexpr void consumeWhitespace() {
|
|
if (currentToken_.type() == CSSTokenType::WhiteSpace) {
|
|
currentToken_ = tokenizer_.next();
|
|
}
|
|
}
|
|
constexpr bool consumeDelimiter(CSSDelimiter delimiter) {
|
|
if (delimiter == CSSDelimiter::None) {
|
|
return true;
|
|
}
|
|
bool hasWhiteSpace = peek().type() == CSSTokenType::WhiteSpace;
|
|
consumeWhitespace();
|
|
switch (delimiter) {
|
|
case CSSDelimiter::Comma:
|
|
if (peek().type() == CSSTokenType::Comma) {
|
|
consumeToken();
|
|
consumeWhitespace();
|
|
return true;
|
|
}
|
|
return false;
|
|
case CSSDelimiter::Whitespace:
|
|
return hasWhiteSpace;
|
|
case CSSDelimiter::OptionalWhitespace:
|
|
return true;
|
|
case CSSDelimiter::CommaOrWhitespace:
|
|
if (peek().type() == CSSTokenType::Comma) {
|
|
consumeToken();
|
|
consumeWhitespace();
|
|
return true;
|
|
}
|
|
return hasWhiteSpace;
|
|
case CSSDelimiter::Solidus:
|
|
if (peek().type() == CSSTokenType::Delim &&
|
|
peek().stringValue() == "/") {
|
|
consumeToken();
|
|
consumeWhitespace();
|
|
return true;
|
|
}
|
|
return false;
|
|
case CSSDelimiter::SolidusOrWhitespace:
|
|
if (peek().type() == CSSTokenType::Delim &&
|
|
peek().stringValue() == "/") {
|
|
consumeToken();
|
|
consumeWhitespace();
|
|
return true;
|
|
}
|
|
return hasWhiteSpace;
|
|
case CSSDelimiter::None:
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
};
|
|
};
|
|
template <
|
|
CSSSyntaxVisitorReturn ReturnT,
|
|
CSSComponentValueVisitor<ReturnT>... VisitorsT>
|
|
struct CSSComponentValueVisitorDispatcher {
|
|
CSSSyntaxParser& parser;
|
|
constexpr ReturnT consumeComponentValue(
|
|
CSSDelimiter delimiter,
|
|
const VisitorsT&... visitors) {
|
|
auto originalParser = parser;
|
|
if (!parser.consumeDelimiter(delimiter)) {
|
|
parser = originalParser;
|
|
return {};
|
|
}
|
|
if (parser.peek().type() == parser.terminator_) {
|
|
parser = originalParser;
|
|
return {};
|
|
}
|
|
switch (parser.peek().type()) {
|
|
case CSSTokenType::Function:
|
|
if (auto ret = visitFunction(visitors...)) {
|
|
return *ret;
|
|
}
|
|
break;
|
|
case CSSTokenType::OpenParen:
|
|
if (auto ret =
|
|
visitSimpleBlock(CSSTokenType::CloseParen, visitors...)) {
|
|
return *ret;
|
|
}
|
|
break;
|
|
case CSSTokenType::OpenSquare:
|
|
if (auto ret =
|
|
visitSimpleBlock(CSSTokenType::CloseSquare, visitors...)) {
|
|
return *ret;
|
|
}
|
|
break;
|
|
case CSSTokenType::OpenCurly:
|
|
if (auto ret =
|
|
visitSimpleBlock(CSSTokenType::CloseCurly, visitors...)) {
|
|
return *ret;
|
|
}
|
|
break;
|
|
default:
|
|
if (auto ret = visitPreservedToken(visitors...)) {
|
|
return *ret;
|
|
}
|
|
break;
|
|
}
|
|
parser = originalParser;
|
|
return ReturnT{};
|
|
}
|
|
constexpr std::optional<ReturnT> visitFunction(
|
|
const CSSComponentValueVisitor<ReturnT> auto& visitor,
|
|
const CSSComponentValueVisitor<ReturnT> auto&... rest) {
|
|
if constexpr (CSSFunctionVisitor<decltype(visitor), ReturnT>) {
|
|
auto name = parser.consumeToken().stringValue();
|
|
parser.consumeWhitespace();
|
|
auto blockParser = CSSSyntaxParser{parser, CSSTokenType::CloseParen};
|
|
auto functionValue = visitor({name}, blockParser);
|
|
parser.advanceToBlockParser(blockParser);
|
|
parser.consumeWhitespace();
|
|
if (parser.peek().type() == CSSTokenType::CloseParen &&
|
|
functionValue != ReturnT{}) {
|
|
parser.consumeToken();
|
|
return functionValue;
|
|
}
|
|
return {};
|
|
}
|
|
return visitFunction(rest...);
|
|
}
|
|
constexpr std::optional<ReturnT> visitFunction() {
|
|
return {};
|
|
}
|
|
constexpr std::optional<ReturnT> visitSimpleBlock(
|
|
CSSTokenType endToken,
|
|
const CSSComponentValueVisitor<ReturnT> auto& visitor,
|
|
const CSSComponentValueVisitor<ReturnT> auto&... rest) {
|
|
if constexpr (CSSSimpleBlockVisitor<decltype(visitor), ReturnT>) {
|
|
auto openBracketType = parser.consumeToken().type();
|
|
parser.consumeWhitespace();
|
|
auto blockParser = CSSSyntaxParser{parser, endToken};
|
|
auto blockValue = visitor({openBracketType}, blockParser);
|
|
parser.advanceToBlockParser(blockParser);
|
|
parser.consumeWhitespace();
|
|
if (parser.peek().type() == endToken && blockValue != ReturnT{}) {
|
|
parser.consumeToken();
|
|
return blockValue;
|
|
}
|
|
return {};
|
|
}
|
|
return visitSimpleBlock(endToken, rest...);
|
|
}
|
|
constexpr std::optional<ReturnT> visitSimpleBlock(CSSTokenType endToken) {
|
|
return {};
|
|
}
|
|
constexpr std::optional<ReturnT> visitPreservedToken(
|
|
const CSSComponentValueVisitor<ReturnT> auto& visitor,
|
|
const CSSComponentValueVisitor<ReturnT> auto&... rest) {
|
|
if constexpr (CSSPreservedTokenVisitor<decltype(visitor), ReturnT>) {
|
|
auto ret = visitor(parser.consumeToken());
|
|
if (ret != ReturnT{}) {
|
|
return ret;
|
|
}
|
|
}
|
|
return visitPreservedToken(rest...);
|
|
}
|
|
constexpr std::optional<ReturnT> visitPreservedToken() {
|
|
return {};
|
|
}
|
|
};
|
|
template <CSSSyntaxVisitorReturn ReturnT>
|
|
constexpr ReturnT CSSSyntaxParser::consumeComponentValue(
|
|
CSSDelimiter delimiter,
|
|
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
|
|
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
|
|
{
|
|
return CSSComponentValueVisitorDispatcher<ReturnT, decltype(visitors)...>{
|
|
*this}
|
|
.consumeComponentValue(delimiter, visitors...);
|
|
}
|
|
template <CSSSyntaxVisitorReturn ReturnT>
|
|
constexpr ReturnT CSSSyntaxParser::consumeComponentValue(
|
|
const CSSComponentValueVisitor<ReturnT> auto&... visitors)
|
|
requires(CSSUniqueComponentValueVisitors<ReturnT, decltype(visitors)...>)
|
|
{
|
|
return consumeComponentValue<ReturnT>(CSSDelimiter::None, visitors...);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSToken.h}:
|
|
namespace facebook::react {
|
|
enum class CSSTokenType {
|
|
CloseCurly,
|
|
CloseParen,
|
|
CloseSquare,
|
|
Comma,
|
|
Delim,
|
|
Dimension,
|
|
EndOfFile,
|
|
Function,
|
|
Ident,
|
|
Number,
|
|
OpenCurly,
|
|
OpenParen,
|
|
OpenSquare,
|
|
Percentage,
|
|
WhiteSpace,
|
|
Hash,
|
|
};
|
|
class CSSToken {
|
|
public:
|
|
explicit constexpr CSSToken(CSSTokenType type) : type_(type) {}
|
|
constexpr CSSToken(CSSTokenType type, std::string_view value)
|
|
: type_{type}, stringValue_{value} {}
|
|
constexpr CSSToken(CSSTokenType type, float value)
|
|
: type_{type}, numericValue_{value} {}
|
|
constexpr CSSToken(CSSTokenType type, float value, std::string_view unit)
|
|
: type_{type}, numericValue_{value}, unit_{unit} {}
|
|
constexpr CSSToken(const CSSToken& other) = default;
|
|
constexpr CSSToken(CSSToken&& other) = default;
|
|
constexpr CSSToken& operator=(const CSSToken& other) = default;
|
|
constexpr CSSToken& operator=(CSSToken&& other) = default;
|
|
constexpr CSSTokenType type() const {
|
|
return type_;
|
|
}
|
|
constexpr std::string_view stringValue() const {
|
|
return stringValue_;
|
|
}
|
|
constexpr float numericValue() const {
|
|
return numericValue_;
|
|
}
|
|
constexpr std::string_view unit() const {
|
|
return unit_;
|
|
}
|
|
constexpr bool operator==(const CSSToken& other) const = default;
|
|
};
|
|
std::string_view unit_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSTokenizer.h}:
|
|
namespace facebook::react {
|
|
class CSSTokenizer {
|
|
public:
|
|
explicit constexpr CSSTokenizer(std::string_view characters)
|
|
: remainingCharacters_{characters} {}
|
|
constexpr CSSToken next() {
|
|
char nextChar = peek();
|
|
if (isWhitespace(nextChar)) {
|
|
return consumeWhitespace();
|
|
}
|
|
switch (nextChar) {
|
|
case '(':
|
|
return consumeCharacter(CSSTokenType::OpenParen);
|
|
case ')':
|
|
return consumeCharacter(CSSTokenType::CloseParen);
|
|
case '[':
|
|
return consumeCharacter(CSSTokenType::OpenSquare);
|
|
case ']':
|
|
return consumeCharacter(CSSTokenType::CloseSquare);
|
|
case '{':
|
|
return consumeCharacter(CSSTokenType::OpenCurly);
|
|
case '}':
|
|
return consumeCharacter(CSSTokenType::CloseCurly);
|
|
case ',':
|
|
return consumeCharacter(CSSTokenType::Comma);
|
|
case '+':
|
|
case '-':
|
|
case '.':
|
|
if (wouldStartNumber()) {
|
|
return consumeNumeric();
|
|
} else {
|
|
return consumeDelim();
|
|
}
|
|
case '#':
|
|
if (isIdent(peek(1))) {
|
|
return consumeHash();
|
|
} else {
|
|
return consumeDelim();
|
|
}
|
|
}
|
|
if (isDigit(nextChar)) {
|
|
return consumeNumeric();
|
|
}
|
|
if (isIdentStart(nextChar)) {
|
|
return consumeIdentlikeToken();
|
|
}
|
|
if (nextChar == '\0') {
|
|
return CSSToken{CSSTokenType::EndOfFile};
|
|
}
|
|
return consumeDelim();
|
|
}
|
|
};
|
|
}
|
|
constexpr CSSToken consumeCharacter(CSSTokenType tokenType) {
|
|
advance();
|
|
consumeRunningValue();
|
|
return CSSToken{tokenType};
|
|
}
|
|
constexpr CSSToken consumeWhitespace() {
|
|
while (isWhitespace(peek())) {
|
|
advance();
|
|
}
|
|
consumeRunningValue();
|
|
return CSSToken{CSSTokenType::WhiteSpace};
|
|
}
|
|
constexpr bool wouldStartNumber() const {
|
|
if (peek() == '+' || peek() == '-') {
|
|
if (isDigit(peek(1))) {
|
|
return true;
|
|
}
|
|
if (peek(1) == '.' && isDigit(peek(2))) {
|
|
return true;
|
|
}
|
|
} else if (peek() == '.' && isDigit(peek(1))) {
|
|
return true;
|
|
} else if (isDigit(peek())) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
constexpr CSSToken consumeNumber() {
|
|
auto* b = remainingCharacters_.data();
|
|
auto* e = b + remainingCharacters_.size();
|
|
float value;
|
|
fast_float::parse_options options{
|
|
fast_float::chars_format::general |
|
|
fast_float::chars_format::allow_leading_plus};
|
|
auto [ptr, ec] = fast_float::from_chars_advanced(b, e, value, options);
|
|
position_ += ptr - b;
|
|
consumeRunningValue();
|
|
return {CSSTokenType::Number, value};
|
|
}
|
|
constexpr CSSToken consumeNumeric() {
|
|
auto numberToken = consumeNumber();
|
|
if (isIdent(peek())) {
|
|
auto ident = consumeIdentSequence();
|
|
return {
|
|
CSSTokenType::Dimension,
|
|
numberToken.numericValue(),
|
|
ident.stringValue()};
|
|
} else if (peek() == '%') {
|
|
advance();
|
|
consumeRunningValue();
|
|
return {CSSTokenType::Percentage, numberToken.numericValue()};
|
|
} else {
|
|
return numberToken;
|
|
}
|
|
}
|
|
constexpr CSSToken consumeIdentlikeToken() {
|
|
auto ident = consumeIdentSequence();
|
|
if (peek() == '(') {
|
|
advance();
|
|
consumeRunningValue();
|
|
return {CSSTokenType::Function, ident.stringValue()};
|
|
}
|
|
return ident;
|
|
}
|
|
constexpr CSSToken consumeIdentSequence() {
|
|
while (isIdent(peek())) {
|
|
advance();
|
|
}
|
|
return {CSSTokenType::Ident, consumeRunningValue()};
|
|
}
|
|
constexpr CSSToken consumeHash() {
|
|
advance();
|
|
consumeRunningValue();
|
|
return {CSSTokenType::Hash, consumeIdentSequence().stringValue()};
|
|
}
|
|
constexpr std::string_view consumeRunningValue() {
|
|
auto next = remainingCharacters_.substr(0, position_);
|
|
remainingCharacters_ = remainingCharacters_.substr(next.size());
|
|
position_ = 0;
|
|
return next;
|
|
}
|
|
static constexpr bool isDigit(char c) {
|
|
return c >= '0' && c <= '9';
|
|
}
|
|
static constexpr bool isIdentStart(char c) {
|
|
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' ||
|
|
static_cast<unsigned char>(c) > 0x80;
|
|
}
|
|
static constexpr bool isIdent(char c) {
|
|
{
|
|
return isIdentStart(c) || isDigit(c) || c == '-';
|
|
}
|
|
}
|
|
static constexpr bool isWhitespace(char c) {
|
|
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
|
|
}
|
|
std::string_view remainingCharacters_;
|
|
size_t position_{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSTransform.h}:
|
|
namespace facebook::react {
|
|
namespace detail {
|
|
template <
|
|
typename DataT,
|
|
TemplateStringLiteral Name,
|
|
CSSDataType... AllowedComponentsT>
|
|
requires(std::is_same_v<
|
|
decltype(DataT::value),
|
|
std::variant<AllowedComponentsT...>>)
|
|
struct CSSVariantComponentTransformParser {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<DataT> {
|
|
if (!iequals(func.name, Name)) {
|
|
return {};
|
|
}
|
|
auto val = parseNextCSSValue<AllowedComponentsT...>(parser);
|
|
return std::visit(
|
|
[&](auto&& v) -> std::optional<DataT> {
|
|
if constexpr (std::is_same_v<
|
|
std::remove_cvref_t<decltype(v)>,
|
|
std::monostate>) {
|
|
return {};
|
|
} else {
|
|
return DataT{.value = std::forward<decltype(v)>(v)};
|
|
}
|
|
},
|
|
val);
|
|
}
|
|
};
|
|
template <typename DataT, TemplateStringLiteral Name>
|
|
requires(std::is_same_v<decltype(DataT::value), float>)
|
|
struct CSSNumberPercentTransformParser {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<DataT> {
|
|
if (!iequals(func.name, Name)) {
|
|
return {};
|
|
}
|
|
auto val = parseNextCSSValue<CSSNumber, CSSPercentage>(parser);
|
|
if (std::holds_alternative<std::monostate>(val)) {
|
|
return {};
|
|
}
|
|
return DataT{
|
|
.value = std::holds_alternative<CSSNumber>(val)
|
|
? std::get<CSSNumber>(val).value
|
|
: std::get<CSSPercentage>(val).value / 100.0f};
|
|
}
|
|
};
|
|
template <typename DataT, TemplateStringLiteral Name>
|
|
requires(std::is_same_v<decltype(DataT::degrees), float>)
|
|
struct CSSAngleTransformParser {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<DataT> {
|
|
if (!iequals(func.name, Name)) {
|
|
return {};
|
|
}
|
|
auto value = parseNextCSSValue<CSSAngle, CSSZero>(parser);
|
|
if (std::holds_alternative<std::monostate>(value)) {
|
|
return {};
|
|
}
|
|
return DataT{
|
|
.degrees = std::holds_alternative<CSSAngle>(value)
|
|
? std::get<CSSAngle>(value).degrees
|
|
: 0.0f,
|
|
};
|
|
}
|
|
};
|
|
} // namespace detail
|
|
struct CSSMatrix {
|
|
std::array<float, 6> values{};
|
|
constexpr bool operator==(const CSSMatrix& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSMatrix> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSMatrix> {
|
|
if (!iequals(func.name, "matrix")) {
|
|
return {};
|
|
}
|
|
CSSMatrix matrix{};
|
|
for (int i = 0; i < 6; i++) {
|
|
auto value = parseNextCSSValue<CSSNumber>(
|
|
parser, i == 0 ? CSSDelimiter::None : CSSDelimiter::Comma);
|
|
if (std::holds_alternative<std::monostate>(value)) {
|
|
return {};
|
|
}
|
|
matrix.values[i] = std::get<CSSNumber>(value).value;
|
|
}
|
|
return matrix;
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSMatrix>);
|
|
struct CSSTranslate {
|
|
std::variant<CSSLength, CSSPercentage> x{};
|
|
std::variant<CSSLength, CSSPercentage> y{};
|
|
constexpr bool operator==(const CSSTranslate& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSTranslate> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSTranslate> {
|
|
if (!iequals(func.name, "translate")) {
|
|
return {};
|
|
}
|
|
auto x = parseNextCSSValue<CSSLengthPercentage>(parser);
|
|
if (std::holds_alternative<std::monostate>(x)) {
|
|
return {};
|
|
}
|
|
auto y =
|
|
parseNextCSSValue<CSSLengthPercentage>(parser, CSSDelimiter::Comma);
|
|
CSSTranslate translate{};
|
|
translate.x = std::holds_alternative<CSSLength>(x)
|
|
? std::variant<CSSLength, CSSPercentage>{std::get<CSSLength>(x)}
|
|
: std::variant<CSSLength, CSSPercentage>{std::get<CSSPercentage>(x)};
|
|
if (!std::holds_alternative<std::monostate>(y)) {
|
|
translate.y = std::holds_alternative<CSSLength>(y)
|
|
? std::variant<CSSLength, CSSPercentage>{std::get<CSSLength>(y)}
|
|
: std::variant<CSSLength, CSSPercentage>{std::get<CSSPercentage>(y)};
|
|
}
|
|
return translate;
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSTranslate>);
|
|
struct CSSTranslate3D {
|
|
std::variant<CSSLength, CSSPercentage> x{};
|
|
std::variant<CSSLength, CSSPercentage> y{};
|
|
CSSLength z{};
|
|
constexpr bool operator==(const CSSTranslate3D& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSTranslate3D> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSTranslate3D> {
|
|
if (!iequals(func.name, "translate3d")) {
|
|
return {};
|
|
}
|
|
auto x = parseNextCSSValue<CSSLengthPercentage>(parser);
|
|
if (std::holds_alternative<std::monostate>(x)) {
|
|
return {};
|
|
}
|
|
auto y =
|
|
parseNextCSSValue<CSSLengthPercentage>(parser, CSSDelimiter::Comma);
|
|
if (std::holds_alternative<std::monostate>(y)) {
|
|
return {};
|
|
}
|
|
auto z = parseNextCSSValue<CSSLength>(parser, CSSDelimiter::Comma);
|
|
if (std::holds_alternative<std::monostate>(z)) {
|
|
return {};
|
|
}
|
|
return CSSTranslate3D{
|
|
.x = std::holds_alternative<CSSLength>(x)
|
|
? std::variant<CSSLength, CSSPercentage>{std::get<CSSLength>(x)}
|
|
: std::variant<CSSLength, CSSPercentage>{std::get<CSSPercentage>(
|
|
x)},
|
|
.y = std::holds_alternative<CSSLength>(y)
|
|
? std::variant<CSSLength, CSSPercentage>{std::get<CSSLength>(y)}
|
|
: std::variant<CSSLength, CSSPercentage>{std::get<CSSPercentage>(
|
|
y)},
|
|
.z = std::get<CSSLength>(z),
|
|
};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSTranslate3D>);
|
|
struct CSSTranslateX {
|
|
std::variant<CSSLength, CSSPercentage> value{};
|
|
constexpr bool operator==(const CSSTranslateX& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSTranslateX>
|
|
: public detail::CSSVariantComponentTransformParser<
|
|
CSSTranslateX,
|
|
"translateX",
|
|
CSSLength,
|
|
CSSPercentage> {};
|
|
static_assert(CSSDataType<CSSTranslateX>);
|
|
struct CSSTranslateY {
|
|
std::variant<CSSLength, CSSPercentage> value{};
|
|
constexpr bool operator==(const CSSTranslateY& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSTranslateY>
|
|
: public detail::CSSVariantComponentTransformParser<
|
|
CSSTranslateY,
|
|
"translateY",
|
|
CSSLength,
|
|
CSSPercentage> {};
|
|
static_assert(CSSDataType<CSSTranslateY>);
|
|
struct CSSScale {
|
|
float x{};
|
|
float y{};
|
|
constexpr bool operator==(const CSSScale& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSScale> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSScale> {
|
|
if (!iequals(func.name, "scale")) {
|
|
return {};
|
|
}
|
|
auto x = parseNextCSSValue<CSSNumber, CSSPercentage>(parser);
|
|
if (std::holds_alternative<std::monostate>(x)) {
|
|
return {};
|
|
}
|
|
auto y = parseNextCSSValue<CSSNumber, CSSPercentage>(
|
|
parser, CSSDelimiter::Comma);
|
|
auto normX = std::holds_alternative<CSSNumber>(x)
|
|
? std::get<CSSNumber>(x).value
|
|
: std::get<CSSPercentage>(x).value / 100.0f;
|
|
auto normY = std::holds_alternative<std::monostate>(y) ? normX
|
|
: std::holds_alternative<CSSNumber>(y)
|
|
? std::get<CSSNumber>(y).value
|
|
: std::get<CSSPercentage>(y).value / 100.0f;
|
|
return CSSScale{normX, normY};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSScale>);
|
|
struct CSSScaleX {
|
|
float value{};
|
|
constexpr bool operator==(const CSSScaleX& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSScaleX>
|
|
: public detail::CSSNumberPercentTransformParser<CSSScaleX, "scaleX"> {};
|
|
static_assert(CSSDataType<CSSScaleX>);
|
|
struct CSSScaleY {
|
|
float value{};
|
|
constexpr bool operator==(const CSSScaleY& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSScaleY>
|
|
: public detail::CSSNumberPercentTransformParser<CSSScaleY, "scaleY"> {};
|
|
static_assert(CSSDataType<CSSScaleY>);
|
|
struct CSSRotate {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSRotate& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSRotate>
|
|
: public detail::CSSAngleTransformParser<CSSRotate, "rotate"> {};
|
|
static_assert(CSSDataType<CSSRotate>);
|
|
struct CSSRotateX {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSRotateX& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSRotateX>
|
|
: public detail::CSSAngleTransformParser<CSSRotateX, "rotateX"> {};
|
|
static_assert(CSSDataType<CSSRotateX>);
|
|
struct CSSRotateY {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSRotateY& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSRotateY>
|
|
: public detail::CSSAngleTransformParser<CSSRotateY, "rotateY"> {};
|
|
static_assert(CSSDataType<CSSRotateY>);
|
|
struct CSSRotateZ {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSRotateZ& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSRotateZ>
|
|
: public detail::CSSAngleTransformParser<CSSRotateZ, "rotateZ"> {};
|
|
static_assert(CSSDataType<CSSRotateZ>);
|
|
struct CSSSkewX {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSSkewX& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSSkewX>
|
|
: public detail::CSSAngleTransformParser<CSSSkewX, "skewX"> {};
|
|
static_assert(CSSDataType<CSSSkewX>);
|
|
struct CSSSkewY {
|
|
float degrees{};
|
|
constexpr bool operator==(const CSSSkewY& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSSkewY>
|
|
: public detail::CSSAngleTransformParser<CSSSkewY, "skewY"> {};
|
|
static_assert(CSSDataType<CSSSkewY>);
|
|
struct CSSPerspective {
|
|
CSSLength length{};
|
|
constexpr bool operator==(const CSSPerspective& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSPerspective> {
|
|
static constexpr auto consumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& parser) -> std::optional<CSSPerspective> {
|
|
if (!iequals(func.name, "perspective")) {
|
|
return {};
|
|
}
|
|
auto value = parseNextCSSValue<CSSLength>(parser);
|
|
if (std::holds_alternative<std::monostate>(value) ||
|
|
std::get<CSSLength>(value).value < 0) {
|
|
return {};
|
|
}
|
|
return CSSPerspective{
|
|
.length = std::get<CSSLength>(value),
|
|
};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSPerspective>);
|
|
using CSSTransformFunction = CSSCompoundDataType<
|
|
CSSMatrix,
|
|
CSSTranslate,
|
|
CSSTranslateX,
|
|
CSSTranslateY,
|
|
CSSTranslate3D,
|
|
CSSScale,
|
|
CSSScaleX,
|
|
CSSScaleY,
|
|
CSSRotate,
|
|
CSSRotateX,
|
|
CSSRotateY,
|
|
CSSRotateZ,
|
|
CSSSkewX,
|
|
CSSSkewY,
|
|
CSSPerspective>;
|
|
using CSSTransformList = CSSWhitespaceSeparatedList<CSSTransformFunction>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSTransformOrigin.h}:
|
|
namespace facebook::react {
|
|
enum class CSSTransformOriginKeyword : std::underlying_type_t<CSSKeyword> {
|
|
Center = static_cast<std::underlying_type_t<CSSKeyword>>(CSSKeyword::Center),
|
|
Left = static_cast<std::underlying_type_t<CSSKeyword>>(CSSKeyword::Left),
|
|
Right = static_cast<std::underlying_type_t<CSSKeyword>>(CSSKeyword::Right),
|
|
Top = static_cast<std::underlying_type_t<CSSKeyword>>(CSSKeyword::Top),
|
|
Bottom = static_cast<std::underlying_type_t<CSSKeyword>>(CSSKeyword::Bottom),
|
|
};
|
|
static_assert(CSSDataType<CSSTransformOriginKeyword>);
|
|
struct CSSTransformOrigin {
|
|
std::variant<CSSLength, CSSPercentage> x{};
|
|
std::variant<CSSLength, CSSPercentage> y{};
|
|
CSSLength z{};
|
|
constexpr bool operator==(const CSSTransformOrigin& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSTransformOrigin> {
|
|
static constexpr auto consume(CSSSyntaxParser& parser)
|
|
-> std::optional<CSSTransformOrigin> {
|
|
auto firstValue =
|
|
parseNextCSSValue<CSSLengthPercentage, CSSTransformOriginKeyword>(
|
|
parser);
|
|
if (std::holds_alternative<std::monostate>(firstValue)) {
|
|
return {};
|
|
}
|
|
auto secondValue =
|
|
parseNextCSSValue<CSSLengthPercentage, CSSTransformOriginKeyword>(
|
|
parser, CSSDelimiter::Whitespace);
|
|
if (std::holds_alternative<std::monostate>(secondValue)) {
|
|
return singleValue(firstValue);
|
|
}
|
|
auto thirdValue =
|
|
parseNextCSSValue<CSSLength>(parser, CSSDelimiter::Whitespace);
|
|
if (std::holds_alternative<CSSLength>(firstValue) ||
|
|
std::holds_alternative<CSSPercentage>(firstValue) ||
|
|
std::holds_alternative<CSSLength>(secondValue) ||
|
|
std::holds_alternative<CSSPercentage>(secondValue)) {
|
|
return xyLengthPercentageValue(firstValue, secondValue, thirdValue);
|
|
}
|
|
if (std::holds_alternative<CSSTransformOriginKeyword>(firstValue) &&
|
|
std::holds_alternative<CSSTransformOriginKeyword>(secondValue)) {
|
|
return xyKeywordValue(
|
|
std::get<CSSTransformOriginKeyword>(firstValue),
|
|
std::get<CSSTransformOriginKeyword>(secondValue),
|
|
thirdValue);
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
if (std::holds_alternative<CSSLength>(value)) {
|
|
result.x = std::get<CSSLength>(value);
|
|
result.y = keywordPercentage(CSSTransformOriginKeyword::Center);
|
|
} else if (std::holds_alternative<CSSPercentage>(value)) {
|
|
result.x = std::get<CSSPercentage>(value);
|
|
result.y = keywordPercentage(CSSTransformOriginKeyword::Center);
|
|
} else if (std::holds_alternative<CSSTransformOriginKeyword>(value)) {
|
|
if (isHorizontalKeyword(std::get<CSSTransformOriginKeyword>(value))) {
|
|
result.x =
|
|
keywordPercentage(std::get<CSSTransformOriginKeyword>(value));
|
|
result.y = keywordPercentage(CSSTransformOriginKeyword::Center);
|
|
} else {
|
|
result.x = keywordPercentage(CSSTransformOriginKeyword::Center);
|
|
result.y =
|
|
keywordPercentage(std::get<CSSTransformOriginKeyword>(value));
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
static constexpr std::optional<CSSTransformOrigin> xyLengthPercentageValue(
|
|
const std::variant<
|
|
std::monostate,
|
|
CSSLength,
|
|
CSSPercentage,
|
|
CSSTransformOriginKeyword>& val1,
|
|
const std::variant<
|
|
std::monostate,
|
|
CSSLength,
|
|
CSSPercentage,
|
|
CSSTransformOriginKeyword>& val2,
|
|
const std::variant<std::monostate, CSSLength>& val3) {
|
|
CSSTransformOrigin result{};
|
|
if (std::holds_alternative<CSSLength>(val1)) {
|
|
result.x = std::get<CSSLength>(val1);
|
|
} else if (std::holds_alternative<CSSPercentage>(val1)) {
|
|
result.x = std::get<CSSPercentage>(val1);
|
|
} else if (std::holds_alternative<CSSTransformOriginKeyword>(val1)) {
|
|
if (!isHorizontalKeyword(std::get<CSSTransformOriginKeyword>(val1))) {
|
|
return {};
|
|
}
|
|
result.x = keywordPercentage(std::get<CSSTransformOriginKeyword>(val1));
|
|
}
|
|
if (std::holds_alternative<CSSLength>(val2)) {
|
|
result.y = std::get<CSSLength>(val2);
|
|
} else if (std::holds_alternative<CSSPercentage>(val2)) {
|
|
result.y = std::get<CSSPercentage>(val2);
|
|
} else if (std::holds_alternative<CSSTransformOriginKeyword>(val2)) {
|
|
if (!isVerticalKeyword(std::get<CSSTransformOriginKeyword>(val2))) {
|
|
return {};
|
|
}
|
|
result.y = keywordPercentage(std::get<CSSTransformOriginKeyword>(val2));
|
|
}
|
|
if (std::holds_alternative<CSSLength>(val3)) {
|
|
result.z = std::get<CSSLength>(val3);
|
|
}
|
|
return result;
|
|
}
|
|
static constexpr std::optional<CSSTransformOrigin> xyKeywordValue(
|
|
CSSTransformOriginKeyword val1,
|
|
CSSTransformOriginKeyword val2,
|
|
const std::variant<std::monostate, CSSLength>& val3) {
|
|
if (isHorizontalKeyword(val1) && isVerticalKeyword(val2)) {
|
|
return CSSTransformOrigin{
|
|
.x = keywordPercentage(val1),
|
|
.y = keywordPercentage(val2),
|
|
.z = std::holds_alternative<CSSLength>(val3)
|
|
? std::get<CSSLength>(val3)
|
|
: CSSLength{}};
|
|
}
|
|
if (isVerticalKeyword(val1) && isHorizontalKeyword(val2)) {
|
|
return CSSTransformOrigin{
|
|
.x = keywordPercentage(val2),
|
|
.y = keywordPercentage(val1),
|
|
.z = std::holds_alternative<CSSLength>(val3)
|
|
? std::get<CSSLength>(val3)
|
|
: CSSLength{}};
|
|
}
|
|
return {};
|
|
}
|
|
static constexpr bool isHorizontalKeyword(CSSTransformOriginKeyword keyword) {
|
|
return keyword == CSSTransformOriginKeyword::Left ||
|
|
keyword == CSSTransformOriginKeyword::Center ||
|
|
keyword == CSSTransformOriginKeyword::Right;
|
|
}
|
|
static constexpr bool isVerticalKeyword(CSSTransformOriginKeyword keyword) {
|
|
return keyword == CSSTransformOriginKeyword::Top ||
|
|
keyword == CSSTransformOriginKeyword::Center ||
|
|
keyword == CSSTransformOriginKeyword::Bottom;
|
|
}
|
|
static constexpr CSSPercentage keywordPercentage(
|
|
CSSTransformOriginKeyword keyword) {
|
|
switch (keyword) {
|
|
case CSSTransformOriginKeyword::Left:
|
|
return CSSPercentage{0.0f};
|
|
case CSSTransformOriginKeyword::Top:
|
|
return CSSPercentage{0.0f};
|
|
case CSSTransformOriginKeyword::Center:
|
|
return CSSPercentage{50.0f};
|
|
case CSSTransformOriginKeyword::Right:
|
|
return CSSPercentage{100.0f};
|
|
case CSSTransformOriginKeyword::Bottom:
|
|
return CSSPercentage{100.0f};
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSTransformOrigin>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSValueParser.h}:
|
|
namespace facebook::react {
|
|
namespace detail {
|
|
class CSSValueParser {
|
|
public:
|
|
explicit constexpr CSSValueParser(CSSSyntaxParser& parser)
|
|
: parser_{parser} {}
|
|
template <CSSDataType... AllowedTypesT>
|
|
constexpr std::variant<std::monostate, AllowedTypesT...> consumeValue(
|
|
CSSDelimiter delimeter,
|
|
CSSCompoundDataType<AllowedTypesT...>) {
|
|
using ReturnT = std::variant<std::monostate, AllowedTypesT...>;
|
|
auto consumedValue =
|
|
tryConsumeParser<ReturnT, CSSDataTypeParser<AllowedTypesT>...>(
|
|
delimeter);
|
|
if (!std::holds_alternative<std::monostate>(consumedValue)) {
|
|
return consumedValue;
|
|
}
|
|
return parser_.consumeComponentValue<ReturnT>(
|
|
delimeter,
|
|
[&](const CSSPreservedToken& token) {
|
|
return tryConsumePreservedToken<
|
|
ReturnT,
|
|
CSSDataTypeParser<AllowedTypesT>...>(token);
|
|
},
|
|
[&](const CSSSimpleBlock& block, CSSSyntaxParser& blockParser) {
|
|
return tryConsumeSimpleBlock<
|
|
ReturnT,
|
|
CSSDataTypeParser<AllowedTypesT>...>(block, blockParser);
|
|
},
|
|
[&](const CSSFunctionBlock& func, CSSSyntaxParser& blockParser) {
|
|
return tryConsumeFunctionBlock<
|
|
ReturnT,
|
|
CSSDataTypeParser<AllowedTypesT>...>(func, blockParser);
|
|
});
|
|
}
|
|
constexpr bool isFinished() const {
|
|
return parser_.isFinished();
|
|
}
|
|
constexpr void consumeWhitespace() {
|
|
parser_.consumeWhitespace();
|
|
}
|
|
};
|
|
}
|
|
template <
|
|
typename ReturnT,
|
|
CSSValidDataTypeParser ParserT,
|
|
CSSValidDataTypeParser... RestParserT>
|
|
constexpr ReturnT tryConsumePreservedToken(const CSSPreservedToken& token) {
|
|
if constexpr (CSSPreservedTokenSink<ParserT>) {
|
|
if (auto ret = ParserT::consumePreservedToken(token)) {
|
|
return *ret;
|
|
}
|
|
}
|
|
return tryConsumePreservedToken<ReturnT, RestParserT...>(token);
|
|
}
|
|
template <typename ReturnT>
|
|
constexpr ReturnT tryConsumeSimpleBlock(
|
|
const CSSSimpleBlock&,
|
|
CSSSyntaxParser&) {
|
|
return {};
|
|
}
|
|
template <
|
|
typename ReturnT,
|
|
CSSValidDataTypeParser ParserT,
|
|
CSSValidDataTypeParser... RestParserT>
|
|
constexpr ReturnT tryConsumeSimpleBlock(
|
|
const CSSSimpleBlock& block,
|
|
CSSSyntaxParser& blockParser) {
|
|
if constexpr (CSSSimpleBlockSink<ParserT>) {
|
|
auto currentParser = blockParser;
|
|
if (auto ret = ParserT::consumeSimpleBlock(block, blockParser)) {
|
|
return *ret;
|
|
}
|
|
blockParser = currentParser;
|
|
}
|
|
return tryConsumeSimpleBlock<ReturnT, RestParserT...>(block, blockParser);
|
|
}
|
|
template <typename ReturnT>
|
|
constexpr ReturnT tryConsumeFunctionBlock(
|
|
const CSSFunctionBlock&,
|
|
CSSSyntaxParser&) {
|
|
return {};
|
|
}
|
|
template <
|
|
typename ReturnT,
|
|
CSSValidDataTypeParser ParserT,
|
|
CSSValidDataTypeParser... RestParserT>
|
|
constexpr ReturnT tryConsumeFunctionBlock(
|
|
const CSSFunctionBlock& func,
|
|
CSSSyntaxParser& blockParser) {
|
|
if constexpr (CSSFunctionBlockSink<ParserT>) {
|
|
auto currentParser = blockParser;
|
|
if (auto ret = ParserT::consumeFunctionBlock(func, blockParser)) {
|
|
return *ret;
|
|
}
|
|
blockParser = currentParser;
|
|
}
|
|
return tryConsumeFunctionBlock<ReturnT, RestParserT...>(func, blockParser);
|
|
}
|
|
template <typename ReturnT>
|
|
constexpr ReturnT tryConsumeParser(CSSDelimiter) {
|
|
return {};
|
|
}
|
|
template <
|
|
typename ReturnT,
|
|
CSSValidDataTypeParser ParserT,
|
|
CSSValidDataTypeParser... RestParserT>
|
|
constexpr ReturnT tryConsumeParser(CSSDelimiter delimeter) {
|
|
if constexpr (CSSParserSink<ParserT>) {
|
|
auto originalParser = parser_;
|
|
if (parser_.consumeDelimiter(delimeter)) {
|
|
if (auto ret = ParserT::consume(parser_)) {
|
|
return *ret;
|
|
}
|
|
}
|
|
parser_ = originalParser;
|
|
}
|
|
return tryConsumeParser<ReturnT, RestParserT...>(delimeter);
|
|
}
|
|
CSSSyntaxParser& parser_;
|
|
};
|
|
} // namespace detail
|
|
template <CSSMaybeCompoundDataType... AllowedTypesT>
|
|
constexpr auto parseCSSProperty(std::string_view css) -> CSSVariantWithTypes<
|
|
CSSMergedDataTypes<CSSWideKeyword, AllowedTypesT...>,
|
|
std::monostate> {
|
|
CSSSyntaxParser syntaxParser(css);
|
|
detail::CSSValueParser parser(syntaxParser);
|
|
parser.consumeWhitespace();
|
|
auto value = parser.consumeValue(
|
|
CSSDelimiter::None,
|
|
CSSMergedDataTypes<CSSWideKeyword, AllowedTypesT...>{});
|
|
parser.consumeWhitespace();
|
|
if (parser.isFinished()) {
|
|
return value;
|
|
}
|
|
return {};
|
|
};
|
|
template <CSSMaybeCompoundDataType... AllowedTypesT>
|
|
constexpr auto parseNextCSSValue(
|
|
CSSSyntaxParser& syntaxParser,
|
|
CSSDelimiter delimeter = CSSDelimiter::None)
|
|
-> CSSVariantWithTypes<
|
|
CSSMergedDataTypes<AllowedTypesT...>,
|
|
std::monostate> {
|
|
detail::CSSValueParser valueParser(syntaxParser);
|
|
return valueParser.consumeValue(
|
|
delimeter, CSSMergedDataTypes<AllowedTypesT...>{});
|
|
}
|
|
template <CSSMaybeCompoundDataType... AllowedTypesT>
|
|
constexpr auto peekNextCSSValue(
|
|
CSSSyntaxParser& syntaxParser,
|
|
CSSDelimiter delimeter = CSSDelimiter::None)
|
|
-> CSSVariantWithTypes<
|
|
CSSMergedDataTypes<AllowedTypesT...>,
|
|
std::monostate> {
|
|
auto savedParser = syntaxParser;
|
|
detail::CSSValueParser valueParser(syntaxParser);
|
|
auto ret = valueParser.consumeValue(
|
|
delimeter, CSSMergedDataTypes<AllowedTypesT...>{});
|
|
syntaxParser = savedParser;
|
|
return ret;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/css/CSSZero.h}:
|
|
namespace facebook::react {
|
|
struct CSSZero {
|
|
constexpr bool operator==(const CSSZero& rhs) const = default;
|
|
};
|
|
template <>
|
|
struct CSSDataTypeParser<CSSZero> {
|
|
static constexpr auto consumePreservedToken(const CSSPreservedToken& token)
|
|
-> std::optional<CSSZero> {
|
|
if (token.type() == CSSTokenType::Number && token.numericValue() == 0) {
|
|
return CSSZero{};
|
|
}
|
|
return {};
|
|
}
|
|
};
|
|
static_assert(CSSDataType<CSSZero>);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertible.h}:
|
|
namespace facebook::react {
|
|
struct DebugStringConvertibleOptions {};
|
|
class DebugStringConvertible {};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/debug/DebugStringConvertibleItem.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/conversions.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/debug/debugStringConvertibleUtils.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/components/progressbar/android/react/renderer/components/progressbar/conversions.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/debug/flags.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/dom/DOM.h}:
|
|
namespace facebook::react::dom {
|
|
constexpr uint_fast16_t DOCUMENT_POSITION_DISCONNECTED = 1;
|
|
constexpr uint_fast16_t DOCUMENT_POSITION_PRECEDING = 2;
|
|
constexpr uint_fast16_t DOCUMENT_POSITION_FOLLOWING = 4;
|
|
constexpr uint_fast16_t DOCUMENT_POSITION_CONTAINS = 8;
|
|
constexpr uint_fast16_t DOCUMENT_POSITION_CONTAINED_BY = 16;
|
|
struct DOMRect {
|
|
double x = 0;
|
|
double y = 0;
|
|
double width = 0;
|
|
double height = 0;
|
|
};
|
|
struct RNMeasureRect {
|
|
double x = 0;
|
|
double y = 0;
|
|
double width = 0;
|
|
double height = 0;
|
|
double pageX = 0;
|
|
double pageY = 0;
|
|
};
|
|
struct DOMOffset {
|
|
std::shared_ptr<const ShadowNode> offsetParent = nullptr;
|
|
double top = 0;
|
|
double left = 0;
|
|
};
|
|
struct DOMPoint {
|
|
double x = 0;
|
|
double y = 0;
|
|
};
|
|
struct DOMSizeRounded {
|
|
int width = 0;
|
|
int height = 0;
|
|
};
|
|
struct DOMBorderWidthRounded {
|
|
int top = 0;
|
|
int right = 0;
|
|
int bottom = 0;
|
|
int left = 0;
|
|
};
|
|
std::shared_ptr<const ShadowNode> getParentNode(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
std::vector<std::shared_ptr<const ShadowNode>> getChildNodes(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
bool isConnected(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
uint_fast16_t compareDocumentPosition(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode,
|
|
const ShadowNode& otherShadowNode);
|
|
std::string getTextContent(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
DOMRect getBoundingClientRect(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode,
|
|
bool includeTransform);
|
|
DOMOffset getOffset(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
DOMPoint getScrollPosition(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
DOMSizeRounded getScrollSize(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
DOMSizeRounded getInnerSize(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
DOMBorderWidthRounded getBorderWidth(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
std::string getTagName(const ShadowNode& shadowNode);
|
|
RNMeasureRect measure(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
DOMRect measureInWindow(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode);
|
|
std::optional<DOMRect> measureLayout(
|
|
const RootShadowNode::Shared& currentRevision,
|
|
const ShadowNode& shadowNode,
|
|
const ShadowNode& relativeToShadowNode);
|
|
} // namespace facebook::react::dom
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/element/ComponentBuilder.h}:
|
|
namespace facebook::react {
|
|
class ComponentBuilder final {
|
|
public:
|
|
ComponentBuilder(
|
|
ComponentDescriptorRegistry::Shared componentDescriptorRegistry);
|
|
ComponentBuilder(const ComponentBuilder& componentBuilder) = default;
|
|
ComponentBuilder(ComponentBuilder&& componentBuilder) noexcept = default;
|
|
ComponentBuilder& operator=(const ComponentBuilder& other) = default;
|
|
ComponentBuilder& operator=(ComponentBuilder&& other) = default;
|
|
template <typename ShadowNodeT>
|
|
std::shared_ptr<ShadowNodeT> build(Element<ShadowNodeT> element) const {
|
|
return std::static_pointer_cast<ShadowNodeT>(build(element.fragment_));
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/element/Element.h}:
|
|
namespace facebook::react {
|
|
template <typename ShadowNodeT>
|
|
class Element final {
|
|
public:
|
|
using ConcreteProps = typename ShadowNodeT::ConcreteProps;
|
|
using SharedConcreteProps = std::shared_ptr<const ConcreteProps>;
|
|
using ConcreteState = typename ShadowNodeT::ConcreteState;
|
|
using ConcreteStateData = typename ShadowNodeT::ConcreteStateData;
|
|
using SharedConcreteState = std::shared_ptr<const ConcreteState>;
|
|
using ConcreteShadowNode = ShadowNodeT;
|
|
using ConcreteUnsharedShadowNode = std::shared_ptr<ConcreteShadowNode>;
|
|
using ConcreteReferenceCallback =
|
|
std::function<void(const std::shared_ptr<const ShadowNodeT>& shadowNode)>;
|
|
Element() {
|
|
fragment_.componentHandle = ShadowNodeT::Handle();
|
|
fragment_.componentName = ShadowNodeT::Name();
|
|
fragment_.props = ShadowNodeT::defaultSharedProps();
|
|
}
|
|
operator ElementFragment() {
|
|
return fragment_;
|
|
}
|
|
Element& tag(Tag tag) {
|
|
fragment_.tag = tag;
|
|
return *this;
|
|
}
|
|
Element& surfaceId(SurfaceId surfaceId) {
|
|
fragment_.surfaceId = surfaceId;
|
|
return *this;
|
|
}
|
|
Element& props(SharedConcreteProps props) {
|
|
fragment_.props = props;
|
|
return *this;
|
|
}
|
|
Element& props(std::function<SharedConcreteProps()> callback) {
|
|
fragment_.props = callback();
|
|
return *this;
|
|
}
|
|
Element& stateData(std::function<void(ConcreteStateData&)> callback) {
|
|
fragment_.stateCallback =
|
|
[callback = std::move(callback)](
|
|
const State::Shared& state) -> StateData::Shared {
|
|
auto stateData =
|
|
static_cast<const ConcreteState*>(state.get())->getData();
|
|
callback(stateData);
|
|
return std::make_shared<ConcreteStateData>(stateData);
|
|
};
|
|
return *this;
|
|
}
|
|
Element& children(std::vector<ElementFragment> children) {
|
|
auto fragments = ElementFragment::List{};
|
|
fragments.reserve(children.size());
|
|
for (const auto& child : children) {
|
|
fragments.push_back(child);
|
|
}
|
|
fragment_.children = fragments;
|
|
return *this;
|
|
}
|
|
Element& reference(
|
|
std::function<void(const ConcreteUnsharedShadowNode& shadowNode)>
|
|
callback) {
|
|
fragment_.referenceCallback =
|
|
[callback = std::move(callback)](
|
|
const std::shared_ptr<const ShadowNode>& shadowNode) {
|
|
callback(std::const_pointer_cast<ConcreteShadowNode>(
|
|
std::static_pointer_cast<const ConcreteShadowNode>(shadowNode)));
|
|
};
|
|
return *this;
|
|
}
|
|
Element& reference(ConcreteUnsharedShadowNode& outShadowNode) {
|
|
fragment_.referenceCallback =
|
|
[&](const std::shared_ptr<const ShadowNode>& shadowNode) {
|
|
outShadowNode = std::const_pointer_cast<ConcreteShadowNode>(
|
|
std::static_pointer_cast<const ConcreteShadowNode>(shadowNode));
|
|
};
|
|
return *this;
|
|
}
|
|
Element& finalize(
|
|
std::function<void(ConcreteShadowNode& shadowNode)> finalizeCallback) {
|
|
fragment_.finalizeCallback = [=](ShadowNode& shadowNode) {
|
|
return finalizeCallback(static_cast<ConcreteShadowNode&>(shadowNode));
|
|
};
|
|
return *this;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/element/ElementFragment.h}:
|
|
namespace facebook::react {
|
|
class ElementFragment final {
|
|
public:
|
|
using Shared = std::shared_ptr<ElementFragment>;
|
|
using List = std::vector<ElementFragment>;
|
|
using ListOfShared = std::vector<Shared>;
|
|
using ReferenceCallback =
|
|
std::function<void(const std::shared_ptr<ShadowNode>& shadowNode)>;
|
|
using FinalizeCallback = std::function<void(ShadowNode& shadowNode)>;
|
|
using StateCallback =
|
|
std::function<StateData::Shared(const State::Shared& state)>;
|
|
ComponentHandle componentHandle;
|
|
ComponentName componentName;
|
|
Tag tag;
|
|
SurfaceId surfaceId;
|
|
Props::Shared props;
|
|
List children;
|
|
ReferenceCallback referenceCallback;
|
|
FinalizeCallback finalizeCallback;
|
|
StateCallback stateCallback;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/element/testUtils.h}:
|
|
namespace facebook::react {
|
|
inline ComponentBuilder simpleComponentBuilder(
|
|
std::shared_ptr<const ContextContainer> contextContainer = nullptr) {
|
|
ComponentDescriptorProviderRegistry componentDescriptorProviderRegistry{};
|
|
auto eventDispatcher = EventDispatcher::Shared{};
|
|
auto componentDescriptorRegistry =
|
|
componentDescriptorProviderRegistry.createComponentDescriptorRegistry(
|
|
ComponentDescriptorParameters{
|
|
eventDispatcher, std::move(contextContainer), nullptr});
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<RootComponentDescriptor>());
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<ViewComponentDescriptor>());
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<ScrollViewComponentDescriptor>());
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<ParagraphComponentDescriptor>());
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<TextComponentDescriptor>());
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<RawTextComponentDescriptor>());
|
|
componentDescriptorProviderRegistry.add(
|
|
concreteComponentDescriptorProvider<ModalHostViewComponentDescriptor>());
|
|
return ComponentBuilder{componentDescriptorRegistry};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/BackgroundImage.h}:
|
|
namespace facebook::react {
|
|
using BackgroundImage = std::variant<LinearGradient, RadialGradient>;
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/BlendMode.h}:
|
|
namespace facebook::react {
|
|
enum class BlendMode {
|
|
Normal,
|
|
Multiply,
|
|
Screen,
|
|
Overlay,
|
|
Darken,
|
|
Lighten,
|
|
ColorDodge,
|
|
ColorBurn,
|
|
HardLight,
|
|
SoftLight,
|
|
Difference,
|
|
Exclusion,
|
|
Hue,
|
|
Saturation,
|
|
Color,
|
|
Luminosity,
|
|
};
|
|
inline std::optional<BlendMode> blendModeFromString(
|
|
std::string_view blendModeName) {
|
|
if (blendModeName == "normal") {
|
|
return BlendMode::Normal;
|
|
} else if (blendModeName == "multiply") {
|
|
return BlendMode::Multiply;
|
|
} else if (blendModeName == "screen") {
|
|
return BlendMode::Screen;
|
|
} else if (blendModeName == "overlay") {
|
|
return BlendMode::Overlay;
|
|
} else if (blendModeName == "darken") {
|
|
return BlendMode::Darken;
|
|
} else if (blendModeName == "lighten") {
|
|
return BlendMode::Lighten;
|
|
} else if (blendModeName == "color-dodge") {
|
|
return BlendMode::ColorDodge;
|
|
} else if (blendModeName == "color-burn") {
|
|
return BlendMode::ColorBurn;
|
|
} else if (blendModeName == "hard-light") {
|
|
return BlendMode::HardLight;
|
|
} else if (blendModeName == "soft-light") {
|
|
return BlendMode::SoftLight;
|
|
} else if (blendModeName == "difference") {
|
|
return BlendMode::Difference;
|
|
} else if (blendModeName == "exclusion") {
|
|
return BlendMode::Exclusion;
|
|
} else if (blendModeName == "hue") {
|
|
return BlendMode::Hue;
|
|
} else if (blendModeName == "saturation") {
|
|
return BlendMode::Saturation;
|
|
} else if (blendModeName == "color") {
|
|
return BlendMode::Color;
|
|
} else if (blendModeName == "luminosity") {
|
|
return BlendMode::Luminosity;
|
|
} else {
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
inline std::string toString(const BlendMode& blendMode) {
|
|
switch (blendMode) {
|
|
case BlendMode::Normal:
|
|
return "normal";
|
|
case BlendMode::Multiply:
|
|
return "multiply";
|
|
case BlendMode::Screen:
|
|
return "screen";
|
|
case BlendMode::Overlay:
|
|
return "overlay";
|
|
case BlendMode::Darken:
|
|
return "darken";
|
|
case BlendMode::Lighten:
|
|
return "lighten";
|
|
case BlendMode::ColorDodge:
|
|
return "color-dodge";
|
|
case BlendMode::ColorBurn:
|
|
return "color-burn";
|
|
case BlendMode::HardLight:
|
|
return "hard-light";
|
|
case BlendMode::SoftLight:
|
|
return "soft-light";
|
|
case BlendMode::Difference:
|
|
return "difference";
|
|
case BlendMode::Exclusion:
|
|
return "exclusion";
|
|
case BlendMode::Hue:
|
|
return "hue";
|
|
case BlendMode::Saturation:
|
|
return "saturation";
|
|
case BlendMode::Color:
|
|
return "color";
|
|
case BlendMode::Luminosity:
|
|
return "luminosity";
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/BoxShadow.h}:
|
|
namespace facebook::react {
|
|
struct BoxShadow {
|
|
bool operator==(const BoxShadow& other) const = default;
|
|
Float offsetX{};
|
|
Float offsetY{};
|
|
Float blurRadius{};
|
|
Float spreadDistance{};
|
|
SharedColor color{};
|
|
bool inset{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Color.h}:
|
|
namespace facebook::react {
|
|
class SharedColor {
|
|
public:
|
|
SharedColor() : color_(HostPlatformColor::UndefinedColor) {}
|
|
SharedColor(Color color) : color_(color) {}
|
|
Color& operator*() {
|
|
return color_;
|
|
}
|
|
const Color& operator*() const {
|
|
return color_;
|
|
}
|
|
bool operator==(const SharedColor& otherColor) const {
|
|
return color_ == otherColor.color_;
|
|
}
|
|
bool operator!=(const SharedColor& otherColor) const {
|
|
return color_ != otherColor.color_;
|
|
}
|
|
operator bool() const {
|
|
return color_ != HostPlatformColor::UndefinedColor;
|
|
}
|
|
};
|
|
bool isColorMeaningful(const SharedColor& color) noexcept;
|
|
SharedColor colorFromComponents(ColorComponents components);
|
|
ColorComponents colorComponentsFromColor(SharedColor color);
|
|
uint8_t alphaFromColor(SharedColor color) noexcept;
|
|
uint8_t redFromColor(SharedColor color) noexcept;
|
|
uint8_t greenFromColor(SharedColor color) noexcept;
|
|
uint8_t blueFromColor(SharedColor color) noexcept;
|
|
SharedColor colorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a);
|
|
SharedColor clearColor();
|
|
SharedColor blackColor();
|
|
SharedColor whiteColor();
|
|
} // namespace facebook::react
|
|
template <>
|
|
struct std::hash<facebook::react::SharedColor> {
|
|
size_t operator()(const facebook::react::SharedColor& color) const {
|
|
return std::hash<facebook::react::Color>{}(*color);
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/ColorComponents.h}:
|
|
namespace facebook::react {
|
|
enum class ColorSpace { sRGB, DisplayP3 };
|
|
ColorSpace getDefaultColorSpace();
|
|
void setDefaultColorSpace(ColorSpace newColorSpace);
|
|
struct ColorComponents {
|
|
float red{0};
|
|
float green{0};
|
|
float blue{0};
|
|
float alpha{0};
|
|
ColorSpace colorSpace{getDefaultColorSpace()};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/ColorStop.h}:
|
|
namespace facebook::react {
|
|
struct ColorStop {
|
|
bool operator==(const ColorStop& other) const = default;
|
|
SharedColor color;
|
|
ValueUnit position;
|
|
};
|
|
struct ProcessedColorStop {
|
|
bool operator==(const ProcessedColorStop& other) const = default;
|
|
SharedColor color;
|
|
std::optional<Float> position;
|
|
};
|
|
}; // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Filter.h}:
|
|
namespace facebook::react {
|
|
enum class FilterType {
|
|
Blur,
|
|
Brightness,
|
|
Contrast,
|
|
Grayscale,
|
|
HueRotate,
|
|
Invert,
|
|
Opacity,
|
|
Saturate,
|
|
Sepia,
|
|
DropShadow
|
|
};
|
|
inline FilterType filterTypeFromString(std::string_view filterName) {
|
|
if (filterName == "blur") {
|
|
return FilterType::Blur;
|
|
} else if (filterName == "brightness") {
|
|
return FilterType::Brightness;
|
|
} else if (filterName == "contrast") {
|
|
return FilterType::Contrast;
|
|
} else if (filterName == "grayscale") {
|
|
return FilterType::Grayscale;
|
|
} else if (filterName == "hueRotate") {
|
|
return FilterType::HueRotate;
|
|
} else if (filterName == "invert") {
|
|
return FilterType::Invert;
|
|
} else if (filterName == "opacity") {
|
|
return FilterType::Opacity;
|
|
} else if (filterName == "saturate") {
|
|
return FilterType::Saturate;
|
|
} else if (filterName == "sepia") {
|
|
return FilterType::Sepia;
|
|
} else if (filterName == "dropShadow") {
|
|
return FilterType::DropShadow;
|
|
} else {
|
|
throw std::invalid_argument(std::string(filterName));
|
|
}
|
|
}
|
|
inline std::string toString(const FilterType& filterType) {
|
|
switch (filterType) {
|
|
case FilterType::Blur:
|
|
return "blur";
|
|
case FilterType::Brightness:
|
|
return "brightness";
|
|
case FilterType::Contrast:
|
|
return "contrast";
|
|
case FilterType::Grayscale:
|
|
return "grayscale";
|
|
case FilterType::HueRotate:
|
|
return "hueRotate";
|
|
case FilterType::Invert:
|
|
return "invert";
|
|
case FilterType::Opacity:
|
|
return "opacity";
|
|
case FilterType::Saturate:
|
|
return "saturate";
|
|
case FilterType::Sepia:
|
|
return "sepia";
|
|
case FilterType::DropShadow:
|
|
return "dropShadow";
|
|
}
|
|
}
|
|
struct DropShadowParams {
|
|
bool operator==(const DropShadowParams& other) const = default;
|
|
Float offsetX{};
|
|
Float offsetY{};
|
|
Float standardDeviation{};
|
|
SharedColor color{};
|
|
};
|
|
struct FilterFunction {
|
|
bool operator==(const FilterFunction& other) const = default;
|
|
FilterType type{};
|
|
std::variant<Float, DropShadowParams> parameters{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Geometry.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Isolation.h}:
|
|
namespace facebook::react {
|
|
enum class Isolation {
|
|
Auto,
|
|
Isolate,
|
|
};
|
|
inline std::optional<Isolation> isolationFromString(
|
|
std::string_view isolationSetting) {
|
|
if (isolationSetting == "auto") {
|
|
return Isolation::Auto;
|
|
} else if (isolationSetting == "isolate") {
|
|
return Isolation::Isolate;
|
|
} else {
|
|
return std::nullopt;
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/LinearGradient.h}:
|
|
namespace facebook::react {
|
|
enum class GradientDirectionType { Angle, Keyword };
|
|
enum class GradientKeyword {
|
|
ToTopRight,
|
|
ToBottomRight,
|
|
ToTopLeft,
|
|
ToBottomLeft,
|
|
};
|
|
struct GradientDirection {
|
|
GradientDirectionType type;
|
|
std::variant<Float, GradientKeyword> value;
|
|
bool operator==(const GradientDirection& other) const {
|
|
return type == other.type && value == other.value;
|
|
}
|
|
};
|
|
struct LinearGradient {
|
|
GradientDirection direction;
|
|
std::vector<ColorStop> colorStops;
|
|
bool operator==(const LinearGradient& other) const {
|
|
return direction == other.direction && colorStops == other.colorStops;
|
|
}
|
|
};
|
|
inline GradientKeyword parseGradientKeyword(const std::string& keyword) {
|
|
if (keyword == "to top right")
|
|
return GradientKeyword::ToTopRight;
|
|
if (keyword == "to bottom right")
|
|
return GradientKeyword::ToBottomRight;
|
|
if (keyword == "to top left")
|
|
return GradientKeyword::ToTopLeft;
|
|
if (keyword == "to bottom left")
|
|
return GradientKeyword::ToBottomLeft;
|
|
throw std::invalid_argument("Invalid gradient keyword: " + keyword);
|
|
}
|
|
}; // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Point.h}:
|
|
namespace facebook::react {
|
|
struct Point {
|
|
Float x{0};
|
|
Float y{0};
|
|
inline Point& operator+=(const Point& point) noexcept {
|
|
x += point.x;
|
|
y += point.y;
|
|
return *this;
|
|
}
|
|
inline Point& operator-=(const Point& point) noexcept {
|
|
x -= point.x;
|
|
y -= point.y;
|
|
return *this;
|
|
}
|
|
inline Point& operator*=(const Point& point) noexcept {
|
|
x *= point.x;
|
|
y *= point.y;
|
|
return *this;
|
|
}
|
|
inline Point operator+(const Point& rhs) const noexcept {
|
|
return {
|
|
.x = this->x + rhs.x,
|
|
.y = this->y + rhs.y,
|
|
};
|
|
}
|
|
inline Point operator-(const Point& rhs) const noexcept {
|
|
return {
|
|
.x = this->x - rhs.x,
|
|
.y = this->y - rhs.y,
|
|
};
|
|
}
|
|
inline Point operator-() const noexcept {
|
|
return {
|
|
.x = -x,
|
|
.y = -y,
|
|
};
|
|
}
|
|
inline bool operator==(const Point& rhs) const = default;
|
|
inline bool operator!=(const Point& rhs) const = default;
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::Point> {
|
|
inline size_t operator()(const facebook::react::Point& point) const noexcept {
|
|
return facebook::react::hash_combine(point.x, point.y);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/RadialGradient.h}:
|
|
namespace facebook::react {
|
|
enum class RadialGradientShape { Circle, Ellipse };
|
|
struct RadialGradientSize {
|
|
enum class SizeKeyword {
|
|
ClosestSide,
|
|
FarthestSide,
|
|
ClosestCorner,
|
|
FarthestCorner
|
|
};
|
|
struct Dimensions {
|
|
ValueUnit x;
|
|
ValueUnit y;
|
|
bool operator==(const Dimensions& other) const {
|
|
return x == other.x && y == other.y;
|
|
}
|
|
bool operator!=(const Dimensions& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
std::variant<SizeKeyword, Dimensions> value;
|
|
bool operator==(const RadialGradientSize& other) const {
|
|
if (std::holds_alternative<SizeKeyword>(value) &&
|
|
std::holds_alternative<SizeKeyword>(other.value)) {
|
|
return std::get<SizeKeyword>(value) == std::get<SizeKeyword>(other.value);
|
|
} else if (
|
|
std::holds_alternative<Dimensions>(value) &&
|
|
std::holds_alternative<Dimensions>(other.value)) {
|
|
return std::get<Dimensions>(value) == std::get<Dimensions>(other.value);
|
|
}
|
|
return false;
|
|
}
|
|
bool operator!=(const RadialGradientSize& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
struct RadialGradientPosition {
|
|
std::optional<ValueUnit> top;
|
|
std::optional<ValueUnit> left;
|
|
std::optional<ValueUnit> right;
|
|
std::optional<ValueUnit> bottom;
|
|
bool operator==(const RadialGradientPosition& other) const {
|
|
return top == other.top && left == other.left && right == other.right &&
|
|
bottom == other.bottom;
|
|
}
|
|
bool operator!=(const RadialGradientPosition& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
struct RadialGradient {
|
|
RadialGradientShape shape;
|
|
RadialGradientSize size;
|
|
RadialGradientPosition position;
|
|
std::vector<ColorStop> colorStops;
|
|
bool operator==(const RadialGradient& other) const {
|
|
return shape == other.shape && size == other.size &&
|
|
position == other.position && colorStops == other.colorStops;
|
|
}
|
|
bool operator!=(const RadialGradient& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
}; // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Rect.h}:
|
|
namespace facebook::react {
|
|
struct Rect {
|
|
Point origin{0, 0};
|
|
Size size{0, 0};
|
|
bool operator==(const Rect& rhs) const noexcept {
|
|
return std::tie(this->origin, this->size) == std::tie(rhs.origin, rhs.size);
|
|
}
|
|
bool operator!=(const Rect& rhs) const noexcept {
|
|
return !(*this == rhs);
|
|
}
|
|
Float getMaxX() const noexcept {
|
|
return size.width > 0 ? origin.x + size.width : origin.x;
|
|
}
|
|
Float getMaxY() const noexcept {
|
|
return size.height > 0 ? origin.y + size.height : origin.y;
|
|
}
|
|
Float getMinX() const noexcept {
|
|
return size.width >= 0 ? origin.x : origin.x + size.width;
|
|
}
|
|
Float getMinY() const noexcept {
|
|
return size.height >= 0 ? origin.y : origin.y + size.height;
|
|
}
|
|
Float getMidX() const noexcept {
|
|
return origin.x + size.width / 2;
|
|
}
|
|
Float getMidY() const noexcept {
|
|
return origin.y + size.height / 2;
|
|
}
|
|
Point getCenter() const noexcept {
|
|
return {getMidX(), getMidY()};
|
|
}
|
|
void unionInPlace(const Rect& rect) noexcept {
|
|
auto x1 = std::min(getMinX(), rect.getMinX());
|
|
auto y1 = std::min(getMinY(), rect.getMinY());
|
|
auto x2 = std::max(getMaxX(), rect.getMaxX());
|
|
auto y2 = std::max(getMaxY(), rect.getMaxY());
|
|
origin = {x1, y1};
|
|
size = {x2 - x1, y2 - y1};
|
|
}
|
|
bool containsPoint(Point point) noexcept {
|
|
return point.x >= origin.x && point.y >= origin.y &&
|
|
point.x <= (origin.x + size.width) &&
|
|
point.y <= (origin.y + size.height);
|
|
}
|
|
static Rect intersect(const Rect& rect1, const Rect& rect2) {
|
|
Float x1 = std::max(rect1.origin.x, rect2.origin.x);
|
|
Float y1 = std::max(rect1.origin.y, rect2.origin.y);
|
|
Float x2 = std::min(
|
|
rect1.origin.x + rect1.size.width, rect2.origin.x + rect2.size.width);
|
|
Float y2 = std::min(
|
|
rect1.origin.y + rect1.size.height, rect2.origin.y + rect2.size.height);
|
|
Float intersectionWidth = x2 - x1;
|
|
Float intersectionHeight = y2 - y1;
|
|
if (intersectionWidth < 0 || intersectionHeight < 0) {
|
|
return {};
|
|
}
|
|
return {{x1, y1}, {intersectionWidth, intersectionHeight}};
|
|
}
|
|
static Rect boundingRect(
|
|
const Point& a,
|
|
const Point& b,
|
|
const Point& c,
|
|
const Point& d) noexcept {
|
|
auto leftTopPoint = a;
|
|
auto rightBottomPoint = a;
|
|
leftTopPoint.x = std::min(leftTopPoint.x, b.x);
|
|
leftTopPoint.x = std::min(leftTopPoint.x, c.x);
|
|
leftTopPoint.x = std::min(leftTopPoint.x, d.x);
|
|
leftTopPoint.y = std::min(leftTopPoint.y, b.y);
|
|
leftTopPoint.y = std::min(leftTopPoint.y, c.y);
|
|
leftTopPoint.y = std::min(leftTopPoint.y, d.y);
|
|
rightBottomPoint.x = std::max(rightBottomPoint.x, b.x);
|
|
rightBottomPoint.x = std::max(rightBottomPoint.x, c.x);
|
|
rightBottomPoint.x = std::max(rightBottomPoint.x, d.x);
|
|
rightBottomPoint.y = std::max(rightBottomPoint.y, b.y);
|
|
rightBottomPoint.y = std::max(rightBottomPoint.y, c.y);
|
|
rightBottomPoint.y = std::max(rightBottomPoint.y, d.y);
|
|
return {
|
|
leftTopPoint,
|
|
{rightBottomPoint.x - leftTopPoint.x,
|
|
rightBottomPoint.y - leftTopPoint.y}};
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::Rect> {
|
|
size_t operator()(const facebook::react::Rect& rect) const noexcept {
|
|
return facebook::react::hash_combine(rect.origin, rect.size);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/RectangleCorners.h}:
|
|
namespace facebook::react {
|
|
template <typename T>
|
|
struct RectangleCorners {
|
|
T topLeft{};
|
|
T topRight{};
|
|
T bottomLeft{};
|
|
T bottomRight{};
|
|
bool operator==(const RectangleCorners<T>& rhs) const noexcept {
|
|
return std::tie(
|
|
this->topLeft,
|
|
this->topRight,
|
|
this->bottomLeft,
|
|
this->bottomRight) ==
|
|
std::tie(rhs.topLeft, rhs.topRight, rhs.bottomLeft, rhs.bottomRight);
|
|
}
|
|
bool operator!=(const RectangleCorners<T>& rhs) const noexcept {
|
|
return !(*this == rhs);
|
|
}
|
|
bool isUniform() const noexcept {
|
|
return topLeft == topRight && topLeft == bottomLeft &&
|
|
topLeft == bottomRight;
|
|
}
|
|
};
|
|
using CornerInsets = RectangleCorners<Float>;
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <typename T>
|
|
struct hash<facebook::react::RectangleCorners<T>> {
|
|
size_t operator()(
|
|
const facebook::react::RectangleCorners<T>& corners) const noexcept {
|
|
return facebook::react::hash_combine(
|
|
corners.topLeft,
|
|
corners.bottomLeft,
|
|
corners.topRight,
|
|
corners.bottomRight);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/RectangleEdges.h}:
|
|
namespace facebook::react {
|
|
template <typename T>
|
|
struct RectangleEdges {
|
|
T left{};
|
|
T top{};
|
|
T right{};
|
|
T bottom{};
|
|
bool operator==(const RectangleEdges<T>& rhs) const noexcept {
|
|
return std::tie(this->left, this->top, this->right, this->bottom) ==
|
|
std::tie(rhs.left, rhs.top, rhs.right, rhs.bottom);
|
|
}
|
|
bool operator!=(const RectangleEdges<T>& rhs) const noexcept {
|
|
return !(*this == rhs);
|
|
}
|
|
bool isUniform() const noexcept {
|
|
return left == top && left == right && left == bottom;
|
|
}
|
|
static const RectangleEdges<T> ZERO;
|
|
};
|
|
template <typename T>
|
|
const RectangleEdges<T> RectangleEdges<T>::ZERO = {};
|
|
template <typename T>
|
|
RectangleEdges<T> operator+(
|
|
const RectangleEdges<T>& lhs,
|
|
const RectangleEdges<T>& rhs) noexcept {
|
|
return RectangleEdges<T>{
|
|
lhs.left + rhs.left,
|
|
lhs.top + rhs.top,
|
|
lhs.right + rhs.right,
|
|
lhs.bottom + rhs.bottom};
|
|
}
|
|
template <typename T>
|
|
RectangleEdges<T> operator-(
|
|
const RectangleEdges<T>& lhs,
|
|
const RectangleEdges<T>& rhs) noexcept {
|
|
return RectangleEdges<T>{
|
|
lhs.left - rhs.left,
|
|
lhs.top - rhs.top,
|
|
lhs.right - rhs.right,
|
|
lhs.bottom - rhs.bottom};
|
|
}
|
|
using EdgeInsets = RectangleEdges<Float>;
|
|
inline Rect insetBy(const Rect& rect, const EdgeInsets& insets) noexcept {
|
|
return Rect{
|
|
{rect.origin.x + insets.left, rect.origin.y + insets.top},
|
|
{rect.size.width - insets.left - insets.right,
|
|
rect.size.height - insets.top - insets.bottom}};
|
|
}
|
|
inline Rect outsetBy(const Rect& rect, const EdgeInsets& outsets) noexcept {
|
|
return Rect{
|
|
{rect.origin.x - outsets.left, rect.origin.y - outsets.top},
|
|
{rect.size.width + outsets.left + outsets.right,
|
|
rect.size.height + outsets.top + outsets.bottom}};
|
|
}
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <typename T>
|
|
struct hash<facebook::react::RectangleEdges<T>> {
|
|
size_t operator()(
|
|
const facebook::react::RectangleEdges<T>& edges) const noexcept {
|
|
return facebook::react::hash_combine(
|
|
edges.left, edges.right, edges.top, edges.bottom);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Size.h}:
|
|
namespace facebook::react {
|
|
struct Size {
|
|
Float width{0};
|
|
Float height{0};
|
|
Size& operator+=(const Point& point) noexcept {
|
|
width += point.x;
|
|
height += point.y;
|
|
return *this;
|
|
}
|
|
Size& operator*=(const Point& point) noexcept {
|
|
width *= point.x;
|
|
height *= point.y;
|
|
return *this;
|
|
}
|
|
};
|
|
inline bool operator==(const Size& rhs, const Size& lhs) noexcept {
|
|
return std::tie(lhs.width, lhs.height) == std::tie(rhs.width, rhs.height);
|
|
}
|
|
inline bool operator!=(const Size& rhs, const Size& lhs) noexcept {
|
|
return !(lhs == rhs);
|
|
}
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::Size> {
|
|
size_t operator()(const facebook::react::Size& size) const {
|
|
return facebook::react::hash_combine(size.width, size.height);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Transform.h}:
|
|
namespace facebook::react {
|
|
inline bool isZero(Float n) {
|
|
return (n < 0 ? n * (-1) : n) < 0.00001;
|
|
}
|
|
enum class TransformOperationType : uint8_t {
|
|
Arbitrary,
|
|
Identity,
|
|
Perspective,
|
|
Scale,
|
|
Translate,
|
|
Rotate,
|
|
Skew
|
|
};
|
|
struct TransformOperation {
|
|
TransformOperationType type;
|
|
ValueUnit x;
|
|
ValueUnit y;
|
|
ValueUnit z;
|
|
bool operator==(const TransformOperation& other) const = default;
|
|
};
|
|
struct TransformOrigin {
|
|
std::array<ValueUnit, 2> xy = {
|
|
ValueUnit(0.0f, UnitType::Undefined),
|
|
ValueUnit(0.0f, UnitType::Undefined)};
|
|
float z = 0.0f;
|
|
bool operator==(const TransformOrigin& other) const {
|
|
return xy[0] == other.xy[0] && xy[1] == other.xy[1] && z == other.z;
|
|
}
|
|
bool operator!=(const TransformOrigin& other) const {
|
|
return !(*this == other);
|
|
}
|
|
bool isSet() const {
|
|
return xy[0].value != 0.0f || xy[0].unit != UnitType::Undefined ||
|
|
xy[1].value != 0.0f || xy[1].unit != UnitType::Undefined || z != 0.0f;
|
|
}
|
|
};
|
|
struct Transform {
|
|
std::vector<TransformOperation> operations{};
|
|
std::array<Float, 16> matrix{
|
|
{1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1}};
|
|
static Transform FromTransformOperation(
|
|
TransformOperation transformOperation,
|
|
const Size& size,
|
|
const Transform& transform = Transform::Identity());
|
|
static TransformOperation DefaultTransformOperation(
|
|
TransformOperationType type);
|
|
static Transform Identity() noexcept;
|
|
static Transform VerticalInversion() noexcept;
|
|
static Transform HorizontalInversion() noexcept;
|
|
static Transform Perspective(Float perspective) noexcept;
|
|
static Transform Scale(Float factorX, Float factorY, Float factorZ) noexcept;
|
|
static Transform Translate(Float x, Float y, Float z) noexcept;
|
|
static Transform Skew(Float x, Float y) noexcept;
|
|
static Transform RotateX(Float radians) noexcept;
|
|
static Transform RotateY(Float radians) noexcept;
|
|
static Transform RotateZ(Float radians) noexcept;
|
|
static Transform Rotate(Float angleX, Float angleY, Float angleZ) noexcept;
|
|
static Transform Interpolate(
|
|
Float animationProgress,
|
|
const Transform& lhs,
|
|
const Transform& rhs,
|
|
const Size& size);
|
|
static bool isVerticalInversion(const Transform& transform) noexcept;
|
|
static bool isHorizontalInversion(const Transform& transform) noexcept;
|
|
bool operator==(const Transform& rhs) const noexcept;
|
|
bool operator!=(const Transform& rhs) const noexcept;
|
|
Float& at(int i, int j) noexcept;
|
|
const Float& at(int i, int j) const noexcept;
|
|
Transform operator*(const Transform& rhs) const;
|
|
Rect applyWithCenter(const Rect& rect, const Point& center) const;
|
|
};
|
|
Point operator*(const Point& point, const Transform& transform);
|
|
Size operator*(const Size& size, const Transform& transform);
|
|
Rect operator*(const Rect& rect, const Transform& transform);
|
|
EdgeInsets operator*(const EdgeInsets& edgeInsets, const Transform& transform);
|
|
Vector operator*(const Transform& transform, const Vector& vector);
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::Transform> {
|
|
size_t operator()(const facebook::react::Transform& transform) const {
|
|
return facebook::react::hash_combine(
|
|
transform.matrix[0],
|
|
transform.matrix[1],
|
|
transform.matrix[2],
|
|
transform.matrix[3],
|
|
transform.matrix[4],
|
|
transform.matrix[5],
|
|
transform.matrix[6],
|
|
transform.matrix[7],
|
|
transform.matrix[8],
|
|
transform.matrix[9],
|
|
transform.matrix[10],
|
|
transform.matrix[11],
|
|
transform.matrix[12],
|
|
transform.matrix[13],
|
|
transform.matrix[14],
|
|
transform.matrix[15]);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/ValueUnit.h}:
|
|
namespace facebook::react {
|
|
enum class UnitType {
|
|
Undefined,
|
|
Point,
|
|
Percent,
|
|
};
|
|
struct ValueUnit {
|
|
float value{0.0f};
|
|
UnitType unit{UnitType::Undefined};
|
|
ValueUnit() = default;
|
|
ValueUnit(float v, UnitType u) : value(v), unit(u) {}
|
|
bool operator==(const ValueUnit& other) const {
|
|
return value == other.value && unit == other.unit;
|
|
}
|
|
bool operator!=(const ValueUnit& other) const {
|
|
return !(*this == other);
|
|
}
|
|
constexpr float resolve(float referenceLength) const {
|
|
switch (unit) {
|
|
case UnitType::Point:
|
|
return value;
|
|
case UnitType::Percent:
|
|
return value * referenceLength * 0.01f;
|
|
case UnitType::Undefined:
|
|
return 0.0f;
|
|
}
|
|
return 0.0f;
|
|
}
|
|
constexpr operator bool() const {
|
|
return unit != UnitType::Undefined;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/Vector.h}:
|
|
namespace facebook::react {
|
|
struct Vector {
|
|
Float x{0};
|
|
Float y{0};
|
|
Float z{0};
|
|
Float w{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/conversions.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/fromRawValueShared.h}:
|
|
namespace facebook::react {
|
|
using parsePlatformColorFn =
|
|
SharedColor (*)(const ContextContainer&, int32_t, const RawValue&);
|
|
inline void fromRawValueShared(
|
|
const ContextContainer& contextContainer,
|
|
int32_t surfaceId,
|
|
const RawValue& value,
|
|
SharedColor& result,
|
|
parsePlatformColorFn parsePlatformColor) {
|
|
ColorComponents colorComponents = {0, 0, 0, 0};
|
|
if (value.hasType<int>()) {
|
|
auto argb = (int64_t)value;
|
|
auto ratio = 255.f;
|
|
colorComponents.alpha = ((argb >> 24) & 0xFF) / ratio;
|
|
colorComponents.red = ((argb >> 16) & 0xFF) / ratio;
|
|
colorComponents.green = ((argb >> 8) & 0xFF) / ratio;
|
|
colorComponents.blue = (argb & 0xFF) / ratio;
|
|
result = colorFromComponents(colorComponents);
|
|
} else if (value.hasType<std::vector<float>>()) {
|
|
auto items = (std::vector<float>)value;
|
|
auto length = items.size();
|
|
react_native_expect(length == 3 || length == 4);
|
|
colorComponents.red = items.at(0);
|
|
colorComponents.green = items.at(1);
|
|
colorComponents.blue = items.at(2);
|
|
colorComponents.alpha = length == 4 ? items.at(3) : 1.0f;
|
|
result = colorFromComponents(colorComponents);
|
|
} else {
|
|
if (value.hasType<std::unordered_map<std::string, RawValue>>()) {
|
|
const auto& items = (std::unordered_map<std::string, RawValue>)value;
|
|
if (items.find("space") != items.end()) {
|
|
colorComponents.red = (float)items.at("r");
|
|
colorComponents.green = (float)items.at("g");
|
|
colorComponents.blue = (float)items.at("b");
|
|
colorComponents.alpha = (float)items.at("a");
|
|
colorComponents.colorSpace = getDefaultColorSpace();
|
|
std::string space = (std::string)items.at("space");
|
|
if (space == "display-p3") {
|
|
colorComponents.colorSpace = ColorSpace::DisplayP3;
|
|
} else if (space == "srgb") {
|
|
colorComponents.colorSpace = ColorSpace::sRGB;
|
|
}
|
|
result = colorFromComponents(colorComponents);
|
|
return;
|
|
}
|
|
}
|
|
result = parsePlatformColor(contextContainer, surfaceId, value);
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Float.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/HostPlatformColor.h}:
|
|
namespace facebook::react {
|
|
using Color = int32_t;
|
|
namespace HostPlatformColor {
|
|
constexpr facebook::react::Color UndefinedColor = 0;
|
|
}
|
|
inline Color
|
|
hostPlatformColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
|
return (a & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);
|
|
}
|
|
inline Color hostPlatformColorFromComponents(ColorComponents components) {
|
|
float ratio = 255;
|
|
return ((int)round(components.alpha * ratio) & 0xff) << 24 |
|
|
((int)round(components.red * ratio) & 0xff) << 16 |
|
|
((int)round(components.green * ratio) & 0xff) << 8 |
|
|
((int)round(components.blue * ratio) & 0xff);
|
|
}
|
|
inline ColorComponents colorComponentsFromHostPlatformColor(Color color) {
|
|
float ratio = 255;
|
|
return ColorComponents{
|
|
(float)((color >> 16) & 0xff) / ratio,
|
|
(float)((color >> 8) & 0xff) / ratio,
|
|
(float)((color >> 0) & 0xff) / ratio,
|
|
(float)((color >> 24) & 0xff) / ratio};
|
|
}
|
|
inline float alphaFromHostPlatformColor(Color color) {
|
|
return static_cast<float>((color >> 24) & 0xff);
|
|
}
|
|
inline float redFromHostPlatformColor(Color color) {
|
|
return static_cast<float>((color >> 16) & 0xff);
|
|
}
|
|
inline float greenFromHostPlatformColor(Color color) {
|
|
return static_cast<float>((color >> 8) & 0xff);
|
|
}
|
|
inline float blueFromHostPlatformColor(Color color) {
|
|
return static_cast<uint8_t>((color >> 0) & 0xff);
|
|
}
|
|
inline bool hostPlatformColorIsColorMeaningful(Color color) noexcept {
|
|
return alphaFromHostPlatformColor(color) > 0;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/PlatformColorParser.h}:
|
|
namespace facebook::react {
|
|
inline SharedColor parsePlatformColor(
|
|
const ContextContainer& contextContainer,
|
|
int32_t surfaceId,
|
|
const RawValue& value) {
|
|
ColorComponents colorComponents = {0, 0, 0, 0};
|
|
if (value.hasType<
|
|
std::unordered_map<std::string, std::vector<std::string>>>()) {
|
|
const auto& fabricUIManager =
|
|
contextContainer.at<jni::global_ref<jobject>>("FabricUIManager");
|
|
static auto getColorFromJava =
|
|
fabricUIManager->getClass()
|
|
->getMethod<jint(jint, jni::JArrayClass<jni::JString>)>("getColor");
|
|
auto map = (std::unordered_map<std::string, std::vector<std::string>>)value;
|
|
auto& resourcePaths = map["resource_paths"];
|
|
auto javaResourcePaths =
|
|
jni::JArrayClass<jni::JString>::newArray(resourcePaths.size());
|
|
for (int i = 0; i < resourcePaths.size(); i++) {
|
|
javaResourcePaths->setElement(i, *jni::make_jstring(resourcePaths[i]));
|
|
}
|
|
auto color =
|
|
getColorFromJava(fabricUIManager, surfaceId, *javaResourcePaths);
|
|
auto argb = (int64_t)color;
|
|
auto ratio = 255.f;
|
|
colorComponents.alpha = ((argb >> 24) & 0xFF) / ratio;
|
|
colorComponents.red = ((argb >> 16) & 0xFF) / ratio;
|
|
colorComponents.green = ((argb >> 8) & 0xFF) / ratio;
|
|
colorComponents.blue = (argb & 0xFF) / ratio;
|
|
}
|
|
return {colorFromComponents(colorComponents)};
|
|
}
|
|
inline void fromRawValue(
|
|
const ContextContainer& contextContainer,
|
|
int32_t surfaceId,
|
|
const RawValue& value,
|
|
SharedColor& result) {
|
|
fromRawValueShared(
|
|
contextContainer, surfaceId, value, result, parsePlatformColor);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/Float.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/HostPlatformColor.h}:
|
|
namespace facebook::react {
|
|
using Color = int32_t;
|
|
namespace HostPlatformColor {
|
|
constexpr facebook::react::Color UndefinedColor = 0;
|
|
}
|
|
inline Color
|
|
hostPlatformColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
|
return (a & 0xff) << 24 | (r & 0xff) << 16 | (g & 0xff) << 8 | (b & 0xff);
|
|
}
|
|
inline Color hostPlatformColorFromComponents(ColorComponents components) {
|
|
float ratio = 255;
|
|
return hostPlatformColorFromRGBA(
|
|
static_cast<uint8_t>(std::round(components.red * ratio)),
|
|
static_cast<uint8_t>(std::round(components.green * ratio)),
|
|
static_cast<uint8_t>(std::round(components.blue * ratio)),
|
|
static_cast<uint8_t>(std::round(components.alpha * ratio)));
|
|
}
|
|
inline float alphaFromHostPlatformColor(Color color) {
|
|
return static_cast<float>((color >> 24) & 0xff);
|
|
}
|
|
inline float redFromHostPlatformColor(Color color) {
|
|
return static_cast<float>((color >> 16) & 0xff);
|
|
}
|
|
inline float greenFromHostPlatformColor(Color color) {
|
|
return static_cast<float>((color >> 8) & 0xff);
|
|
}
|
|
inline float blueFromHostPlatformColor(Color color) {
|
|
return static_cast<uint8_t>((color >> 0) & 0xff);
|
|
}
|
|
inline bool hostPlatformColorIsColorMeaningful(Color color) noexcept {
|
|
return alphaFromHostPlatformColor(color) > 0;
|
|
}
|
|
inline ColorComponents colorComponentsFromHostPlatformColor(Color color) {
|
|
float ratio = 255;
|
|
return ColorComponents{
|
|
static_cast<float>(redFromHostPlatformColor(color)) / ratio,
|
|
static_cast<float>(greenFromHostPlatformColor(color)) / ratio,
|
|
static_cast<float>(blueFromHostPlatformColor(color)) / ratio,
|
|
static_cast<float>(alphaFromHostPlatformColor(color)) / ratio};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/cxx/react/renderer/graphics/PlatformColorParser.h}:
|
|
namespace facebook::react {
|
|
inline SharedColor
|
|
parsePlatformColor(const ContextContainer&, int32_t, const RawValue&) {
|
|
float alpha = 0;
|
|
float red = 0;
|
|
float green = 0;
|
|
float blue = 0;
|
|
return {colorFromComponents({red, green, blue, alpha})};
|
|
}
|
|
inline void fromRawValue(
|
|
const ContextContainer& contextContainer,
|
|
int32_t surfaceId,
|
|
const RawValue& value,
|
|
SharedColor& result) {
|
|
fromRawValueShared(
|
|
contextContainer, surfaceId, value, result, parsePlatformColor);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/Float.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/macos/react/renderer/graphics/Float.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/HostPlatformColor.h}:
|
|
namespace facebook::react {
|
|
struct DynamicColor {
|
|
int32_t lightColor = 0;
|
|
int32_t darkColor = 0;
|
|
int32_t highContrastLightColor = 0;
|
|
int32_t highContrastDarkColor = 0;
|
|
};
|
|
struct Color {
|
|
Color(int32_t color);
|
|
Color(const DynamicColor& dynamicColor);
|
|
Color(const ColorComponents& components);
|
|
Color() : uiColor_(nullptr) {};
|
|
int32_t getColor() const;
|
|
std::size_t getUIColorHash() const;
|
|
static Color createSemanticColor(std::vector<std::string>& semanticItems);
|
|
std::shared_ptr<void> getUIColor() const {
|
|
return uiColor_;
|
|
}
|
|
float getChannel(int channelId) const;
|
|
ColorComponents getColorComponents() const {
|
|
float ratio = 255;
|
|
int32_t primitiveColor = getColor();
|
|
return ColorComponents{
|
|
(float)((primitiveColor >> 16) & 0xff) / ratio,
|
|
(float)((primitiveColor >> 8) & 0xff) / ratio,
|
|
(float)((primitiveColor >> 0) & 0xff) / ratio,
|
|
(float)((primitiveColor >> 24) & 0xff) / ratio};
|
|
}
|
|
bool operator==(const Color& other) const;
|
|
bool operator!=(const Color& other) const;
|
|
operator int32_t() const {
|
|
return getColor();
|
|
}
|
|
};
|
|
namespace HostPlatformColor {
|
|
[[clang::no_destroy]] static const facebook::react::Color UndefinedColor =
|
|
Color();
|
|
}
|
|
inline Color
|
|
hostPlatformColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
|
float ratio = 255;
|
|
const auto colorComponents = ColorComponents{
|
|
.red = r / ratio,
|
|
.green = g / ratio,
|
|
.blue = b / ratio,
|
|
.alpha = a / ratio,
|
|
};
|
|
return Color(colorComponents);
|
|
}
|
|
inline Color hostPlatformColorFromComponents(ColorComponents components) {
|
|
return Color(components);
|
|
}
|
|
inline ColorComponents colorComponentsFromHostPlatformColor(Color color) {
|
|
return color.getColorComponents();
|
|
}
|
|
inline float alphaFromHostPlatformColor(Color color) {
|
|
return color.getChannel(3) * 255;
|
|
}
|
|
inline float redFromHostPlatformColor(Color color) {
|
|
return color.getChannel(0) * 255;
|
|
}
|
|
inline float greenFromHostPlatformColor(Color color) {
|
|
return color.getChannel(1) * 255;
|
|
}
|
|
inline float blueFromHostPlatformColor(Color color) {
|
|
return color.getChannel(2) * 255;
|
|
}
|
|
inline bool hostPlatformColorIsColorMeaningful(Color color) noexcept {
|
|
return alphaFromHostPlatformColor(color) > 0;
|
|
}
|
|
} // namespace facebook::react
|
|
template <>
|
|
struct std::hash<facebook::react::Color> {
|
|
size_t operator()(const facebook::react::Color& color) const {
|
|
return color.getUIColorHash();
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/macos/react/renderer/graphics/PlatformColorParser.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/RCTPlatformColorUtils.h}:
|
|
namespace facebook::react {
|
|
} // namespace facebook::react
|
|
facebook::react::ColorComponents RCTPlatformColorComponentsFromSemanticItems(
|
|
std::vector<std::string>& semanticItems);
|
|
UIColor* RCTPlatformColorFromSemanticItems(
|
|
std::vector<std::string>& semanticItems);
|
|
UIColor* RCTPlatformColorFromColor(const facebook::react::Color& color);
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/macos/react/renderer/graphics/Float.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/Float.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/macos/react/renderer/graphics/HostPlatformColor.h}:
|
|
namespace facebook::react {
|
|
struct DynamicColor {
|
|
int32_t lightColor = 0;
|
|
int32_t darkColor = 0;
|
|
int32_t highContrastLightColor = 0;
|
|
int32_t highContrastDarkColor = 0;
|
|
};
|
|
struct Color {
|
|
Color(int32_t color);
|
|
Color(const DynamicColor& dynamicColor);
|
|
Color(const ColorComponents& components);
|
|
Color(std::shared_ptr<void> uiColor);
|
|
int32_t getColor() const;
|
|
std::shared_ptr<void> getUIColor() const {
|
|
return uiColor_;
|
|
}
|
|
float getChannel(int channelId) const;
|
|
ColorComponents getColorComponents() const {
|
|
float ratio = 255;
|
|
int32_t primitiveColor = getColor();
|
|
return ColorComponents{
|
|
(float)((primitiveColor >> 16) & 0xff) / ratio,
|
|
(float)((primitiveColor >> 8) & 0xff) / ratio,
|
|
(float)((primitiveColor >> 0) & 0xff) / ratio,
|
|
(float)((primitiveColor >> 24) & 0xff) / ratio};
|
|
}
|
|
bool operator==(const Color& other) const;
|
|
bool operator!=(const Color& other) const;
|
|
operator int32_t() const {
|
|
return getColor();
|
|
}
|
|
};
|
|
namespace HostPlatformColor {
|
|
[[clang::no_destroy]] static const facebook::react::Color UndefinedColor =
|
|
Color(nullptr);
|
|
}
|
|
inline Color
|
|
hostPlatformColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
|
float ratio = 255;
|
|
const auto colorComponents = ColorComponents{
|
|
.red = r / ratio,
|
|
.green = g / ratio,
|
|
.blue = b / ratio,
|
|
.alpha = a / ratio,
|
|
};
|
|
return Color(colorComponents);
|
|
}
|
|
inline Color hostPlatformColorFromComponents(ColorComponents components) {
|
|
return Color(components);
|
|
}
|
|
inline ColorComponents colorComponentsFromHostPlatformColor(Color color) {
|
|
return color.getColorComponents();
|
|
}
|
|
inline float alphaFromHostPlatformColor(Color color) {
|
|
return color.getChannel(3) * 255;
|
|
}
|
|
inline float redFromHostPlatformColor(Color color) {
|
|
return color.getChannel(0) * 255;
|
|
}
|
|
inline float greenFromHostPlatformColor(Color color) {
|
|
return color.getChannel(1) * 255;
|
|
}
|
|
inline float blueFromHostPlatformColor(Color color) {
|
|
return color.getChannel(2) * 255;
|
|
}
|
|
inline bool hostPlatformColorIsColorMeaningful(Color color) noexcept {
|
|
return alphaFromHostPlatformColor(color) > 0;
|
|
}
|
|
} // namespace facebook::react
|
|
template <>
|
|
struct std::hash<facebook::react::Color> {
|
|
size_t operator()(const facebook::react::Color& color) const {
|
|
auto seed = size_t{0};
|
|
facebook::react::hash_combine(seed, color.getColor());
|
|
return seed;
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/macos/react/renderer/graphics/PlatformColorParser.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/ios/react/renderer/graphics/PlatformColorParser.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/macos/react/renderer/graphics/RCTPlatformColorUtils.h}:
|
|
facebook::react::ColorComponents RCTPlatformColorComponentsFromSemanticItems(
|
|
std::vector<std::string>& semanticItems);
|
|
RCTUIColor* RCTPlatformColorFromSemanticItems(
|
|
std::vector<std::string>& semanticItems);
|
|
RCTUIColor* RCTPlatformColorFromColor(const facebook::react::Color& color);
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/windows/third-party/react/renderer/graphics/Float.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/graphics/platform/android/react/renderer/graphics/Float.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/windows/third-party/react/renderer/graphics/HostPlatformColor.h}:
|
|
namespace facebook::react {
|
|
struct Color {
|
|
bool operator==(const Color& otherColor) const {
|
|
return (m_isUndefined && otherColor.m_isUndefined) ||
|
|
(m_isUndefined == otherColor.m_isUndefined &&
|
|
m_color == otherColor.m_color &&
|
|
m_platformColor == otherColor.m_platformColor);
|
|
}
|
|
bool operator!=(const Color& otherColor) const {
|
|
return m_isUndefined != otherColor.m_isUndefined ||
|
|
m_color != otherColor.m_color ||
|
|
m_platformColor != otherColor.m_platformColor;
|
|
}
|
|
Color(int32_t color) {
|
|
m_color = ColorFrom(color);
|
|
}
|
|
Color(const winrt::Windows::UI::Color& color) {
|
|
m_color = color;
|
|
}
|
|
Color() {
|
|
m_isUndefined = true;
|
|
};
|
|
Color(const Color&) = default;
|
|
Color(Color&&) = default;
|
|
~Color() = default;
|
|
winrt::Windows::UI::Color AsWindowsColor() const {
|
|
if (m_platformColor.empty()) {
|
|
return m_color;
|
|
}
|
|
return ResolvePlatformColor(m_platformColor);
|
|
}
|
|
xaml::Media::Brush AsWindowsBrush() const {
|
|
return ResolveColorBrush(m_platformColor, m_color);
|
|
}
|
|
COLORREF AsColorRefNoAlpha() const {
|
|
return RGB(m_color.R, m_color.G, m_color.B);
|
|
}
|
|
COLORREF AsColorRefWithAlpha() const {
|
|
return RGB(m_color.R, m_color.G, m_color.B) | (m_color.A << 24);
|
|
}
|
|
operator int32_t() const {
|
|
const auto resolvedColor = AsWindowsColor();
|
|
return (resolvedColor.A & 0xff) << 24 | (resolvedColor.R & 0xff) << 16 |
|
|
(resolvedColor.G & 0xff) << 8 | (resolvedColor.B & 0xff);
|
|
}
|
|
Color& operator=(const Color&) = default;
|
|
Color& operator=(Color&&) = default;
|
|
bool m_isUndefined{false};
|
|
winrt::Windows::UI::Color m_color{};
|
|
std::vector<std::string> m_platformColor{};
|
|
};
|
|
namespace HostPlatformColor {
|
|
static const facebook::react::Color UndefinedColor{};
|
|
}
|
|
inline Color
|
|
hostPlatformColorFromRGBA(uint8_t r, uint8_t g, uint8_t b, uint8_t a) {
|
|
return winrt::Windows::UI::Color{a, r, g, b};
|
|
}
|
|
inline Color hostPlatformColorFromComponents(ColorComponents components) {
|
|
float ratio = 255;
|
|
return hostPlatformColorFromRGBA(
|
|
static_cast<uint8_t>((int)round(components.red * ratio) & 0xff),
|
|
static_cast<uint8_t>((int)round(components.green * ratio) & 0xff),
|
|
static_cast<uint8_t>((int)round(components.blue * ratio) & 0xff),
|
|
static_cast<uint8_t>((int)round(components.alpha * ratio) & 0xff));
|
|
}
|
|
inline float alphaFromHostPlatformColor(Color color) {
|
|
return color.AsWindowsColor().A;
|
|
}
|
|
inline float redFromHostPlatformColor(Color color) {
|
|
return color.AsWindowsColor().R;
|
|
}
|
|
inline float greenFromHostPlatformColor(Color color) {
|
|
return color.AsWindowsColor().G;
|
|
}
|
|
inline float blueFromHostPlatformColor(Color color) {
|
|
return color.AsWindowsColor().B;
|
|
}
|
|
inline bool hostPlatformColorIsColorMeaningful(Color color) noexcept {
|
|
return alphaFromHostPlatformColor(color) > 0;
|
|
}
|
|
inline ColorComponents colorComponentsFromHostPlatformColor(Color color) {
|
|
float ratio = 255;
|
|
if (color.m_platformColor.empty()) {
|
|
const auto windowsColor = color.AsWindowsColor();
|
|
return ColorComponents{
|
|
(float)windowsColor.R / ratio,
|
|
(float)windowsColor.G / ratio,
|
|
(float)windowsColor.B / ratio,
|
|
(float)windowsColor.A / ratio};
|
|
} else {
|
|
return ColorComponents{1.f, 0.f, 0.f, 1.f};
|
|
}
|
|
}
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::Color> {
|
|
size_t operator()(const facebook::react::Color& color) const {
|
|
size_t h = color.m_color.A + (color.m_color.B << 8) +
|
|
(color.m_color.G << 16) + (color.m_color.R << 24);
|
|
for (auto s : color.m_platformColor) {
|
|
h ^= hash<decltype(s)>{}(s);
|
|
}
|
|
return h;
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/platform/windows/third-party/react/renderer/graphics/PlatformColorParser.h}:
|
|
namespace facebook::react {
|
|
inline SharedColor parsePlatformColor(
|
|
const ContextContainer& contextContainer,
|
|
int32_t surfaceId,
|
|
const RawValue& value) {
|
|
if (value.hasType<
|
|
std::unordered_map<std::string, std::vector<std::string>>>()) {
|
|
auto map = (std::unordered_map<std::string, std::vector<std::string>>)value;
|
|
if (map.find("windowsbrush") != map.end()) {
|
|
facebook::react::Color color;
|
|
color.m_isUndefined = false;
|
|
color.m_platformColor = map["windowsbrush"];
|
|
return color;
|
|
}
|
|
}
|
|
return HostPlatformColor::UndefinedColor;
|
|
}
|
|
inline void fromRawValue(
|
|
const ContextContainer& contextContainer,
|
|
int32_t surfaceId,
|
|
const RawValue& value,
|
|
SharedColor& result) {
|
|
fromRawValueShared(
|
|
contextContainer, surfaceId, value, result, parsePlatformColor);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/graphics/rounding.h}:
|
|
namespace facebook::react {
|
|
template <Float (*RoundingFunction)(Float)>
|
|
Float roundToPixel(Float value, Float scaleFactor) {
|
|
return RoundingFunction(value * scaleFactor) / scaleFactor;
|
|
}
|
|
template <Float (*RoundingFunction)(Float)>
|
|
Point roundToPixel(Point value, Float scaleFactor) {
|
|
return Point{
|
|
roundToPixel<RoundingFunction>(value.x, scaleFactor),
|
|
roundToPixel<RoundingFunction>(value.y, scaleFactor)};
|
|
}
|
|
template <Float (*RoundingFunction)(Float)>
|
|
Size roundToPixel(Size value, Float scaleFactor) {
|
|
return Size{
|
|
roundToPixel<RoundingFunction>(value.width, scaleFactor),
|
|
roundToPixel<RoundingFunction>(value.height, scaleFactor)};
|
|
}
|
|
template <Float (*RoundingFunction)(Float)>
|
|
Rect roundToPixel(Rect value, Float scaleFactor) {
|
|
return Rect{
|
|
roundToPixel<RoundingFunction>(value.origin),
|
|
roundToPixel<RoundingFunction>(value.size)};
|
|
}
|
|
inline float round(float value) noexcept {
|
|
return ::roundf(value);
|
|
}
|
|
inline double round(double value) noexcept {
|
|
return ::round(value);
|
|
}
|
|
inline long double round(long double value) noexcept {
|
|
return ::roundl(value);
|
|
}
|
|
inline float ceil(float value) noexcept {
|
|
return ::ceilf(value);
|
|
}
|
|
inline double ceil(double value) noexcept {
|
|
return ::ceil(value);
|
|
}
|
|
inline long double ceil(long double value) noexcept {
|
|
return ::ceill(value);
|
|
}
|
|
inline float floor(float value) noexcept {
|
|
return ::floorf(value);
|
|
}
|
|
inline double floor(double value) noexcept {
|
|
return ::floor(value);
|
|
}
|
|
inline long double floor(long double value) noexcept {
|
|
return ::floorl(value);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/ImageManager.h}:
|
|
namespace facebook::react {
|
|
class ImageManager {
|
|
public:
|
|
ImageManager(const std::shared_ptr<const ContextContainer>& contextContainer);
|
|
virtual ~ImageManager();
|
|
virtual ImageRequest requestImage(
|
|
const ImageSource& imageSource,
|
|
SurfaceId surfaceId) const;
|
|
virtual ImageRequest requestImage(
|
|
const ImageSource& imageSource,
|
|
SurfaceId surfaceId,
|
|
const ImageRequestParams& imageRequestParams,
|
|
Tag tag) const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/ImageRequest.h}:
|
|
namespace facebook::react {
|
|
class ImageRequest final {
|
|
public:
|
|
ImageRequest(
|
|
ImageSource imageSource,
|
|
std::shared_ptr<const ImageTelemetry> telemetry,
|
|
SharedFunction<> resumeFunction = {},
|
|
SharedFunction<> cancelationFunction = {});
|
|
ImageRequest(ImageRequest&& other) noexcept = default;
|
|
ImageRequest& operator=(ImageRequest&& other) noexcept = default;
|
|
ImageRequest(const ImageRequest& other) = delete;
|
|
ImageRequest& operator=(const ImageRequest& other) = delete;
|
|
~ImageRequest() = default;
|
|
const ImageSource& getImageSource() const;
|
|
const std::shared_ptr<const ImageResponseObserverCoordinator>&
|
|
getSharedObserverCoordinator() const;
|
|
const ImageResponseObserverCoordinator& getObserverCoordinator() const;
|
|
const std::shared_ptr<const ImageTelemetry>& getSharedTelemetry() const;
|
|
};
|
|
std::shared_ptr<const ImageResponseObserverCoordinator> coordinator_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponse.h}:
|
|
namespace facebook::react {
|
|
class ImageResponse final {
|
|
public:
|
|
enum class Status {
|
|
Loading,
|
|
Completed,
|
|
Failed,
|
|
Cancelled,
|
|
Consumed,
|
|
};
|
|
ImageResponse(std::shared_ptr<void> image, std::shared_ptr<void> metadata);
|
|
std::shared_ptr<void> getImage() const;
|
|
std::shared_ptr<void> getMetadata() const;
|
|
};
|
|
std::shared_ptr<void> metadata_{};
|
|
};
|
|
class ImageLoadError {
|
|
public:
|
|
explicit ImageLoadError(std::shared_ptr<void> error);
|
|
std::shared_ptr<void> getError() const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserver.h}:
|
|
namespace facebook::react {
|
|
class ImageResponseObserver {
|
|
public:
|
|
virtual ~ImageResponseObserver() noexcept = default;
|
|
virtual void didReceiveProgress(float progress, int64_t loaded, int64_t total)
|
|
const = 0;
|
|
virtual void didReceiveImage(const ImageResponse& imageResponse) const = 0;
|
|
virtual void didReceiveFailure(const ImageLoadError& error) const = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/ImageResponseObserverCoordinator.h}:
|
|
namespace facebook::react {
|
|
class ImageResponseObserverCoordinator {
|
|
public:
|
|
ImageResponseObserverCoordinator(
|
|
SharedFunction<> resumeFunction,
|
|
SharedFunction<> cancelationFunction);
|
|
void addObserver(const ImageResponseObserver& observer) const;
|
|
void removeObserver(const ImageResponseObserver& observer) const;
|
|
void nativeImageResponseProgress(
|
|
float progress,
|
|
int64_t loaded,
|
|
int64_t total) const;
|
|
void nativeImageResponseComplete(const ImageResponse& imageResponse) const;
|
|
void nativeImageResponseFailed(const ImageLoadError& loadError) const;
|
|
};
|
|
mutable std::shared_ptr<void> imageData_;
|
|
mutable std::shared_ptr<void> imageMetadata_;
|
|
mutable std::shared_ptr<void> imageErrorData_;
|
|
mutable std::mutex mutex_;
|
|
SharedFunction<> resumeRequest_;
|
|
SharedFunction<> cancelRequest_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/ImageTelemetry.h}:
|
|
namespace facebook::react {
|
|
class ImageTelemetry final {
|
|
public:
|
|
ImageTelemetry(const SurfaceId surfaceId) : surfaceId_(surfaceId) {
|
|
willRequestUrlTime_ = telemetryTimePointNow();
|
|
}
|
|
TelemetryTimePoint getWillRequestUrlTime() const;
|
|
SurfaceId getSurfaceId() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageFetcher.h}:
|
|
namespace facebook::react {
|
|
class ImageFetcher {
|
|
public:
|
|
ImageFetcher(std::shared_ptr<const ContextContainer> contextContainer)
|
|
: contextContainer_(std::move(contextContainer)) {}
|
|
ImageRequest requestImage(
|
|
const ImageSource& imageSource,
|
|
const ImageRequestParams& imageRequestParams,
|
|
SurfaceId surfaceId,
|
|
Tag tag) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/ImageRequestParams.h}:
|
|
namespace facebook::react {
|
|
class ImageRequestParams {
|
|
public:
|
|
ImageRequestParams() = default;
|
|
ImageRequestParams(
|
|
Float blurRadius,
|
|
ImageSource defaultSource,
|
|
ImageResizeMode resizeMode,
|
|
std::string resizeMethod,
|
|
Float resizeMultiplier,
|
|
bool shouldNotifyLoadEvents,
|
|
SharedColor overlayColor,
|
|
SharedColor tintColor,
|
|
Float fadeDuration,
|
|
bool progressiveRenderingEnabled,
|
|
ImageSource loadingIndicatorSource,
|
|
std::string analyticTag)
|
|
: blurRadius(blurRadius),
|
|
defaultSource(std::move(defaultSource)),
|
|
resizeMode(resizeMode),
|
|
resizeMethod(std::move(resizeMethod)),
|
|
resizeMultiplier(resizeMultiplier),
|
|
shouldNotifyLoadEvents(shouldNotifyLoadEvents),
|
|
overlayColor(overlayColor),
|
|
tintColor(tintColor),
|
|
fadeDuration(fadeDuration),
|
|
progressiveRenderingEnabled(progressiveRenderingEnabled),
|
|
loadingIndicatorSource(std::move(loadingIndicatorSource)),
|
|
analyticTag(std::move(analyticTag)) {}
|
|
Float blurRadius{};
|
|
ImageSource defaultSource{};
|
|
ImageResizeMode resizeMode{ImageResizeMode::Stretch};
|
|
std::string resizeMethod{};
|
|
Float resizeMultiplier{};
|
|
bool shouldNotifyLoadEvents{};
|
|
SharedColor overlayColor{};
|
|
SharedColor tintColor{};
|
|
Float fadeDuration{};
|
|
bool progressiveRenderingEnabled{};
|
|
ImageSource loadingIndicatorSource{};
|
|
std::string analyticTag{};
|
|
bool operator==(const ImageRequestParams& rhs) const {
|
|
return std::tie(
|
|
this->blurRadius,
|
|
this->defaultSource,
|
|
this->resizeMode,
|
|
this->resizeMethod,
|
|
this->resizeMultiplier,
|
|
this->shouldNotifyLoadEvents,
|
|
this->overlayColor,
|
|
this->tintColor,
|
|
this->fadeDuration,
|
|
this->progressiveRenderingEnabled,
|
|
this->loadingIndicatorSource,
|
|
this->analyticTag) ==
|
|
std::tie(
|
|
rhs.blurRadius,
|
|
rhs.defaultSource,
|
|
rhs.resizeMode,
|
|
rhs.resizeMethod,
|
|
rhs.resizeMultiplier,
|
|
rhs.shouldNotifyLoadEvents,
|
|
rhs.overlayColor,
|
|
rhs.tintColor,
|
|
rhs.fadeDuration,
|
|
rhs.progressiveRenderingEnabled,
|
|
rhs.loadingIndicatorSource,
|
|
rhs.analyticTag);
|
|
}
|
|
bool operator!=(const ImageRequestParams& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/android/react/renderer/imagemanager/conversions.h}:
|
|
namespace facebook::react {
|
|
namespace {
|
|
inline std::string toString(const ImageResizeMode& value) {
|
|
switch (value) {
|
|
case ImageResizeMode::Cover:
|
|
return "cover";
|
|
case ImageResizeMode::Contain:
|
|
return "contain";
|
|
case ImageResizeMode::Stretch:
|
|
return "stretch";
|
|
case ImageResizeMode::Center:
|
|
return "center";
|
|
case ImageResizeMode::Repeat:
|
|
return "repeat";
|
|
case ImageResizeMode::None:
|
|
return "none";
|
|
}
|
|
}
|
|
constexpr MapBuffer::Key IS_KEY_URI = 0;
|
|
constexpr MapBuffer::Key IS_KEY_DEFAULT_SRC = 1;
|
|
constexpr MapBuffer::Key IS_KEY_RESIZE_MODE = 2;
|
|
constexpr MapBuffer::Key IS_KEY_RESIZE_METHOD = 3;
|
|
constexpr MapBuffer::Key IS_KEY_BLUR_RADIUS = 4;
|
|
constexpr MapBuffer::Key IS_KEY_VIEW_WIDTH = 5;
|
|
constexpr MapBuffer::Key IS_KEY_VIEW_HEIGHT = 6;
|
|
constexpr MapBuffer::Key IS_KEY_RESIZE_MULTIPLIER = 7;
|
|
constexpr MapBuffer::Key IS_KEY_SHOULD_NOTIFY_LOAD_EVENTS = 8;
|
|
constexpr MapBuffer::Key IS_KEY_OVERLAY_COLOR = 9;
|
|
constexpr MapBuffer::Key IS_KEY_TINT_COLOR = 10;
|
|
constexpr MapBuffer::Key IS_KEY_FADE_DURATION = 11;
|
|
constexpr MapBuffer::Key IS_KEY_PROGRESSIVE_RENDERING_ENABLED = 12;
|
|
constexpr MapBuffer::Key IS_KEY_LOADING_INDICATOR_SRC = 13;
|
|
constexpr MapBuffer::Key IS_KEY_ANALYTIC_TAG = 14;
|
|
inline void serializeImageSource(
|
|
MapBufferBuilder& builder,
|
|
const ImageSource& imageSource) {
|
|
builder.putString(IS_KEY_URI, imageSource.uri);
|
|
builder.putDouble(IS_KEY_VIEW_WIDTH, imageSource.size.width);
|
|
builder.putDouble(IS_KEY_VIEW_HEIGHT, imageSource.size.height);
|
|
}
|
|
inline void serializeImageRequestParams(
|
|
MapBufferBuilder& builder,
|
|
const ImageRequestParams& imageRequestParams) {
|
|
builder.putString(IS_KEY_DEFAULT_SRC, imageRequestParams.defaultSource.uri);
|
|
builder.putString(
|
|
IS_KEY_RESIZE_MODE, toString(imageRequestParams.resizeMode));
|
|
builder.putString(IS_KEY_RESIZE_METHOD, imageRequestParams.resizeMethod);
|
|
builder.putDouble(IS_KEY_BLUR_RADIUS, imageRequestParams.blurRadius);
|
|
builder.putDouble(
|
|
IS_KEY_RESIZE_MULTIPLIER, imageRequestParams.resizeMultiplier);
|
|
builder.putBool(
|
|
IS_KEY_SHOULD_NOTIFY_LOAD_EVENTS,
|
|
imageRequestParams.shouldNotifyLoadEvents);
|
|
if (isColorMeaningful(imageRequestParams.overlayColor)) {
|
|
builder.putInt(
|
|
IS_KEY_OVERLAY_COLOR, toAndroidRepr(imageRequestParams.overlayColor));
|
|
}
|
|
if (isColorMeaningful(imageRequestParams.tintColor)) {
|
|
builder.putInt(
|
|
IS_KEY_TINT_COLOR, toAndroidRepr(imageRequestParams.tintColor));
|
|
}
|
|
builder.putDouble(IS_KEY_FADE_DURATION, imageRequestParams.fadeDuration);
|
|
builder.putBool(
|
|
IS_KEY_PROGRESSIVE_RENDERING_ENABLED,
|
|
imageRequestParams.progressiveRenderingEnabled);
|
|
builder.putString(
|
|
IS_KEY_LOADING_INDICATOR_SRC,
|
|
imageRequestParams.loadingIndicatorSource.uri);
|
|
builder.putString(IS_KEY_ANALYTIC_TAG, imageRequestParams.analyticTag);
|
|
}
|
|
} // namespace
|
|
inline MapBuffer serializeImageRequest(
|
|
const ImageSource& imageSource,
|
|
const ImageRequestParams& imageRequestParams) {
|
|
auto builder = MapBufferBuilder();
|
|
serializeImageSource(builder, imageSource);
|
|
serializeImageRequestParams(builder, imageRequestParams);
|
|
return builder.build();
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/cxx/react/renderer/imagemanager/ImageRequestParams.h}:
|
|
namespace facebook::react {
|
|
class ImageRequestParams {
|
|
public:
|
|
ImageRequestParams() = default;
|
|
explicit ImageRequestParams(Float blurRadius) : blurRadius(blurRadius) {}
|
|
Float blurRadius{};
|
|
bool operator==(const ImageRequestParams& rhs) const {
|
|
return this->blurRadius == rhs.blurRadius;
|
|
}
|
|
bool operator!=(const ImageRequestParams& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequestParams.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/ImageRequestParams.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTImageManager : NSObject <RCTImageManagerProtocol>
|
|
- (instancetype)initWithImageLoader:(id<RCTImageLoaderWithAttributionProtocol>)imageLoader;
|
|
- (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource
|
|
surfaceId:(facebook::react::SurfaceId)surfaceId;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/RCTImageManagerProtocol.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImagePrimitivesConversions.h}:
|
|
inline static UIViewContentMode RCTContentModeFromImageResizeMode(facebook::react::ImageResizeMode imageResizeMode)
|
|
{
|
|
switch (imageResizeMode) {
|
|
case facebook::react::ImageResizeMode::Cover:
|
|
return UIViewContentModeScaleAspectFill;
|
|
case facebook::react::ImageResizeMode::Contain:
|
|
return UIViewContentModeScaleAspectFit;
|
|
case facebook::react::ImageResizeMode::Stretch:
|
|
return UIViewContentModeScaleToFill;
|
|
case facebook::react::ImageResizeMode::Center:
|
|
return UIViewContentModeCenter;
|
|
case facebook::react::ImageResizeMode::Repeat:
|
|
return UIViewContentModeScaleToFill;
|
|
case facebook::react::ImageResizeMode::None:
|
|
return UIViewContentModeTopLeft;
|
|
}
|
|
}
|
|
inline std::string toString(const facebook::react::ImageResizeMode &value)
|
|
{
|
|
switch (value) {
|
|
case facebook::react::ImageResizeMode::Cover:
|
|
return "cover";
|
|
case facebook::react::ImageResizeMode::Contain:
|
|
return "contain";
|
|
case facebook::react::ImageResizeMode::Stretch:
|
|
return "stretch";
|
|
case facebook::react::ImageResizeMode::Center:
|
|
return "center";
|
|
case facebook::react::ImageResizeMode::Repeat:
|
|
return "repeat";
|
|
case facebook::react::ImageResizeMode::None:
|
|
return "none";
|
|
}
|
|
}
|
|
inline static NSURLRequestCachePolicy NSURLRequestCachePolicyFromImageSource(
|
|
const facebook::react::ImageSource &imageSource)
|
|
{
|
|
switch (imageSource.cache) {
|
|
case facebook::react::ImageSource::CacheStategy::Reload:
|
|
return NSURLRequestReloadIgnoringLocalCacheData;
|
|
break;
|
|
case facebook::react::ImageSource::CacheStategy::ForceCache:
|
|
return NSURLRequestReturnCacheDataElseLoad;
|
|
break;
|
|
case facebook::react::ImageSource::CacheStategy::OnlyIfCached:
|
|
return NSURLRequestReturnCacheDataDontLoad;
|
|
break;
|
|
default:
|
|
return NSURLRequestUseProtocolCachePolicy;
|
|
break;
|
|
}
|
|
}
|
|
inline static NSURL *NSURLFromImageSource(const facebook::react::ImageSource &imageSource)
|
|
{
|
|
@try {
|
|
NSString *urlString = [NSString stringWithUTF8String:imageSource.uri.c_str()];
|
|
if (!imageSource.bundle.empty()) {
|
|
NSString *bundle = [NSString stringWithUTF8String:imageSource.bundle.c_str()];
|
|
urlString = [NSString stringWithFormat:@"%@.bundle/%@", bundle, urlString];
|
|
}
|
|
NSURL *url = [[NSURL alloc] initWithString:urlString];
|
|
if (url.scheme) {
|
|
return url;
|
|
}
|
|
if ([urlString rangeOfString:@":"].location != NSNotFound) {
|
|
urlString =
|
|
[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
|
url = [NSURL URLWithString:urlString];
|
|
return url;
|
|
}
|
|
urlString = [urlString stringByRemovingPercentEncoding];
|
|
if ([urlString hasPrefix:@"~"]) {
|
|
urlString = [urlString stringByExpandingTildeInPath];
|
|
} else {
|
|
if (![urlString isAbsolutePath]) {
|
|
urlString = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:urlString];
|
|
}
|
|
}
|
|
url = [NSURL fileURLWithPath:urlString];
|
|
return url;
|
|
} @catch (__unused NSException *exception) {
|
|
return nil;
|
|
}
|
|
}
|
|
inline static NSURLRequest *NSURLRequestFromImageSource(const facebook::react::ImageSource &imageSource)
|
|
{
|
|
NSURL *url = NSURLFromImageSource(imageSource);
|
|
if (!url) {
|
|
RCTLogError(@"URI parsing error.");
|
|
return nil;
|
|
}
|
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
|
|
NSString *method = @"GET";
|
|
if (!imageSource.method.empty()) {
|
|
method = [[NSString alloc] initWithUTF8String:imageSource.method.c_str()].uppercaseString;
|
|
}
|
|
NSData *body = nil;
|
|
if (!imageSource.body.empty()) {
|
|
body = [NSData dataWithBytes:imageSource.body.c_str() length:imageSource.body.size()];
|
|
}
|
|
NSURLRequestCachePolicy cachePolicy = NSURLRequestCachePolicyFromImageSource(imageSource);
|
|
if ([method isEqualToString:@"GET"] && imageSource.headers.empty() && body == nil &&
|
|
cachePolicy == NSURLRequestUseProtocolCachePolicy) {
|
|
return request;
|
|
}
|
|
for (const auto &header : imageSource.headers) {
|
|
NSString *key = [NSString stringWithUTF8String:header.first.c_str()];
|
|
NSString *value = [NSString stringWithUTF8String:header.second.c_str()];
|
|
if (key != nullptr && value != nullptr) {
|
|
[request setValue:value forHTTPHeaderField:key];
|
|
}
|
|
}
|
|
request.HTTPBody = body;
|
|
request.HTTPMethod = method;
|
|
request.cachePolicy = cachePolicy;
|
|
return request;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTSyncImageManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSyncImageManager : NSObject <RCTImageManagerProtocol>
|
|
- (instancetype)initWithImageLoader:(id<RCTImageLoaderWithAttributionProtocol>)imageLoader;
|
|
- (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource
|
|
surfaceId:(facebook::react::SurfaceId)surfaceId;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/ImageRequestParams.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequestParams.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/RCTImageManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManager.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/RCTImageManagerProtocol.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/RCTImagePrimitivesConversions.h}:
|
|
inline static UIViewContentMode RCTContentModeFromImageResizeMode(facebook::react::ImageResizeMode imageResizeMode)
|
|
{
|
|
switch (imageResizeMode) {
|
|
case facebook::react::ImageResizeMode::Cover:
|
|
return UIViewContentModeScaleAspectFill;
|
|
case facebook::react::ImageResizeMode::Contain:
|
|
return UIViewContentModeScaleAspectFit;
|
|
case facebook::react::ImageResizeMode::Stretch:
|
|
return UIViewContentModeScaleToFill;
|
|
case facebook::react::ImageResizeMode::Center:
|
|
return UIViewContentModeCenter;
|
|
case facebook::react::ImageResizeMode::Repeat:
|
|
return UIViewContentModeScaleToFill;
|
|
case facebook::react::ImageResizeMode::None:
|
|
return UIViewContentModeTopLeft;
|
|
}
|
|
}
|
|
inline std::string toString(const facebook::react::ImageResizeMode &value)
|
|
{
|
|
switch (value) {
|
|
case facebook::react::ImageResizeMode::Cover:
|
|
return "cover";
|
|
case facebook::react::ImageResizeMode::Contain:
|
|
return "contain";
|
|
case facebook::react::ImageResizeMode::Stretch:
|
|
return "stretch";
|
|
case facebook::react::ImageResizeMode::Center:
|
|
return "center";
|
|
case facebook::react::ImageResizeMode::Repeat:
|
|
return "repeat";
|
|
case facebook::react::ImageResizeMode::None:
|
|
return "none";
|
|
}
|
|
}
|
|
inline static NSURLRequestCachePolicy NSURLRequestCachePolicyFromImageSource(
|
|
const facebook::react::ImageSource &imageSource)
|
|
{
|
|
switch (imageSource.cache) {
|
|
case facebook::react::ImageSource::CacheStategy::Reload:
|
|
return NSURLRequestReloadIgnoringLocalCacheData;
|
|
break;
|
|
case facebook::react::ImageSource::CacheStategy::ForceCache:
|
|
return NSURLRequestReturnCacheDataElseLoad;
|
|
break;
|
|
case facebook::react::ImageSource::CacheStategy::OnlyIfCached:
|
|
return NSURLRequestReturnCacheDataDontLoad;
|
|
break;
|
|
default:
|
|
return NSURLRequestUseProtocolCachePolicy;
|
|
break;
|
|
}
|
|
}
|
|
inline static NSURL *NSURLFromImageSource(const facebook::react::ImageSource &imageSource)
|
|
{
|
|
@try {
|
|
NSString *urlString = [NSString stringWithUTF8String:imageSource.uri.c_str()];
|
|
if (!imageSource.bundle.empty()) {
|
|
NSString *bundle = [NSString stringWithUTF8String:imageSource.bundle.c_str()];
|
|
urlString = [NSString stringWithFormat:@"%@.bundle/%@", bundle, urlString];
|
|
}
|
|
NSURL *url = [[NSURL alloc] initWithString:urlString];
|
|
if (url.scheme) {
|
|
return url;
|
|
}
|
|
if ([urlString rangeOfString:@":"].location != NSNotFound) {
|
|
urlString =
|
|
[urlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
|
|
url = [NSURL URLWithString:urlString];
|
|
return url;
|
|
}
|
|
urlString = [urlString stringByRemovingPercentEncoding];
|
|
if ([urlString hasPrefix:@"~"]) {
|
|
urlString = [urlString stringByExpandingTildeInPath];
|
|
} else {
|
|
if (![urlString isAbsolutePath]) {
|
|
urlString = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:urlString];
|
|
}
|
|
}
|
|
url = [NSURL fileURLWithPath:urlString];
|
|
return url;
|
|
} @catch (__unused NSException *exception) {
|
|
return nil;
|
|
}
|
|
}
|
|
inline static NSURLRequest *NSURLRequestFromImageSource(const facebook::react::ImageSource &imageSource)
|
|
{
|
|
NSURL *url = NSURLFromImageSource(imageSource);
|
|
if (!url) {
|
|
RCTLogError(@"URI parsing error.");
|
|
return nil;
|
|
}
|
|
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
|
|
NSString *method = @"GET";
|
|
if (!imageSource.method.empty()) {
|
|
method = [[NSString alloc] initWithUTF8String:imageSource.method.c_str()].uppercaseString;
|
|
}
|
|
NSData *body = nil;
|
|
if (!imageSource.body.empty()) {
|
|
body = [NSData dataWithBytes:imageSource.body.c_str() length:imageSource.body.size()];
|
|
}
|
|
NSURLRequestCachePolicy cachePolicy = NSURLRequestCachePolicyFromImageSource(imageSource);
|
|
if ([method isEqualToString:@"GET"] && imageSource.headers.empty() && body == nil &&
|
|
cachePolicy == NSURLRequestUseProtocolCachePolicy) {
|
|
return request;
|
|
}
|
|
for (const auto &header : imageSource.headers) {
|
|
NSString *key = [NSString stringWithUTF8String:header.first.c_str()];
|
|
NSString *value = [NSString stringWithUTF8String:header.second.c_str()];
|
|
if (key != NULL && value != NULL) {
|
|
[request setValue:value forHTTPHeaderField:key];
|
|
}
|
|
}
|
|
request.HTTPBody = body;
|
|
request.HTTPMethod = method;
|
|
request.cachePolicy = cachePolicy;
|
|
return request;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/macos/react/renderer/imagemanager/RCTSyncImageManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/RCTImageManagerProtocol.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
@interface RCTSyncImageManager : NSObject <RCTImageManagerProtocol>
|
|
- (instancetype)initWithImageLoader:(id<RCTImageLoaderWithAttributionProtocol>)imageLoader;
|
|
- (facebook::react::ImageRequest)requestImage:(facebook::react::ImageSource)imageSource
|
|
surfaceId:(facebook::react::SurfaceId)surfaceId;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/imagemanager/primitives.h}:
|
|
namespace facebook::react {
|
|
class ImageSource {
|
|
public:
|
|
enum class Type { Invalid, Remote, Local };
|
|
enum class CacheStategy { Default, Reload, ForceCache, OnlyIfCached };
|
|
Type type{};
|
|
std::string uri{};
|
|
std::string bundle{};
|
|
Float scale{3};
|
|
Size size{0};
|
|
std::string body{};
|
|
std::string method{};
|
|
CacheStategy cache = CacheStategy::Default;
|
|
std::vector<std::pair<std::string, std::string>> headers{};
|
|
bool operator==(const ImageSource& rhs) const {
|
|
return std::tie(this->type, this->uri) == std::tie(rhs.type, rhs.uri);
|
|
}
|
|
bool operator!=(const ImageSource& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
};
|
|
using ImageSources = std::vector<ImageSource>;
|
|
enum class ImageResizeMode {
|
|
Cover,
|
|
Contain,
|
|
Stretch,
|
|
Center,
|
|
Repeat,
|
|
None,
|
|
};
|
|
class ImageErrorInfo {
|
|
public:
|
|
std::string error{};
|
|
int responseCode{};
|
|
std::vector<std::pair<std::string, std::string>> httpResponseHeaders{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/leakchecker/LeakChecker.h}:
|
|
namespace facebook::react {
|
|
using GarbageCollectionTrigger = std::function<void()>;
|
|
class LeakChecker final {
|
|
public:
|
|
LeakChecker(RuntimeExecutor runtimeExecutor);
|
|
void uiManagerDidCreateShadowNodeFamily(
|
|
const ShadowNodeFamily::Shared& shadowNodeFamily) const;
|
|
void stopSurface(SurfaceId surfaceId);
|
|
};
|
|
WeakFamilyRegistry registry_{};
|
|
SurfaceId previouslyStoppedSurface_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/leakchecker/WeakFamilyRegistry.h}:
|
|
namespace facebook::react {
|
|
class WeakFamilyRegistry final {
|
|
public:
|
|
using WeakFamilies = std::vector<ShadowNodeFamily::Weak>;
|
|
void add(const ShadowNodeFamily::Shared& shadowNodeFamily) const;
|
|
void removeFamiliesWithSurfaceId(SurfaceId surfaceId) const;
|
|
WeakFamilies weakFamiliesForSurfaceId(SurfaceId surfaceId) const;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h}:
|
|
namespace facebook::react {
|
|
class MapBuffer {
|
|
public:
|
|
using Key = uint16_t;
|
|
constexpr static uint16_t HEADER_ALIGNMENT = 0xFE;
|
|
struct Header {
|
|
uint16_t alignment = HEADER_ALIGNMENT;
|
|
uint16_t count;
|
|
uint32_t bufferSize;
|
|
};
|
|
#pragma pack(push, 1)
|
|
struct Bucket {
|
|
Key key;
|
|
uint16_t type;
|
|
uint64_t data;
|
|
Bucket(Key key, uint16_t type, uint64_t data)
|
|
: key(key), type(type), data(data) {}
|
|
};
|
|
#pragma pack(pop)
|
|
static_assert(sizeof(Header) == 8, "MapBuffer header size is incorrect.");
|
|
static_assert(sizeof(Bucket) == 12, "MapBuffer bucket size is incorrect.");
|
|
enum DataType : uint16_t {
|
|
Boolean = 0,
|
|
Int = 1,
|
|
Double = 2,
|
|
String = 3,
|
|
Map = 4,
|
|
Long = 5,
|
|
};
|
|
explicit MapBuffer(std::vector<uint8_t> data);
|
|
MapBuffer(const MapBuffer& buffer) = delete;
|
|
MapBuffer& operator=(const MapBuffer& other) = delete;
|
|
MapBuffer(MapBuffer&& buffer) = default;
|
|
MapBuffer& operator=(MapBuffer&& other) = default;
|
|
int32_t getInt(MapBuffer::Key key) const;
|
|
int64_t getLong(MapBuffer::Key key) const;
|
|
bool getBool(MapBuffer::Key key) const;
|
|
double getDouble(MapBuffer::Key key) const;
|
|
std::string getString(MapBuffer::Key key) const;
|
|
MapBuffer getMapBuffer(MapBuffer::Key key) const;
|
|
std::vector<MapBuffer> getMapBufferList(MapBuffer::Key key) const;
|
|
size_t size() const;
|
|
const uint8_t* data() const;
|
|
uint16_t count() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBuffer.h}
|
|
|
|
namespace facebook::react {
|
|
constexpr uint32_t INITIAL_BUCKETS_SIZE = 10;
|
|
class MapBufferBuilder {
|
|
public:
|
|
MapBufferBuilder(uint32_t initialSize = INITIAL_BUCKETS_SIZE);
|
|
static MapBuffer EMPTY();
|
|
void putInt(MapBuffer::Key key, int32_t value);
|
|
void putLong(MapBuffer::Key key, int64_t value);
|
|
void putBool(MapBuffer::Key key, bool value);
|
|
void putDouble(MapBuffer::Key key, double value);
|
|
void putString(MapBuffer::Key key, const std::string& value);
|
|
void putMapBuffer(MapBuffer::Key key, const MapBuffer& map);
|
|
void putMapBufferList(
|
|
MapBuffer::Key key,
|
|
const std::vector<MapBuffer>& mapBufferList);
|
|
MapBuffer build();
|
|
};
|
|
std::vector<uint8_t> dynamicData_{};
|
|
uint16_t lastKey_{0};
|
|
bool needsSort_{false};
|
|
void storeKeyValue(
|
|
MapBuffer::Key key,
|
|
MapBuffer::DataType type,
|
|
const uint8_t* value,
|
|
uint32_t valueSize);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/Differentiator.h}:
|
|
namespace facebook::react {
|
|
ShadowViewMutation::List calculateShadowViewMutations(
|
|
const ShadowNode& oldRootShadowNode,
|
|
const ShadowNode& newRootShadowNode);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/MountingCoordinator.h}:
|
|
namespace facebook::react {
|
|
class MountingCoordinator final {
|
|
public:
|
|
MountingCoordinator(const ShadowTreeRevision& baseRevision);
|
|
SurfaceId getSurfaceId() const;
|
|
std::optional<MountingTransaction> pullTransaction(
|
|
bool willPerformAsynchronously = false) const;
|
|
void didPerformAsyncTransactions() const;
|
|
bool hasPendingTransactions() const;
|
|
bool waitForTransaction(std::chrono::duration<double> timeout) const;
|
|
const TelemetryController& getTelemetryController() const;
|
|
ShadowTreeRevision getBaseRevision() const;
|
|
|
|
public:
|
|
void updateBaseRevision(const ShadowTreeRevision& baseRevision) const;
|
|
void resetLatestRevision() const;
|
|
void setMountingOverrideDelegate(
|
|
std::weak_ptr<const MountingOverrideDelegate> delegate) const;
|
|
};
|
|
mutable std::optional<ShadowTreeRevision> lastRevision_{};
|
|
mutable MountingTransaction::Number number_{0};
|
|
mutable std::condition_variable signal_;
|
|
mutable std::vector<std::weak_ptr<const MountingOverrideDelegate>>
|
|
mountingOverrideDelegates_;
|
|
TelemetryController telemetryController_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/MountingOverrideDelegate.h}:
|
|
namespace facebook::react {
|
|
class MountingOverrideDelegate {
|
|
public:
|
|
virtual bool shouldOverridePullTransaction() const = 0;
|
|
virtual ~MountingOverrideDelegate() = default;
|
|
virtual std::optional<MountingTransaction> pullTransaction(
|
|
SurfaceId surfaceId,
|
|
MountingTransaction::Number number,
|
|
const TransactionTelemetry& telemetry,
|
|
ShadowViewMutationList mutations) const = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/MountingTransaction.h}:
|
|
namespace facebook::react {
|
|
class MountingTransaction final {
|
|
public:
|
|
using Number = int64_t;
|
|
MountingTransaction(
|
|
SurfaceId surfaceId,
|
|
Number number,
|
|
ShadowViewMutationList&& mutations,
|
|
TransactionTelemetry telemetry);
|
|
explicit MountingTransaction(const MountingTransaction& mountingTransaction) =
|
|
default;
|
|
MountingTransaction& operator=(const MountingTransaction& other) = delete;
|
|
MountingTransaction(MountingTransaction&& mountingTransaction) noexcept =
|
|
default;
|
|
MountingTransaction& operator=(MountingTransaction&& other) = default;
|
|
const ShadowViewMutationList& getMutations() const&;
|
|
ShadowViewMutationList getMutations() &&;
|
|
TransactionTelemetry& getTelemetry() const;
|
|
SurfaceId getSurfaceId() const;
|
|
Number getNumber() const;
|
|
void mergeWith(MountingTransaction&& transaction);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/ShadowTree.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/mounting/MountingOverrideDelegate.h}
|
|
|
|
namespace facebook::react {
|
|
using ShadowTreeCommitTransaction = std::function<RootShadowNode::Unshared(
|
|
const RootShadowNode& oldRootShadowNode)>;
|
|
enum class ShadowTreeCommitStatus {
|
|
Succeeded,
|
|
Failed,
|
|
Cancelled,
|
|
};
|
|
enum class ShadowTreeCommitMode {
|
|
Normal,
|
|
Suspended,
|
|
};
|
|
enum class ShadowTreeCommitSource {
|
|
Unknown,
|
|
React,
|
|
};
|
|
struct ShadowTreeCommitOptions {
|
|
bool enableStateReconciliation{false};
|
|
bool mountSynchronously{true};
|
|
ShadowTreeCommitSource source{ShadowTreeCommitSource::Unknown};
|
|
};
|
|
class ShadowTree final {
|
|
public:
|
|
using Unique = std::unique_ptr<ShadowTree>;
|
|
using CommitStatus = ShadowTreeCommitStatus;
|
|
using CommitMode = ShadowTreeCommitMode;
|
|
using CommitSource = ShadowTreeCommitSource;
|
|
using CommitOptions = ShadowTreeCommitOptions;
|
|
ShadowTree(
|
|
SurfaceId surfaceId,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext,
|
|
const ShadowTreeDelegate& delegate,
|
|
const ContextContainer& contextContainer);
|
|
~ShadowTree();
|
|
SurfaceId getSurfaceId() const;
|
|
void setCommitMode(CommitMode commitMode) const;
|
|
CommitMode getCommitMode() const;
|
|
CommitStatus tryCommit(
|
|
const ShadowTreeCommitTransaction& transaction,
|
|
const CommitOptions& commitOptions,
|
|
bool hasLocked = false) const;
|
|
CommitStatus commit(
|
|
const ShadowTreeCommitTransaction& transaction,
|
|
const CommitOptions& commitOptions) const;
|
|
ShadowTreeRevision getCurrentRevision() const;
|
|
void commitEmptyTree() const;
|
|
void notifyDelegatesOfUpdates() const;
|
|
std::shared_ptr<const MountingCoordinator> getMountingCoordinator() const;
|
|
};
|
|
void mount(ShadowTreeRevision revision, bool mountSynchronously) const;
|
|
void emitLayoutEvents(
|
|
std::vector<const LayoutableShadowNode*>& affectedLayoutableNodes) const;
|
|
const SurfaceId surfaceId_;
|
|
const ShadowTreeDelegate& delegate_;
|
|
mutable std::shared_mutex commitMutex_;
|
|
mutable CommitMode commitMode_{CommitMode::Normal};
|
|
mutable ShadowTreeRevision currentRevision_;
|
|
std::shared_ptr<const MountingCoordinator> mountingCoordinator_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeDelegate.h}:
|
|
namespace facebook::react {
|
|
class ShadowTreeDelegate {
|
|
public:
|
|
virtual RootShadowNode::Unshared shadowTreeWillCommit(
|
|
const ShadowTree& shadowTree,
|
|
const RootShadowNode::Shared& oldRootShadowNode,
|
|
const RootShadowNode::Unshared& newRootShadowNode,
|
|
const ShadowTreeCommitOptions& commitOptions) const = 0;
|
|
virtual void shadowTreeDidFinishTransaction(
|
|
std::shared_ptr<const MountingCoordinator> mountingCoordinator,
|
|
bool mountSynchronously) const = 0;
|
|
virtual ~ShadowTreeDelegate() noexcept = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeRegistry.h}:
|
|
namespace facebook::react {
|
|
class ShadowTreeRegistry final {
|
|
public:
|
|
ShadowTreeRegistry() = default;
|
|
~ShadowTreeRegistry();
|
|
void add(std::unique_ptr<ShadowTree>&& shadowTree) const;
|
|
std::unique_ptr<ShadowTree> remove(SurfaceId surfaceId) const;
|
|
bool visit(
|
|
SurfaceId surfaceId,
|
|
const std::function<void(const ShadowTree& shadowTree)>& callback) const;
|
|
void enumerate(
|
|
const std::function<void(const ShadowTree& shadowTree, bool& stop)>&
|
|
callback) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/ShadowTreeRevision.h}:
|
|
namespace facebook::react {
|
|
class ShadowTreeRevision final {
|
|
public:
|
|
using Number = int64_t;
|
|
friend
|
|
friend
|
|
RootShadowNode::Shared rootShadowNode;
|
|
Number number;
|
|
TransactionTelemetry telemetry;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/ShadowView.h}:
|
|
namespace facebook::react {
|
|
struct ShadowView final {
|
|
ShadowView() = default;
|
|
ShadowView(const ShadowView& shadowView) = default;
|
|
ShadowView(ShadowView&& shadowView) noexcept = default;
|
|
explicit ShadowView(const ShadowNode& shadowNode);
|
|
ShadowView& operator=(const ShadowView& other) = default;
|
|
ShadowView& operator=(ShadowView&& other) = default;
|
|
bool operator==(const ShadowView& rhs) const;
|
|
bool operator!=(const ShadowView& rhs) const;
|
|
ComponentName componentName{};
|
|
ComponentHandle componentHandle{};
|
|
SurfaceId surfaceId{};
|
|
Tag tag{};
|
|
ShadowNodeTraits traits{};
|
|
Props::Shared props{};
|
|
EventEmitter::Shared eventEmitter{};
|
|
LayoutMetrics layoutMetrics{EmptyLayoutMetrics};
|
|
State::Shared state{};
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::ShadowView> {
|
|
size_t operator()(const facebook::react::ShadowView& shadowView) const {
|
|
return facebook::react::hash_combine(
|
|
0,
|
|
shadowView.surfaceId,
|
|
shadowView.componentHandle,
|
|
shadowView.tag,
|
|
shadowView.props,
|
|
shadowView.eventEmitter,
|
|
shadowView.layoutMetrics,
|
|
shadowView.state);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/ShadowViewMutation.h}:
|
|
namespace facebook::react {
|
|
struct ShadowViewMutation final {
|
|
using List = std::vector<ShadowViewMutation>;
|
|
ShadowViewMutation() = delete;
|
|
static ShadowViewMutation CreateMutation(ShadowView shadowView);
|
|
static ShadowViewMutation DeleteMutation(ShadowView shadowView);
|
|
static ShadowViewMutation
|
|
InsertMutation(Tag parentTag, ShadowView childShadowView, int index);
|
|
static ShadowViewMutation InsertMutation(
|
|
const ShadowView& parentShadowView,
|
|
ShadowView childShadowView,
|
|
int index) {
|
|
return InsertMutation(parentShadowView.tag, childShadowView, index);
|
|
}
|
|
static ShadowViewMutation
|
|
RemoveMutation(Tag parentTag, ShadowView childShadowView, int index);
|
|
static ShadowViewMutation RemoveMutation(
|
|
const ShadowView& parentShadowView,
|
|
ShadowView childShadowView,
|
|
int index) {
|
|
return RemoveMutation(parentShadowView.tag, childShadowView, index);
|
|
}
|
|
static ShadowViewMutation UpdateMutation(
|
|
ShadowView oldChildShadowView,
|
|
ShadowView newChildShadowView,
|
|
Tag parentTag);
|
|
static ShadowViewMutation UpdateMutation(
|
|
ShadowView oldChildShadowView,
|
|
ShadowView newChildShadowView,
|
|
const ShadowView& parentShadowView) {
|
|
return UpdateMutation(
|
|
oldChildShadowView, newChildShadowView, parentShadowView.tag);
|
|
}
|
|
enum Type : std::uint8_t {
|
|
Create = 1,
|
|
Delete = 2,
|
|
Insert = 4,
|
|
Remove = 8,
|
|
Update = 16,
|
|
};
|
|
Type type = {Create};
|
|
Tag parentTag = -1;
|
|
ShadowView oldChildShadowView = {};
|
|
ShadowView newChildShadowView = {};
|
|
int index = -1;
|
|
bool mutatedViewIsVirtual() const;
|
|
};
|
|
using ShadowViewMutationList = std::vector<ShadowViewMutation>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/TelemetryController.h}:
|
|
namespace facebook::react {
|
|
using MountingTransactionCallback = std::function<void(
|
|
const MountingTransaction& transaction,
|
|
const SurfaceTelemetry& surfaceTelemetry)>;
|
|
class TelemetryController final {
|
|
friend
|
|
TelemetryController(const MountingCoordinator& mountingCoordinator) noexcept;
|
|
TelemetryController(const TelemetryController& other) noexcept = delete;
|
|
TelemetryController& operator=(const TelemetryController& other) noexcept =
|
|
delete;
|
|
|
|
public:
|
|
bool pullTransaction(
|
|
const MountingTransactionCallback& willMount,
|
|
const MountingTransactionCallback& doMount,
|
|
const MountingTransactionCallback& didMount) const;
|
|
};
|
|
mutable std::mutex mutex_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/internal/CullingContext.h}:
|
|
namespace facebook::react {
|
|
struct CullingContext {
|
|
Rect frame;
|
|
Transform transform;
|
|
bool shouldConsiderCulling() const;
|
|
CullingContext adjustCullingContextIfNeeded(
|
|
const ShadowViewNodePair& pair) const;
|
|
bool operator==(const CullingContext& rhs) const = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/internal/ShadowViewNodePair.h}:
|
|
namespace facebook::react {
|
|
struct ShadowViewNodePair final {
|
|
ShadowView shadowView;
|
|
const ShadowNode* shadowNode;
|
|
bool flattened{false};
|
|
bool isConcreteView{true};
|
|
Point contextOrigin{0, 0};
|
|
size_t mountIndex{0};
|
|
mutable const ShadowViewNodePair* otherTreePair{nullptr};
|
|
bool operator==(const ShadowViewNodePair& rhs) const {
|
|
return this->shadowNode == rhs.shadowNode;
|
|
}
|
|
bool operator!=(const ShadowViewNodePair& rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
bool inOtherTree() const {
|
|
return this->otherTreePair != nullptr;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/internal/TinyMap.h}:
|
|
template <typename KeyT, typename ValueT>
|
|
class TinyMap final {
|
|
public:
|
|
using Pair = std::pair<KeyT, ValueT>;
|
|
using Iterator = Pair*;
|
|
inline Iterator begin() {
|
|
cleanVector(erasedAtFront_ != numErased_);
|
|
Iterator it = begin_();
|
|
if (it != nullptr) {
|
|
return it + erasedAtFront_;
|
|
}
|
|
return nullptr;
|
|
}
|
|
inline Iterator end() {
|
|
if (vector_.empty() || numErased_ == vector_.size()) {
|
|
return nullptr;
|
|
}
|
|
return &vector_.back() + 1;
|
|
}
|
|
inline Iterator find(KeyT key) {
|
|
cleanVector();
|
|
react_native_assert(key != 0);
|
|
if (begin_() == nullptr) {
|
|
return end();
|
|
}
|
|
for (auto it = begin_() + erasedAtFront_; it != end(); it++) {
|
|
if (it->first == key) {
|
|
return it;
|
|
}
|
|
}
|
|
return end();
|
|
}
|
|
inline void insert(Pair pair) {
|
|
react_native_assert(pair.first != 0);
|
|
vector_.push_back(pair);
|
|
}
|
|
inline void erase(Iterator iterator) {
|
|
iterator->first = 0;
|
|
if (iterator == begin_() + erasedAtFront_) {
|
|
erasedAtFront_++;
|
|
}
|
|
numErased_++;
|
|
}
|
|
};
|
|
size_t erasedAtFront_{0};
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/internal/sliceChildShadowNodeViewPairs.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/mounting/internal/CullingContext.h}
|
|
|
|
namespace facebook::react {
|
|
using ViewNodePairScope = std::deque<ShadowViewNodePair>;
|
|
std::vector<ShadowViewNodePair*> sliceChildShadowNodeViewPairs(
|
|
const ShadowViewNodePair& shadowNodePair,
|
|
ViewNodePairScope& viewNodePairScope,
|
|
bool allowFlattened,
|
|
Point layoutOffset,
|
|
const CullingContext& cullingContext);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/stubs/StubView.h}:
|
|
namespace facebook::react {
|
|
static const int NO_VIEW_TAG = -1;
|
|
class StubView final {
|
|
public:
|
|
using Shared = std::shared_ptr<StubView>;
|
|
StubView() = default;
|
|
StubView(const StubView& stubView) = default;
|
|
operator ShadowView() const;
|
|
void update(const ShadowView& shadowView);
|
|
ComponentName componentName;
|
|
ComponentHandle componentHandle;
|
|
SurfaceId surfaceId;
|
|
Tag tag;
|
|
ShadowNodeTraits traits{};
|
|
Props::Shared props;
|
|
SharedEventEmitter eventEmitter;
|
|
LayoutMetrics layoutMetrics;
|
|
State::Shared state;
|
|
std::vector<StubView::Shared> children;
|
|
Tag parentTag{NO_VIEW_TAG};
|
|
};
|
|
bool operator==(const StubView& lhs, const StubView& rhs);
|
|
bool operator!=(const StubView& lhs, const StubView& rhs);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/stubs/StubViewTree.h}:
|
|
namespace facebook::react {
|
|
class StubViewTree {
|
|
public:
|
|
StubViewTree() = default;
|
|
StubViewTree(const ShadowView& shadowView);
|
|
void mutate(const ShadowViewMutationList& mutations);
|
|
void dispatchCommand(
|
|
const ShadowView& shadowView,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args);
|
|
const StubView& getRootStubView() const;
|
|
const StubView& getStubView(Tag tag) const;
|
|
size_t size() const;
|
|
std::vector<std::string> takeMountingLogs();
|
|
};
|
|
std::unordered_map<Tag, StubView::Shared> registry_{};
|
|
std::vector<std::string> mountingLogs_{};
|
|
friend bool operator==(const StubViewTree& lhs, const StubViewTree& rhs);
|
|
friend bool operator!=(const StubViewTree& lhs, const StubViewTree& rhs);
|
|
std::ostream& dumpTags(std::ostream& stream) const;
|
|
bool hasTag(Tag tag) const {
|
|
return registry_.find(tag) != registry_.end();
|
|
}
|
|
std::string getNativeId(Tag tag);
|
|
std::string getNativeId(const ShadowView& shadowView);
|
|
void recordMutation(const ShadowViewMutation& mutation);
|
|
};
|
|
bool operator==(const StubViewTree& lhs, const StubViewTree& rhs);
|
|
bool operator!=(const StubViewTree& lhs, const StubViewTree& rhs);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/stubs/stubs.h}:
|
|
namespace facebook::react {
|
|
StubViewTree buildStubViewTreeWithoutUsingDifferentiator(
|
|
const ShadowNode& rootShadowNode);
|
|
StubViewTree buildStubViewTreeUsingDifferentiator(
|
|
const ShadowNode& rootShadowNode);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/mounting/updateMountedFlag.h}:
|
|
namespace facebook::react {
|
|
void updateMountedFlag(
|
|
const std::vector<std::shared_ptr<const ShadowNode>>& oldChildren,
|
|
const std::vector<std::shared_ptr<const ShadowNode>>& newChildren,
|
|
ShadowTreeCommitSource commitSource);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/observers/events/EventPerformanceLogger.h}:
|
|
namespace facebook::react {
|
|
class EventPerformanceLogger : public EventLogger,
|
|
public RuntimeSchedulerEventTimingDelegate,
|
|
public UIManagerMountHook {
|
|
public:
|
|
explicit EventPerformanceLogger(
|
|
std::weak_ptr<PerformanceEntryReporter> performanceEntryReporter);
|
|
EventTag onEventStart(
|
|
std::string_view name,
|
|
SharedEventTarget target,
|
|
std::optional<HighResTimeStamp> eventStartTimeStamp =
|
|
std::nullopt) override;
|
|
void onEventProcessingStart(EventTag tag) override;
|
|
void onEventProcessingEnd(EventTag tag) override;
|
|
void dispatchPendingEventTimingEntries(
|
|
const std::unordered_set<SurfaceId>&
|
|
surfaceIdsWithPendingRenderingUpdates) override;
|
|
void shadowTreeDidMount(
|
|
const RootShadowNode::Shared& rootShadowNode,
|
|
HighResTimeStamp mountTime) noexcept override;
|
|
};
|
|
HighResTimeStamp startTime;
|
|
std::optional<HighResTimeStamp> processingStartTime;
|
|
std::optional<HighResTimeStamp> processingEndTime;
|
|
bool isWaitingForMount{false};
|
|
PerformanceEntryInteractionId interactionId{0};
|
|
bool isWaitingForDispatch() {
|
|
return !processingEndTime.has_value();
|
|
}
|
|
};
|
|
std::unordered_map<EventTag, EventEntry> eventsInFlight_;
|
|
std::mutex eventsInFlightMutex_;
|
|
std::weak_ptr<PerformanceEntryReporter> performanceEntryReporter_;
|
|
EventTag sCurrentEventTag_{EMPTY_EVENT_TAG};
|
|
EventTag createEventTag();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserver.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverState.h}
|
|
|
|
namespace facebook::react {
|
|
using IntersectionObserverObserverId = int32_t;
|
|
struct IntersectionObserverEntry {
|
|
IntersectionObserverObserverId intersectionObserverId;
|
|
ShadowNodeFamily::Shared shadowNodeFamily;
|
|
Rect targetRect;
|
|
Rect rootRect;
|
|
Rect intersectionRect;
|
|
bool isIntersectingAboveThresholds;
|
|
HighResTimeStamp time;
|
|
bool sameShadowNodeFamily(
|
|
const ShadowNodeFamily& otherShadowNodeFamily) const {
|
|
return std::addressof(*shadowNodeFamily) ==
|
|
std::addressof(otherShadowNodeFamily);
|
|
}
|
|
};
|
|
class IntersectionObserver {
|
|
public:
|
|
IntersectionObserver(
|
|
IntersectionObserverObserverId intersectionObserverId,
|
|
std::optional<ShadowNodeFamily::Shared> observationRootShadowNodeFamily,
|
|
ShadowNodeFamily::Shared targetShadowNodeFamily,
|
|
std::vector<Float> thresholds,
|
|
std::optional<std::vector<Float>> rootThresholds = std::nullopt);
|
|
std::optional<IntersectionObserverEntry> updateIntersectionObservation(
|
|
const RootShadowNode& rootShadowNode,
|
|
HighResTimeStamp time);
|
|
std::optional<IntersectionObserverEntry>
|
|
updateIntersectionObservationForSurfaceUnmount(HighResTimeStamp time);
|
|
IntersectionObserverObserverId getIntersectionObserverId() const {
|
|
return intersectionObserverId_;
|
|
}
|
|
ShadowNodeFamily::Shared getTargetShadowNodeFamily() const {
|
|
return targetShadowNodeFamily_;
|
|
}
|
|
std::vector<Float> getThresholds() const {
|
|
return thresholds_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserver.h}
|
|
|
|
namespace facebook::react {
|
|
class IntersectionObserverManager final
|
|
: public UIManagerMountHook,
|
|
public RuntimeSchedulerIntersectionObserverDelegate {
|
|
public:
|
|
IntersectionObserverManager();
|
|
void observe(
|
|
IntersectionObserverObserverId intersectionObserverId,
|
|
const std::optional<ShadowNodeFamily::Shared>& observationRootShadowNode,
|
|
const ShadowNodeFamily::Shared& shadowNode,
|
|
std::vector<Float> thresholds,
|
|
std::optional<std::vector<Float>> rootThresholds,
|
|
const UIManager& uiManager);
|
|
void unobserve(
|
|
IntersectionObserverObserverId intersectionObserverId,
|
|
const ShadowNodeFamily::Shared& shadowNode);
|
|
void connect(
|
|
RuntimeScheduler& runtimeScheduler,
|
|
UIManager& uiManager,
|
|
std::function<void()> notifyIntersectionObserversCallback);
|
|
void disconnect(RuntimeScheduler& runtimeScheduler, UIManager& uiManager);
|
|
std::vector<IntersectionObserverEntry> takeRecords();
|
|
void updateIntersectionObservations(
|
|
const std::unordered_set<SurfaceId>&
|
|
surfaceIdsWithPendingRenderingUpdates) override;
|
|
void shadowTreeDidMount(
|
|
const RootShadowNode::Shared& rootShadowNode,
|
|
HighResTimeStamp time) noexcept override;
|
|
void shadowTreeDidUnmount(SurfaceId surfaceId, HighResTimeStamp time) noexcept
|
|
override;
|
|
};
|
|
mutable std::function<void()> notifyIntersectionObserversCallback_;
|
|
mutable std::vector<IntersectionObserverEntry> pendingEntries_;
|
|
mutable std::mutex pendingEntriesMutex_;
|
|
mutable bool notifiedIntersectionObservers_{};
|
|
mutable bool mountHookRegistered_{};
|
|
void notifyObserversIfNecessary();
|
|
void notifyObservers();
|
|
void updateIntersectionObservations(
|
|
SurfaceId surfaceId,
|
|
const RootShadowNode* rootShadowNode,
|
|
HighResTimeStamp time);
|
|
const IntersectionObserver& getRegisteredIntersectionObserver(
|
|
SurfaceId surfaceId,
|
|
IntersectionObserverObserverId observerId) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/observers/intersection/IntersectionObserverState.h}:
|
|
namespace {
|
|
enum class IntersectionObserverStateType {
|
|
Initial,
|
|
NotIntersecting,
|
|
Intersecting,
|
|
};
|
|
}
|
|
namespace facebook::react {
|
|
class IntersectionObserverState {
|
|
public:
|
|
static IntersectionObserverState Initial();
|
|
static IntersectionObserverState NotIntersecting();
|
|
static IntersectionObserverState Intersecting(Float threshold);
|
|
static IntersectionObserverState Intersecting(
|
|
Float threshold,
|
|
Float rootThreshold);
|
|
bool isIntersecting() const;
|
|
bool operator==(const IntersectionObserverState& other) const;
|
|
bool operator!=(const IntersectionObserverState& other) const;
|
|
};
|
|
std::optional<Float> rootThreshold_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/observers/mutation/MutationObserver.h}:
|
|
namespace facebook::react {
|
|
using MutationObserverId = int32_t;
|
|
struct MutationRecord {
|
|
MutationObserverId mutationObserverId;
|
|
std::shared_ptr<const ShadowNode> targetShadowNode;
|
|
std::vector<std::shared_ptr<const ShadowNode>> addedShadowNodes;
|
|
std::vector<std::shared_ptr<const ShadowNode>> removedShadowNodes;
|
|
};
|
|
class MutationObserver {
|
|
public:
|
|
explicit MutationObserver(MutationObserverId mutationObserverId);
|
|
MutationObserver(const MutationObserver&) = delete;
|
|
MutationObserver& operator=(const MutationObserver&) = delete;
|
|
MutationObserver(MutationObserver&&) = default;
|
|
MutationObserver& operator=(MutationObserver&&) = default;
|
|
void observe(
|
|
std::shared_ptr<const ShadowNodeFamily> targetShadowNodeFamily,
|
|
bool observeSubtree);
|
|
void recordMutations(
|
|
const RootShadowNode& oldRootShadowNode,
|
|
const RootShadowNode& newRootShadowNode,
|
|
std::vector<MutationRecord>& recordedMutations) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/observers/mutation/MutationObserverManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/observers/mutation/MutationObserver.h}
|
|
|
|
namespace facebook::react {
|
|
class MutationObserverManager final : public UIManagerCommitHook {
|
|
public:
|
|
MutationObserverManager();
|
|
void observe(
|
|
MutationObserverId mutationObserverId,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
bool observeSubtree,
|
|
const UIManager& uiManager);
|
|
void unobserveAll(MutationObserverId mutationObserverId);
|
|
void connect(
|
|
UIManager& uiManager,
|
|
std::function<void(std::vector<MutationRecord>&)> onMutations);
|
|
void disconnect(UIManager& uiManager);
|
|
void commitHookWasRegistered(const UIManager& uiManager) noexcept override;
|
|
void commitHookWasUnregistered(const UIManager& uiManager) noexcept override;
|
|
RootShadowNode::Unshared shadowTreeWillCommit(
|
|
const ShadowTree& shadowTree,
|
|
const RootShadowNode::Shared& oldRootShadowNode,
|
|
const RootShadowNode::Unshared& newRootShadowNode,
|
|
const ShadowTree::CommitOptions& commitOptions) noexcept override;
|
|
};
|
|
void runMutationObservations(
|
|
const ShadowTree& shadowTree,
|
|
const RootShadowNode& oldRootShadowNode,
|
|
const RootShadowNode& newRootShadowNode);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerEventTimingDelegate.h}
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerIntersectionObserverDelegate.h}
|
|
|
|
namespace facebook::react {
|
|
using RuntimeSchedulerRenderingUpdate = std::function<void()>;
|
|
using SurfaceId = int32_t;
|
|
using RuntimeSchedulerTaskErrorHandler =
|
|
std::function<void(jsi::Runtime& runtime, jsi::JSError& error)>;
|
|
extern const char RuntimeSchedulerKey[];
|
|
class RuntimeSchedulerBase {
|
|
public:
|
|
virtual ~RuntimeSchedulerBase() = default;
|
|
virtual void scheduleWork(RawCallback&& callback) noexcept = 0;
|
|
virtual void executeNowOnTheSameThread(RawCallback&& callback) = 0;
|
|
virtual std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
jsi::Function&& callback) noexcept = 0;
|
|
virtual std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
RawCallback&& callback) noexcept = 0;
|
|
virtual std::shared_ptr<Task> scheduleIdleTask(
|
|
jsi::Function&& callback,
|
|
HighResDuration timeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept = 0;
|
|
virtual std::shared_ptr<Task> scheduleIdleTask(
|
|
RawCallback&& callback,
|
|
HighResDuration timeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept = 0;
|
|
virtual void cancelTask(Task& task) noexcept = 0;
|
|
virtual bool getShouldYield() noexcept = 0;
|
|
virtual SchedulerPriority getCurrentPriorityLevel() const noexcept = 0;
|
|
virtual HighResTimeStamp now() const noexcept = 0;
|
|
virtual void callExpiredTasks(jsi::Runtime& runtime) = 0;
|
|
virtual void scheduleRenderingUpdate(
|
|
SurfaceId surfaceId,
|
|
RuntimeSchedulerRenderingUpdate&& renderingUpdate) = 0;
|
|
virtual void setShadowTreeRevisionConsistencyManager(
|
|
ShadowTreeRevisionConsistencyManager* provider) = 0;
|
|
virtual void setPerformanceEntryReporter(
|
|
PerformanceEntryReporter* reporter) = 0;
|
|
virtual void setEventTimingDelegate(
|
|
RuntimeSchedulerEventTimingDelegate* eventTimingDelegate) = 0;
|
|
virtual void setIntersectionObserverDelegate(
|
|
RuntimeSchedulerIntersectionObserverDelegate*
|
|
intersectionObserverDelegate) = 0;
|
|
};
|
|
class RuntimeScheduler final : RuntimeSchedulerBase {
|
|
public:
|
|
explicit RuntimeScheduler(
|
|
RuntimeExecutor runtimeExecutor,
|
|
std::function<HighResTimeStamp()> now = HighResTimeStamp::now,
|
|
RuntimeSchedulerTaskErrorHandler onTaskError = handleTaskErrorDefault);
|
|
RuntimeScheduler(const RuntimeScheduler&) = delete;
|
|
RuntimeScheduler& operator=(const RuntimeScheduler&) = delete;
|
|
RuntimeScheduler(RuntimeScheduler&&) = delete;
|
|
RuntimeScheduler& operator=(RuntimeScheduler&&) = delete;
|
|
void scheduleWork(RawCallback&& callback) noexcept override;
|
|
void executeNowOnTheSameThread(RawCallback&& callback) override;
|
|
std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
jsi::Function&& callback) noexcept override;
|
|
std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
RawCallback&& callback) noexcept override;
|
|
std::shared_ptr<Task> scheduleIdleTask(
|
|
jsi::Function&& callback,
|
|
HighResDuration timeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept override;
|
|
std::shared_ptr<Task> scheduleIdleTask(
|
|
RawCallback&& callback,
|
|
HighResDuration timeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept override;
|
|
void cancelTask(Task& task) noexcept override;
|
|
bool getShouldYield() noexcept override;
|
|
SchedulerPriority getCurrentPriorityLevel() const noexcept override;
|
|
HighResTimeStamp now() const noexcept override;
|
|
void callExpiredTasks(jsi::Runtime& runtime) override;
|
|
void scheduleRenderingUpdate(
|
|
SurfaceId surfaceId,
|
|
RuntimeSchedulerRenderingUpdate&& renderingUpdate) override;
|
|
void setShadowTreeRevisionConsistencyManager(
|
|
ShadowTreeRevisionConsistencyManager*
|
|
shadowTreeRevisionConsistencyManager) override;
|
|
void setPerformanceEntryReporter(PerformanceEntryReporter* reporter) override;
|
|
void setEventTimingDelegate(
|
|
RuntimeSchedulerEventTimingDelegate* eventTimingDelegate) override;
|
|
void setIntersectionObserverDelegate(
|
|
RuntimeSchedulerIntersectionObserverDelegate*
|
|
intersectionObserverDelegate) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerBinding.h}:
|
|
namespace facebook::react {
|
|
class RuntimeSchedulerBinding : public jsi::HostObject {
|
|
public:
|
|
RuntimeSchedulerBinding(std::shared_ptr<RuntimeScheduler> runtimeScheduler);
|
|
static std::shared_ptr<RuntimeSchedulerBinding> createAndInstallIfNeeded(
|
|
jsi::Runtime& runtime,
|
|
const std::shared_ptr<RuntimeScheduler>& runtimeScheduler);
|
|
static std::shared_ptr<RuntimeSchedulerBinding> getBinding(
|
|
jsi::Runtime& runtime);
|
|
std::shared_ptr<RuntimeScheduler> getRuntimeScheduler() noexcept;
|
|
jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& name) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerCallInvoker.h}:
|
|
namespace facebook::react {
|
|
class RuntimeSchedulerCallInvoker : public CallInvoker {
|
|
public:
|
|
RuntimeSchedulerCallInvoker(std::weak_ptr<RuntimeScheduler> runtimeScheduler);
|
|
void invokeAsync(CallFunc&& func) noexcept override;
|
|
void invokeSync(CallFunc&& func) override;
|
|
void invokeAsync(SchedulerPriority priority, CallFunc&& func) noexcept
|
|
override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerEventTimingDelegate.h}:
|
|
namespace facebook::react {
|
|
using SurfaceId = int32_t;
|
|
class RuntimeSchedulerEventTimingDelegate {
|
|
public:
|
|
virtual ~RuntimeSchedulerEventTimingDelegate() = default;
|
|
virtual void dispatchPendingEventTimingEntries(
|
|
const std::unordered_set<SurfaceId>&
|
|
surfaceIdsWithPendingRenderingUpdates) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeSchedulerIntersectionObserverDelegate.h}:
|
|
namespace facebook::react {
|
|
using SurfaceId = int32_t;
|
|
class RuntimeSchedulerIntersectionObserverDelegate {
|
|
public:
|
|
virtual ~RuntimeSchedulerIntersectionObserverDelegate() = default;
|
|
virtual void updateIntersectionObservations(
|
|
const std::unordered_set<SurfaceId>&
|
|
surfaceIdsWithPendingRenderingUpdates) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Legacy.h}:
|
|
namespace facebook::react {
|
|
class RuntimeScheduler_Legacy final : public RuntimeSchedulerBase {
|
|
public:
|
|
explicit RuntimeScheduler_Legacy(
|
|
RuntimeExecutor runtimeExecutor,
|
|
std::function<HighResTimeStamp()> now,
|
|
RuntimeSchedulerTaskErrorHandler onTaskError);
|
|
RuntimeScheduler_Legacy(const RuntimeScheduler_Legacy&) = delete;
|
|
RuntimeScheduler_Legacy& operator=(const RuntimeScheduler_Legacy&) = delete;
|
|
RuntimeScheduler_Legacy(RuntimeScheduler_Legacy&&) = delete;
|
|
RuntimeScheduler_Legacy& operator=(RuntimeScheduler_Legacy&&) = delete;
|
|
void scheduleWork(RawCallback&& callback) noexcept override;
|
|
void executeNowOnTheSameThread(RawCallback&& callback) override;
|
|
std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
jsi::Function&& callback) noexcept override;
|
|
std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
RawCallback&& callback) noexcept override;
|
|
std::shared_ptr<Task> scheduleIdleTask(
|
|
jsi::Function&& callback,
|
|
HighResDuration timeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept override;
|
|
std::shared_ptr<Task> scheduleIdleTask(
|
|
RawCallback&& callback,
|
|
HighResDuration timeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept override;
|
|
void cancelTask(Task& task) noexcept override;
|
|
bool getShouldYield() noexcept override;
|
|
SchedulerPriority getCurrentPriorityLevel() const noexcept override;
|
|
HighResTimeStamp now() const noexcept override;
|
|
void callExpiredTasks(jsi::Runtime& runtime) override;
|
|
void scheduleRenderingUpdate(
|
|
SurfaceId surfaceId,
|
|
RuntimeSchedulerRenderingUpdate&& renderingUpdate) override;
|
|
void setShadowTreeRevisionConsistencyManager(
|
|
ShadowTreeRevisionConsistencyManager*
|
|
shadowTreeRevisionConsistencyManager) override;
|
|
void setPerformanceEntryReporter(
|
|
PerformanceEntryReporter* performanceEntryReporter) override;
|
|
void setEventTimingDelegate(
|
|
RuntimeSchedulerEventTimingDelegate* eventTimingDelegate) override;
|
|
void setIntersectionObserverDelegate(
|
|
RuntimeSchedulerIntersectionObserverDelegate*
|
|
intersectionObserverDelegate) override;
|
|
};
|
|
std::atomic<uint_fast8_t> runtimeAccessRequests_{0};
|
|
std::atomic_bool isSynchronous_{false};
|
|
void startWorkLoop(jsi::Runtime& runtime);
|
|
void scheduleWorkLoopIfNecessary();
|
|
void executeTask(
|
|
jsi::Runtime& runtime,
|
|
const std::shared_ptr<Task>& task,
|
|
bool didUserCallbackTimeout);
|
|
std::function<HighResTimeStamp()> now_;
|
|
std::atomic_bool isWorkLoopScheduled_{false};
|
|
std::atomic_bool isPerformingWork_{false};
|
|
std::atomic<ShadowTreeRevisionConsistencyManager*>
|
|
shadowTreeRevisionConsistencyManager_{nullptr};
|
|
RuntimeSchedulerTaskErrorHandler onTaskError_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/RuntimeScheduler_Modern.h}:
|
|
namespace facebook::react {
|
|
class RuntimeScheduler_Modern final : public RuntimeSchedulerBase {
|
|
public:
|
|
explicit RuntimeScheduler_Modern(
|
|
RuntimeExecutor runtimeExecutor,
|
|
std::function<HighResTimeStamp()> now,
|
|
RuntimeSchedulerTaskErrorHandler onTaskError);
|
|
RuntimeScheduler_Modern(const RuntimeScheduler_Modern&) = delete;
|
|
RuntimeScheduler_Modern& operator=(const RuntimeScheduler_Modern&) = delete;
|
|
RuntimeScheduler_Modern(RuntimeScheduler_Modern&&) = delete;
|
|
RuntimeScheduler_Modern& operator=(RuntimeScheduler_Modern&&) = delete;
|
|
void scheduleWork(RawCallback&& callback) noexcept override;
|
|
void executeNowOnTheSameThread(RawCallback&& callback) override;
|
|
std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
jsi::Function&& callback) noexcept override;
|
|
std::shared_ptr<Task> scheduleTask(
|
|
SchedulerPriority priority,
|
|
RawCallback&& callback) noexcept override;
|
|
std::shared_ptr<Task> scheduleIdleTask(
|
|
jsi::Function&& callback,
|
|
HighResDuration customTimeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept override;
|
|
std::shared_ptr<Task> scheduleIdleTask(
|
|
RawCallback&& callback,
|
|
HighResDuration customTimeout = timeoutForSchedulerPriority(
|
|
SchedulerPriority::IdlePriority)) noexcept override;
|
|
void cancelTask(Task& task) noexcept override;
|
|
bool getShouldYield() noexcept override;
|
|
SchedulerPriority getCurrentPriorityLevel() const noexcept override;
|
|
HighResTimeStamp now() const noexcept override;
|
|
void callExpiredTasks(jsi::Runtime& runtime) override;
|
|
void scheduleRenderingUpdate(
|
|
SurfaceId surfaceId,
|
|
RuntimeSchedulerRenderingUpdate&& renderingUpdate) override;
|
|
void setShadowTreeRevisionConsistencyManager(
|
|
ShadowTreeRevisionConsistencyManager*
|
|
shadowTreeRevisionConsistencyManager) override;
|
|
void setPerformanceEntryReporter(
|
|
PerformanceEntryReporter* performanceEntryReporter) override;
|
|
void setEventTimingDelegate(
|
|
RuntimeSchedulerEventTimingDelegate* eventTimingDelegate) override;
|
|
void setIntersectionObserverDelegate(
|
|
RuntimeSchedulerIntersectionObserverDelegate*
|
|
intersectionObserverDelegate) override;
|
|
};
|
|
std::priority_queue<
|
|
std::shared_ptr<Task>,
|
|
std::vector<std::shared_ptr<Task>>,
|
|
TaskPriorityComparer>
|
|
taskQueue_;
|
|
Task* currentTask_{};
|
|
HighResTimeStamp lastYieldingOpportunity_;
|
|
HighResDuration longestPeriodWithoutYieldingOpportunity_;
|
|
void markYieldingOpportunity(HighResTimeStamp currentTime);
|
|
mutable std::shared_mutex schedulingMutex_;
|
|
const RuntimeExecutor runtimeExecutor_;
|
|
SchedulerPriority currentPriority_{SchedulerPriority::NormalPriority};
|
|
void scheduleEventLoop();
|
|
void runEventLoop(jsi::Runtime& runtime);
|
|
std::shared_ptr<Task> selectTask();
|
|
void scheduleTask(std::shared_ptr<Task> task);
|
|
void runEventLoopTick(jsi::Runtime& runtime, Task& task);
|
|
void executeTask(
|
|
jsi::Runtime& runtime,
|
|
Task& task,
|
|
bool didUserCallbackTimeout) const;
|
|
void updateRendering();
|
|
bool performingMicrotaskCheckpoint_{false};
|
|
void performMicrotaskCheckpoint(jsi::Runtime& runtime);
|
|
void reportLongTasks(
|
|
const Task& task,
|
|
HighResTimeStamp startTime,
|
|
HighResTimeStamp endTime);
|
|
std::function<HighResTimeStamp()> now_;
|
|
bool isEventLoopScheduled_{false};
|
|
std::queue<RuntimeSchedulerRenderingUpdate> pendingRenderingUpdates_;
|
|
std::unordered_set<SurfaceId> surfaceIdsWithPendingRenderingUpdates_;
|
|
std::atomic<ShadowTreeRevisionConsistencyManager*>
|
|
shadowTreeRevisionConsistencyManager_{nullptr};
|
|
std::atomic<RuntimeSchedulerEventTimingDelegate*> eventTimingDelegate_{
|
|
nullptr};
|
|
PerformanceEntryReporter* performanceEntryReporter_{nullptr};
|
|
RuntimeSchedulerIntersectionObserverDelegate* intersectionObserverDelegate_{
|
|
nullptr};
|
|
RuntimeSchedulerTaskErrorHandler onTaskError_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/SchedulerPriorityUtils.h}:
|
|
namespace facebook::react {
|
|
static constexpr std::underlying_type<SchedulerPriority>::type serialize(
|
|
SchedulerPriority schedulerPriority) {
|
|
return static_cast<std::underlying_type<SchedulerPriority>::type>(
|
|
schedulerPriority);
|
|
}
|
|
static inline SchedulerPriority fromRawValue(double value) {
|
|
switch ((int)value) {
|
|
case 1:
|
|
return SchedulerPriority::ImmediatePriority;
|
|
case 2:
|
|
return SchedulerPriority::UserBlockingPriority;
|
|
case 3:
|
|
return SchedulerPriority::NormalPriority;
|
|
case 4:
|
|
return SchedulerPriority::LowPriority;
|
|
case 5:
|
|
return SchedulerPriority::IdlePriority;
|
|
}
|
|
react_native_assert(false && "Unsupported SchedulerPriority value");
|
|
return SchedulerPriority::NormalPriority;
|
|
}
|
|
static inline HighResDuration timeoutForSchedulerPriority(
|
|
SchedulerPriority schedulerPriority) noexcept {
|
|
switch (schedulerPriority) {
|
|
case SchedulerPriority::ImmediatePriority:
|
|
return HighResDuration::fromChrono(std::chrono::milliseconds(0));
|
|
case SchedulerPriority::UserBlockingPriority:
|
|
return HighResDuration::fromChrono(std::chrono::milliseconds(250));
|
|
case SchedulerPriority::NormalPriority:
|
|
return HighResDuration::fromChrono(std::chrono::seconds(5));
|
|
case SchedulerPriority::LowPriority:
|
|
return HighResDuration::fromChrono(std::chrono::seconds(10));
|
|
case SchedulerPriority::IdlePriority:
|
|
return HighResDuration::fromChrono(std::chrono::minutes(5));
|
|
}
|
|
react_native_assert(false && "Unsupported SchedulerPriority value");
|
|
return HighResDuration::fromChrono(std::chrono::seconds(5));
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/Task.h}:
|
|
namespace facebook::react {
|
|
using RawCallback = std::function<void(jsi::Runtime&)>;
|
|
struct Task final : public jsi::NativeState {
|
|
Task(
|
|
SchedulerPriority priority,
|
|
jsi::Function&& callback,
|
|
HighResTimeStamp expirationTime);
|
|
Task(
|
|
SchedulerPriority priority,
|
|
RawCallback&& callback,
|
|
HighResTimeStamp expirationTime);
|
|
};
|
|
class TaskPriorityComparer {
|
|
public:
|
|
inline bool operator()(
|
|
const std::shared_ptr<Task>& lhs,
|
|
const std::shared_ptr<Task>& rhs) {
|
|
return lhs->expirationTime > rhs->expirationTime;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/primitives.h}:
|
|
namespace facebook::react {
|
|
inline static jsi::Value valueFromTask(
|
|
jsi::Runtime& runtime,
|
|
std::shared_ptr<Task> task) {
|
|
jsi::Object obj(runtime);
|
|
obj.setNativeState(runtime, std::move(task));
|
|
return obj;
|
|
}
|
|
inline static std::shared_ptr<Task> taskFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& value) {
|
|
if (value.isNull()) {
|
|
return nullptr;
|
|
}
|
|
return value.getObject(runtime).getNativeState<Task>(runtime);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/StubClock.h}:
|
|
namespace facebook::react {
|
|
class StubClock {
|
|
public:
|
|
HighResTimeStamp getNow() const {
|
|
return timePoint_;
|
|
}
|
|
void setTimePoint(HighResTimeStamp timePoint) {
|
|
timePoint_ = timePoint;
|
|
}
|
|
HighResTimeStamp getTimePoint() {
|
|
return timePoint_;
|
|
}
|
|
void advanceTimeBy(HighResDuration duration) {
|
|
timePoint_ += duration;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/StubErrorUtils.h}:
|
|
namespace facebook::react {
|
|
class StubErrorUtils : public jsi::HostObject {
|
|
public:
|
|
static std::shared_ptr<StubErrorUtils> createAndInstallIfNeeded(
|
|
jsi::Runtime& runtime) {
|
|
auto errorUtilsModuleName = "ErrorUtils";
|
|
auto errorUtilsValue =
|
|
runtime.global().getProperty(runtime, errorUtilsModuleName);
|
|
if (errorUtilsValue.isUndefined()) {
|
|
auto stubErrorUtils = std::make_shared<StubErrorUtils>();
|
|
auto object = jsi::Object::createFromHostObject(runtime, stubErrorUtils);
|
|
runtime.global().setProperty(
|
|
runtime, errorUtilsModuleName, std::move(object));
|
|
return stubErrorUtils;
|
|
}
|
|
auto stubErrorUtilsObject = errorUtilsValue.asObject(runtime);
|
|
return stubErrorUtilsObject.getHostObject<StubErrorUtils>(runtime);
|
|
}
|
|
jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& name) override {
|
|
auto propertyName = name.utf8(runtime);
|
|
if (propertyName == "reportFatalError") {
|
|
return jsi::Function::createFromHostFunction(
|
|
runtime,
|
|
name,
|
|
1,
|
|
[this](
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value&,
|
|
const jsi::Value* arguments,
|
|
size_t) noexcept -> jsi::Value {
|
|
reportFatalCallCount_++;
|
|
return jsi::Value::undefined();
|
|
});
|
|
}
|
|
return jsi::Value::undefined();
|
|
}
|
|
int getReportFatalCallCount() const {
|
|
return reportFatalCallCount_;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/runtimescheduler/tests/StubQueue.h}:
|
|
class StubQueue {
|
|
public:
|
|
void runOnQueue(std::function<void()>&& func) {
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
callbackQueue_.push(func);
|
|
}
|
|
signal_.notify_one();
|
|
}
|
|
void flush() {
|
|
while (size() > 0) {
|
|
tick();
|
|
}
|
|
}
|
|
void tick() {
|
|
std::function<void()> callback;
|
|
{
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
if (!callbackQueue_.empty()) {
|
|
callback = callbackQueue_.front();
|
|
callbackQueue_.pop();
|
|
}
|
|
}
|
|
if (callback) {
|
|
callback();
|
|
}
|
|
}
|
|
size_t size() const {
|
|
std::lock_guard<std::mutex> lock(mutex_);
|
|
return callbackQueue_.size();
|
|
}
|
|
bool waitForTask() const {
|
|
std::unique_lock<std::mutex> lock(mutex_);
|
|
return signal_.wait_for(
|
|
lock, StubQueue::timeout, [this]() { return !callbackQueue_.empty(); });
|
|
}
|
|
bool waitForTasks(std::size_t numberOfTasks) const {
|
|
std::unique_lock<std::mutex> lock(mutex_);
|
|
return signal_.wait_for(lock, StubQueue::timeout, [this, numberOfTasks]() {
|
|
return numberOfTasks == callbackQueue_.size();
|
|
});
|
|
}
|
|
};
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/scheduler/InspectorData.h}:
|
|
namespace facebook::react {
|
|
struct InspectorData {
|
|
std::vector<std::string> hierarchy;
|
|
int selectedIndex;
|
|
std::string fileName;
|
|
int lineNumber;
|
|
int columnNumber;
|
|
folly::dynamic props;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/scheduler/Scheduler.h}:
|
|
namespace facebook::react {
|
|
class Scheduler final : public UIManagerDelegate {
|
|
public:
|
|
Scheduler(
|
|
const SchedulerToolbox& schedulerToolbox,
|
|
UIManagerAnimationDelegate* animationDelegate,
|
|
SchedulerDelegate* delegate);
|
|
~Scheduler() override;
|
|
void registerSurface(const SurfaceHandler& surfaceHandler) const noexcept;
|
|
void unregisterSurface(const SurfaceHandler& surfaceHandler) const noexcept;
|
|
const ComponentDescriptor*
|
|
findComponentDescriptorByHandle_DO_NOT_USE_THIS_IS_BROKEN(
|
|
ComponentHandle handle) const;
|
|
void setDelegate(SchedulerDelegate* delegate);
|
|
SchedulerDelegate* getDelegate() const;
|
|
void animationTick() const;
|
|
void uiManagerDidFinishTransaction(
|
|
std::shared_ptr<const MountingCoordinator> mountingCoordinator,
|
|
bool mountSynchronously) override;
|
|
void uiManagerDidCreateShadowNode(const ShadowNode& shadowNode) override;
|
|
void uiManagerDidDispatchCommand(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args) override;
|
|
void uiManagerDidSendAccessibilityEvent(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
const std::string& eventType) override;
|
|
void uiManagerDidSetIsJSResponder(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
bool isJSResponder,
|
|
bool blockNativeResponder) override;
|
|
void uiManagerShouldSynchronouslyUpdateViewOnUIThread(
|
|
Tag tag,
|
|
const folly::dynamic& props) override;
|
|
void uiManagerDidUpdateShadowTree(
|
|
const std::unordered_map<Tag, folly::dynamic>& tagToProps) override;
|
|
void uiManagerShouldAddEventListener(
|
|
std::shared_ptr<const EventListener> listener) final;
|
|
void uiManagerShouldRemoveEventListener(
|
|
const std::shared_ptr<const EventListener>& listener) final;
|
|
void uiManagerDidStartSurface(const ShadowTree& shadowTree) override;
|
|
std::shared_ptr<const ContextContainer> getContextContainer() const;
|
|
std::shared_ptr<UIManager> getUIManager() const;
|
|
void reportMount(SurfaceId surfaceId) const;
|
|
void addEventListener(std::shared_ptr<const EventListener> listener);
|
|
void removeEventListener(
|
|
const std::shared_ptr<const EventListener>& listener);
|
|
void uiManagerShouldSetOnSurfaceStartCallback(
|
|
OnSurfaceStartCallback&& callback) override;
|
|
};
|
|
mutable std::shared_mutex onSurfaceStartCallbackMutex_;
|
|
OnSurfaceStartCallback onSurfaceStartCallback_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerDelegate.h}:
|
|
namespace facebook::react {
|
|
class SchedulerDelegate {
|
|
public:
|
|
virtual void schedulerDidFinishTransaction(
|
|
const std::shared_ptr<const MountingCoordinator>&
|
|
mountingCoordinator) = 0;
|
|
virtual void schedulerShouldRenderTransactions(
|
|
const std::shared_ptr<const MountingCoordinator>&
|
|
mountingCoordinator) = 0;
|
|
virtual void schedulerDidRequestPreliminaryViewAllocation(
|
|
const ShadowNode& shadowNode) = 0;
|
|
virtual void schedulerDidDispatchCommand(
|
|
const ShadowView& shadowView,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args) = 0;
|
|
virtual void schedulerDidSendAccessibilityEvent(
|
|
const ShadowView& shadowView,
|
|
const std::string& eventType) = 0;
|
|
virtual void schedulerDidSetIsJSResponder(
|
|
const ShadowView& shadowView,
|
|
bool isJSResponder,
|
|
bool blockNativeResponder) = 0;
|
|
virtual void schedulerShouldSynchronouslyUpdateViewOnUIThread(
|
|
Tag tag,
|
|
const folly::dynamic& props) = 0;
|
|
virtual void schedulerDidUpdateShadowTree(
|
|
const std::unordered_map<Tag, folly::dynamic>& tagToProps) = 0;
|
|
virtual ~SchedulerDelegate() noexcept = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/scheduler/SchedulerToolbox.h}:
|
|
namespace facebook::react {
|
|
struct SchedulerToolbox final {
|
|
std::shared_ptr<const ContextContainer> contextContainer;
|
|
ComponentRegistryFactory componentRegistryFactory;
|
|
std::optional<RuntimeExecutor> bridgelessBindingsExecutor;
|
|
RuntimeExecutor runtimeExecutor;
|
|
EventBeat::Factory eventBeatFactory;
|
|
std::vector<std::shared_ptr<UIManagerCommitHook>> commitHooks;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceHandler.h}:
|
|
namespace facebook::react {
|
|
class SurfaceHandler {
|
|
public:
|
|
enum class Status {
|
|
Unregistered = 0,
|
|
Registered = 1,
|
|
Running = 2,
|
|
};
|
|
SurfaceHandler(const std::string& moduleName, SurfaceId surfaceId) noexcept;
|
|
virtual ~SurfaceHandler() noexcept;
|
|
SurfaceHandler(SurfaceHandler&& other) noexcept;
|
|
SurfaceHandler(const SurfaceHandler& SurfaceHandler) noexcept = delete;
|
|
SurfaceHandler& operator=(SurfaceHandler&& other) noexcept;
|
|
SurfaceHandler& operator=(const SurfaceHandler& other) noexcept = delete;
|
|
void setContextContainer(
|
|
std::shared_ptr<const ContextContainer> contextContainer) const noexcept;
|
|
Status getStatus() const noexcept;
|
|
void start() const noexcept;
|
|
void stop() const noexcept;
|
|
virtual void setDisplayMode(DisplayMode displayMode) const noexcept;
|
|
DisplayMode getDisplayMode() const noexcept;
|
|
SurfaceId getSurfaceId() const noexcept;
|
|
void setSurfaceId(SurfaceId surfaceId) const noexcept;
|
|
std::string getModuleName() const noexcept;
|
|
void setProps(const folly::dynamic& props) const noexcept;
|
|
folly::dynamic getProps() const noexcept;
|
|
std::shared_ptr<const MountingCoordinator> getMountingCoordinator()
|
|
const noexcept;
|
|
Size measure(
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext) const;
|
|
void constraintLayout(
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext) const;
|
|
LayoutConstraints getLayoutConstraints() const noexcept;
|
|
LayoutContext getLayoutContext() const noexcept;
|
|
};
|
|
SurfaceId surfaceId{};
|
|
DisplayMode displayMode{DisplayMode::Visible};
|
|
folly::dynamic props{};
|
|
LayoutConstraints layoutConstraints{};
|
|
LayoutContext layoutContext{};
|
|
std::shared_ptr<const ContextContainer> contextContainer{};
|
|
};
|
|
struct Link {
|
|
Status status{Status::Unregistered};
|
|
const UIManager* uiManager{};
|
|
const ShadowTree* shadowTree{};
|
|
};
|
|
mutable std::shared_mutex linkMutex_;
|
|
mutable Link link_;
|
|
mutable std::shared_mutex parametersMutex_;
|
|
mutable Parameters parameters_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/scheduler/SurfaceManager.h}:
|
|
namespace facebook::react {
|
|
class SurfaceManager final {
|
|
public:
|
|
explicit SurfaceManager(const Scheduler& scheduler) noexcept;
|
|
~SurfaceManager() noexcept;
|
|
struct SurfaceProps {
|
|
SurfaceId surfaceId;
|
|
std::string moduleName;
|
|
folly::dynamic props;
|
|
LayoutConstraints layoutConstraints;
|
|
LayoutContext layoutContext;
|
|
};
|
|
void startSurface(
|
|
SurfaceId surfaceId,
|
|
const std::string& moduleName,
|
|
const folly::dynamic& props,
|
|
const LayoutConstraints& layoutConstraints = {},
|
|
const LayoutContext& layoutContext = {}) noexcept;
|
|
void stopSurface(SurfaceId surfaceId) noexcept;
|
|
void stopAllSurfaces() noexcept;
|
|
bool isSurfaceRunning(SurfaceId surfaceId) const noexcept;
|
|
std::unordered_set<SurfaceId> getRunningSurfaces() const noexcept;
|
|
std::optional<SurfaceManager::SurfaceProps> getSurfaceProps(
|
|
SurfaceId surfaceId) const noexcept;
|
|
Size measureSurface(
|
|
SurfaceId surfaceId,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext) const noexcept;
|
|
void constraintSurfaceLayout(
|
|
SurfaceId surfaceId,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext) const noexcept;
|
|
std::shared_ptr<const MountingCoordinator> findMountingCoordinator(
|
|
SurfaceId surfaceId) const noexcept;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/telemetry/SurfaceTelemetry.h}:
|
|
namespace facebook::react {
|
|
class SurfaceTelemetry final {
|
|
public:
|
|
constexpr static size_t kMaxNumberOfRecordedCommitTelemetries = 16;
|
|
TelemetryDuration getLayoutTime() const;
|
|
TelemetryDuration getTextMeasureTime() const;
|
|
TelemetryDuration getCommitTime() const;
|
|
TelemetryDuration getDiffTime() const;
|
|
TelemetryDuration getMountTime() const;
|
|
int getNumberOfTransactions() const;
|
|
int getNumberOfMutations() const;
|
|
int getNumberOfTextMeasurements() const;
|
|
int getLastRevisionNumber() const;
|
|
std::vector<TransactionTelemetry> getRecentTransactionTelemetries() const;
|
|
void incorporate(
|
|
const TransactionTelemetry& telemetry,
|
|
int numberOfMutations);
|
|
};
|
|
TelemetryDuration commitTime_{};
|
|
TelemetryDuration textMeasureTime_{};
|
|
TelemetryDuration diffTime_{};
|
|
TelemetryDuration mountTime_{};
|
|
int numberOfTransactions_{};
|
|
int numberOfMutations_{};
|
|
int numberOfTextMeasurements_{};
|
|
int lastRevisionNumber_{};
|
|
std::vector<TransactionTelemetry> recentTransactionTelemetries_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/telemetry/TransactionTelemetry.h}:
|
|
namespace facebook::react {
|
|
class TransactionTelemetry final {
|
|
public:
|
|
static TransactionTelemetry* threadLocalTelemetry();
|
|
TransactionTelemetry();
|
|
TransactionTelemetry(std::function<TelemetryTimePoint()> now);
|
|
void setAsThreadLocal();
|
|
void unsetAsThreadLocal();
|
|
void willDiff();
|
|
void didDiff();
|
|
void willCommit();
|
|
void didCommit();
|
|
void willLayout();
|
|
void willMeasureText();
|
|
void didMeasureText();
|
|
void didLayout();
|
|
void didLayout(int affectedLayoutNodesCount);
|
|
void willMount();
|
|
void didMount();
|
|
void setRevisionNumber(int revisionNumber);
|
|
TelemetryTimePoint getDiffStartTime() const;
|
|
TelemetryTimePoint getDiffEndTime() const;
|
|
TelemetryTimePoint getLayoutStartTime() const;
|
|
TelemetryTimePoint getLayoutEndTime() const;
|
|
TelemetryTimePoint getCommitStartTime() const;
|
|
TelemetryTimePoint getCommitEndTime() const;
|
|
TelemetryTimePoint getMountStartTime() const;
|
|
TelemetryTimePoint getMountEndTime() const;
|
|
TelemetryDuration getTextMeasureTime() const;
|
|
int getNumberOfTextMeasurements() const;
|
|
int getRevisionNumber() const;
|
|
int getAffectedLayoutNodesCount() const;
|
|
};
|
|
TelemetryTimePoint diffEndTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint commitStartTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint commitEndTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint layoutStartTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint layoutEndTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint mountStartTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint mountEndTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryTimePoint lastTextMeasureStartTime_{kTelemetryUndefinedTimePoint};
|
|
TelemetryDuration textMeasureTime_{0};
|
|
int numberOfTextMeasurements_{0};
|
|
int revisionNumber_{0};
|
|
std::function<TelemetryTimePoint()> now_;
|
|
int affectedLayoutNodesCount_{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/TextLayoutContext.h}:
|
|
namespace facebook::react {
|
|
struct TextLayoutContext {
|
|
Float pointScaleFactor{1.0};
|
|
SurfaceId surfaceId{-1};
|
|
bool operator==(const TextLayoutContext& rhs) const = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/TextLayoutManagerExtended.h}:
|
|
namespace facebook::react {
|
|
template <typename TextLayoutManagerT>
|
|
concept TextLayoutManagerWithPreparedLayout = requires(
|
|
TextLayoutManagerT textLayoutManager,
|
|
AttributedString attributedString,
|
|
ParagraphAttributes paragraphAttributes,
|
|
TextLayoutContext layoutContext,
|
|
LayoutConstraints layoutConstraints,
|
|
typename TextLayoutManagerT::PreparedLayout preparedLayout) {
|
|
sizeof(typename TextLayoutManagerT::PreparedLayout);
|
|
{
|
|
textLayoutManager.prepareLayout(
|
|
attributedString, paragraphAttributes, layoutContext, layoutConstraints)
|
|
} -> std::same_as<typename TextLayoutManagerT::PreparedLayout>;
|
|
{
|
|
textLayoutManager.measurePreparedLayout(
|
|
preparedLayout, layoutContext, layoutConstraints)
|
|
} -> std::same_as<TextMeasurement>;
|
|
};
|
|
namespace detail {
|
|
template <typename T>
|
|
struct PreparedLayoutT {
|
|
using type = std::nullptr_t;
|
|
};
|
|
template <TextLayoutManagerWithPreparedLayout T>
|
|
struct PreparedLayoutT<T> {
|
|
using type = typename T::PreparedLayout;
|
|
};
|
|
template <typename TextLayoutManagerT>
|
|
class TextLayoutManagerExtended {
|
|
public:
|
|
static constexpr bool supportsLineMeasurement() {
|
|
return requires(TextLayoutManagerT textLayoutManager) {
|
|
{
|
|
textLayoutManager.measureLines(
|
|
AttributedStringBox{}, ParagraphAttributes{}, Size{})
|
|
} -> std::same_as<LinesMeasurements>;
|
|
};
|
|
}
|
|
static constexpr bool supportsPreparedLayout() {
|
|
return TextLayoutManagerWithPreparedLayout<TextLayoutManagerT>;
|
|
}
|
|
using PreparedLayout = typename PreparedLayoutT<TextLayoutManagerT>::type;
|
|
TextLayoutManagerExtended(const TextLayoutManagerT& textLayoutManager)
|
|
: textLayoutManager_(textLayoutManager) {}
|
|
LinesMeasurements measureLines(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const Size& size) {
|
|
if constexpr (supportsLineMeasurement()) {
|
|
return textLayoutManager_.measureLines(
|
|
attributedStringBox, paragraphAttributes, size);
|
|
}
|
|
LOG(FATAL) << "Platform TextLayoutManager does not support measureLines";
|
|
}
|
|
PreparedLayout prepareLayout(
|
|
const AttributedString& attributedString,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const {
|
|
if constexpr (supportsPreparedLayout()) {
|
|
return textLayoutManager_.prepareLayout(
|
|
attributedString,
|
|
paragraphAttributes,
|
|
layoutContext,
|
|
layoutConstraints);
|
|
}
|
|
LOG(FATAL) << "Platform TextLayoutManager does not support prepareLayout";
|
|
}
|
|
TextMeasurement measurePreparedLayout(
|
|
const PreparedLayout& layout,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const {
|
|
if constexpr (supportsPreparedLayout()) {
|
|
return textLayoutManager_.measurePreparedLayout(
|
|
layout, layoutContext, layoutConstraints);
|
|
}
|
|
LOG(FATAL)
|
|
<< "Platform TextLayoutManager does not support measurePreparedLayout";
|
|
}
|
|
};
|
|
} // namespace detail
|
|
using TextLayoutManagerExtended =
|
|
detail::TextLayoutManagerExtended<TextLayoutManager>;
|
|
struct MeasuredPreparedLayout {
|
|
LayoutConstraints layoutConstraints;
|
|
TextMeasurement measurement;
|
|
TextLayoutManagerExtended::PreparedLayout preparedLayout{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/TextMeasureCache.h}:
|
|
namespace facebook::react {
|
|
struct LineMeasurement {
|
|
std::string text;
|
|
Rect frame;
|
|
Float descender;
|
|
Float capHeight;
|
|
Float ascender;
|
|
Float xHeight;
|
|
LineMeasurement(
|
|
std::string text,
|
|
Rect frame,
|
|
Float descender,
|
|
Float capHeight,
|
|
Float ascender,
|
|
Float xHeight);
|
|
LineMeasurement(const folly::dynamic& data);
|
|
bool operator==(const LineMeasurement& rhs) const;
|
|
static inline Float baseline(const std::vector<LineMeasurement>& lines) {
|
|
if (!lines.empty()) {
|
|
return lines[0].ascender;
|
|
}
|
|
return 0;
|
|
}
|
|
};
|
|
using LinesMeasurements = std::vector<LineMeasurement>;
|
|
class TextMeasurement final {
|
|
public:
|
|
class Attachment final {
|
|
public:
|
|
Rect frame;
|
|
bool isClipped;
|
|
};
|
|
using Attachments = std::vector<Attachment>;
|
|
Size size;
|
|
Attachments attachments;
|
|
};
|
|
class TextMeasureCacheKey final {
|
|
public:
|
|
AttributedString attributedString{};
|
|
ParagraphAttributes paragraphAttributes{};
|
|
LayoutConstraints layoutConstraints{};
|
|
};
|
|
class LineMeasureCacheKey final {
|
|
public:
|
|
AttributedString attributedString{};
|
|
ParagraphAttributes paragraphAttributes{};
|
|
Size size{};
|
|
};
|
|
class PreparedTextCacheKey final {
|
|
public:
|
|
AttributedString attributedString{};
|
|
ParagraphAttributes paragraphAttributes{};
|
|
LayoutConstraints layoutConstraints{};
|
|
};
|
|
constexpr auto kSimpleThreadSafeCacheSizeCap = size_t{1024};
|
|
using TextMeasureCache = SimpleThreadSafeCache<
|
|
TextMeasureCacheKey,
|
|
TextMeasurement,
|
|
kSimpleThreadSafeCacheSizeCap>;
|
|
using LineMeasureCache = SimpleThreadSafeCache<
|
|
LineMeasureCacheKey,
|
|
LinesMeasurements,
|
|
kSimpleThreadSafeCacheSizeCap>;
|
|
inline bool areTextAttributesEquivalentLayoutWise(
|
|
const TextAttributes& lhs,
|
|
const TextAttributes& rhs) {
|
|
return std::tie(
|
|
lhs.fontFamily,
|
|
lhs.fontWeight,
|
|
lhs.fontStyle,
|
|
lhs.fontVariant,
|
|
lhs.allowFontScaling,
|
|
lhs.dynamicTypeRamp,
|
|
lhs.alignment) ==
|
|
std::tie(
|
|
rhs.fontFamily,
|
|
rhs.fontWeight,
|
|
rhs.fontStyle,
|
|
rhs.fontVariant,
|
|
rhs.allowFontScaling,
|
|
rhs.dynamicTypeRamp,
|
|
rhs.alignment) &&
|
|
floatEquality(lhs.fontSize, rhs.fontSize) &&
|
|
floatEquality(lhs.fontSizeMultiplier, rhs.fontSizeMultiplier) &&
|
|
floatEquality(lhs.letterSpacing, rhs.letterSpacing) &&
|
|
floatEquality(lhs.lineHeight, rhs.lineHeight);
|
|
}
|
|
inline size_t textAttributesHashLayoutWise(
|
|
const TextAttributes& textAttributes) {
|
|
return facebook::react::hash_combine(
|
|
textAttributes.fontFamily,
|
|
textAttributes.fontSize,
|
|
textAttributes.fontSizeMultiplier,
|
|
textAttributes.fontWeight,
|
|
textAttributes.fontStyle,
|
|
textAttributes.fontVariant,
|
|
textAttributes.allowFontScaling,
|
|
textAttributes.dynamicTypeRamp,
|
|
textAttributes.letterSpacing,
|
|
textAttributes.lineHeight,
|
|
textAttributes.alignment);
|
|
}
|
|
inline bool areAttributedStringFragmentsEquivalentLayoutWise(
|
|
const AttributedString::Fragment& lhs,
|
|
const AttributedString::Fragment& rhs) {
|
|
return lhs.string == rhs.string &&
|
|
areTextAttributesEquivalentLayoutWise(
|
|
lhs.textAttributes, rhs.textAttributes) &&
|
|
(!lhs.isAttachment() ||
|
|
(lhs.parentShadowView.layoutMetrics ==
|
|
rhs.parentShadowView.layoutMetrics));
|
|
}
|
|
inline bool areAttributedStringFragmentsEquivalentDisplayWise(
|
|
const AttributedString::Fragment& lhs,
|
|
const AttributedString::Fragment& rhs) {
|
|
return lhs.isContentEqual(rhs) &&
|
|
(!lhs.isAttachment() ||
|
|
(lhs.parentShadowView.layoutMetrics ==
|
|
rhs.parentShadowView.layoutMetrics));
|
|
}
|
|
inline size_t attributedStringFragmentHashLayoutWise(
|
|
const AttributedString::Fragment& fragment) {
|
|
return facebook::react::hash_combine(
|
|
fragment.string, textAttributesHashLayoutWise(fragment.textAttributes));
|
|
}
|
|
inline size_t attributedStringFragmentHashDisplayWise(
|
|
const AttributedString::Fragment& fragment) {
|
|
return facebook::react::hash_combine(
|
|
fragment.string, fragment.textAttributes);
|
|
}
|
|
inline bool areAttributedStringsEquivalentLayoutWise(
|
|
const AttributedString& lhs,
|
|
const AttributedString& rhs) {
|
|
auto& lhsFragment = lhs.getFragments();
|
|
auto& rhsFragment = rhs.getFragments();
|
|
if (lhsFragment.size() != rhsFragment.size()) {
|
|
return false;
|
|
}
|
|
auto size = lhsFragment.size();
|
|
for (auto i = size_t{0}; i < size; i++) {
|
|
if (!areAttributedStringFragmentsEquivalentLayoutWise(
|
|
lhsFragment.at(i), rhsFragment.at(i))) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
inline bool areAttributedStringsEquivalentDisplayWise(
|
|
const AttributedString& lhs,
|
|
const AttributedString& rhs) {
|
|
auto& lhsFragment = lhs.getFragments();
|
|
auto& rhsFragment = rhs.getFragments();
|
|
if (lhsFragment.size() != rhsFragment.size()) {
|
|
return false;
|
|
}
|
|
auto size = lhsFragment.size();
|
|
for (size_t i = 0; i < size; i++) {
|
|
if (!areAttributedStringFragmentsEquivalentDisplayWise(
|
|
lhsFragment.at(i), rhsFragment.at(i))) {
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
inline size_t attributedStringHashLayoutWise(
|
|
const AttributedString& attributedString) {
|
|
auto seed = size_t{0};
|
|
for (const auto& fragment : attributedString.getFragments()) {
|
|
facebook::react::hash_combine(
|
|
seed, attributedStringFragmentHashLayoutWise(fragment));
|
|
}
|
|
return seed;
|
|
}
|
|
inline size_t attributedStringHashDisplayWise(
|
|
const AttributedString& attributedString) {
|
|
size_t seed = 0;
|
|
for (const auto& fragment : attributedString.getFragments()) {
|
|
facebook::react::hash_combine(
|
|
seed, attributedStringFragmentHashDisplayWise(fragment));
|
|
}
|
|
return seed;
|
|
}
|
|
inline bool operator==(
|
|
const TextMeasureCacheKey& lhs,
|
|
const TextMeasureCacheKey& rhs) {
|
|
return areAttributedStringsEquivalentLayoutWise(
|
|
lhs.attributedString, rhs.attributedString) &&
|
|
lhs.paragraphAttributes == rhs.paragraphAttributes &&
|
|
lhs.layoutConstraints == rhs.layoutConstraints;
|
|
}
|
|
inline bool operator==(
|
|
const LineMeasureCacheKey& lhs,
|
|
const LineMeasureCacheKey& rhs) {
|
|
return areAttributedStringsEquivalentLayoutWise(
|
|
lhs.attributedString, rhs.attributedString) &&
|
|
lhs.paragraphAttributes == rhs.paragraphAttributes &&
|
|
lhs.size == rhs.size;
|
|
}
|
|
inline bool operator==(
|
|
const PreparedTextCacheKey& lhs,
|
|
const PreparedTextCacheKey& rhs) {
|
|
return areAttributedStringsEquivalentDisplayWise(
|
|
lhs.attributedString, rhs.attributedString) &&
|
|
lhs.paragraphAttributes == rhs.paragraphAttributes &&
|
|
lhs.layoutConstraints == rhs.layoutConstraints;
|
|
}
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::TextMeasureCacheKey> {
|
|
size_t operator()(const facebook::react::TextMeasureCacheKey& key) const {
|
|
return facebook::react::hash_combine(
|
|
attributedStringHashLayoutWise(key.attributedString),
|
|
key.paragraphAttributes,
|
|
key.layoutConstraints);
|
|
}
|
|
};
|
|
template <>
|
|
struct hash<facebook::react::LineMeasureCacheKey> {
|
|
size_t operator()(const facebook::react::LineMeasureCacheKey& key) const {
|
|
return facebook::react::hash_combine(
|
|
attributedStringHashLayoutWise(key.attributedString),
|
|
key.paragraphAttributes,
|
|
key.size);
|
|
}
|
|
};
|
|
template <>
|
|
struct hash<facebook::react::PreparedTextCacheKey> {
|
|
size_t operator()(const facebook::react::PreparedTextCacheKey& key) const {
|
|
return facebook::react::hash_combine(
|
|
attributedStringHashDisplayWise(key.attributedString),
|
|
key.paragraphAttributes,
|
|
key.layoutConstraints);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/JPreparedLayout.h}:
|
|
namespace facebook::react {
|
|
class JPreparedLayout : public jni::JavaClass<JPreparedLayout> {
|
|
public:
|
|
static auto constexpr kJavaDescriptor =
|
|
"Lcom/facebook/react/views/text/PreparedLayout;";
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/android/react/renderer/textlayoutmanager/TextLayoutManager.h}:
|
|
namespace facebook::react {
|
|
class TextLayoutManager {
|
|
public:
|
|
using PreparedLayout = SafeReleaseJniRef<jni::global_ref<JPreparedLayout>>;
|
|
TextLayoutManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer);
|
|
TextLayoutManager(const TextLayoutManager&) = delete;
|
|
TextLayoutManager& operator=(const TextLayoutManager&) = delete;
|
|
TextLayoutManager(TextLayoutManager&&) = delete;
|
|
TextLayoutManager& operator=(TextLayoutManager&&) = delete;
|
|
TextMeasurement measure(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
TextMeasurement measureCachedSpannableById(
|
|
int64_t cacheId,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
LinesMeasurements measureLines(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const Size& size) const;
|
|
PreparedLayout prepareLayout(
|
|
const AttributedString& attributedString,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
TextMeasurement measurePreparedLayout(
|
|
const PreparedLayout& layout,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/cxx/react/renderer/textlayoutmanager/TextLayoutManager.h}:
|
|
namespace facebook::react {
|
|
class TextLayoutManager {
|
|
public:
|
|
explicit TextLayoutManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer);
|
|
virtual ~TextLayoutManager() = default;
|
|
TextLayoutManager(const TextLayoutManager&) = delete;
|
|
TextLayoutManager& operator=(const TextLayoutManager&) = delete;
|
|
TextLayoutManager(TextLayoutManager&&) = delete;
|
|
TextLayoutManager& operator=(TextLayoutManager&&) = delete;
|
|
virtual TextMeasurement measure(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
|
|
protected:
|
|
std::shared_ptr<const ContextContainer> contextContainer_;
|
|
TextMeasureCache textMeasureCache_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
NSString *const RCTAttributedStringIsHighlightedAttributeName = @"IsHighlighted";
|
|
NSString *const RCTAttributedStringEventEmitterKey = @"EventEmitter";
|
|
NSString *const RCTTextAttributesAccessibilityRoleAttributeName = @"AccessibilityRole";
|
|
NSMutableDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(
|
|
const facebook::react::TextAttributes &textAttributes);
|
|
NSAttributedString *RCTNSAttributedStringFromAttributedString(
|
|
const facebook::react::AttributedString &attributedString);
|
|
NSAttributedString *RCTNSAttributedStringFromAttributedStringBox(
|
|
const facebook::react::AttributedStringBox &attributedStringBox);
|
|
facebook::react::AttributedStringBox RCTAttributedStringBoxFromNSAttributedString(
|
|
NSAttributedString *nsAttributedString);
|
|
NSString *RCTNSStringFromStringApplyingTextTransform(NSString *string, facebook::react::TextTransform textTransform);
|
|
void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText);
|
|
BOOL RCTIsAttributedStringEffectivelySame(
|
|
NSAttributedString *text1,
|
|
NSAttributedString *text2,
|
|
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
|
const facebook::react::TextAttributes &baseTextAttributes);
|
|
static inline NSData *RCTWrapEventEmitter(const facebook::react::SharedEventEmitter &eventEmitter)
|
|
{
|
|
auto eventEmitterPtr = new std::weak_ptr<const facebook::react::EventEmitter>(eventEmitter);
|
|
return [[NSData alloc] initWithBytesNoCopy:eventEmitterPtr
|
|
length:sizeof(eventEmitterPtr)
|
|
deallocator:^(void *ptrToDelete, NSUInteger) {
|
|
delete (std::weak_ptr<facebook::react::EventEmitter> *)ptrToDelete;
|
|
}];
|
|
}
|
|
static inline facebook::react::SharedEventEmitter RCTUnwrapEventEmitter(NSData *data)
|
|
{
|
|
if (data.length == 0) {
|
|
return nullptr;
|
|
}
|
|
auto weakPtr = dynamic_cast<std::weak_ptr<const facebook::react::EventEmitter> *>(
|
|
(std::weak_ptr<const facebook::react::EventEmitter> *)data.bytes);
|
|
if (weakPtr) {
|
|
return weakPtr->lock();
|
|
}
|
|
return nullptr;
|
|
}
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTFontProperties.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_ENUM(NSInteger, RCTFontStyle) {
|
|
RCTFontStyleUndefined = -1,
|
|
RCTFontStyleNormal,
|
|
RCTFontStyleItalic,
|
|
RCTFontStyleOblique,
|
|
};
|
|
typedef NS_OPTIONS(NSInteger, RCTFontVariant) {
|
|
RCTFontVariantUndefined = -1,
|
|
RCTFontVariantDefault = 0,
|
|
RCTFontVariantSmallCaps = 1 << 1,
|
|
RCTFontVariantOldstyleNums = 1 << 2,
|
|
RCTFontVariantLiningNums = 1 << 3,
|
|
RCTFontVariantTabularNums = 1 << 4,
|
|
RCTFontVariantProportionalNums = 1 << 5,
|
|
RCTFontVariantStylisticOne = 1 << 6,
|
|
RCTFontVariantStylisticTwo = 1 << 7,
|
|
RCTFontVariantStylisticThree = 1 << 8,
|
|
RCTFontVariantStylisticFour = 1 << 9,
|
|
RCTFontVariantStylisticFive = 1 << 10,
|
|
RCTFontVariantStylisticSix = 1 << 11,
|
|
RCTFontVariantStylisticSeven = 1 << 12,
|
|
RCTFontVariantStylisticEight = 1 << 13,
|
|
RCTFontVariantStylisticNine = 1 << 14,
|
|
RCTFontVariantStylisticTen = 1 << 15,
|
|
RCTFontVariantStylisticEleven = 1 << 16,
|
|
RCTFontVariantStylisticTwelve = 1 << 17,
|
|
RCTFontVariantStylisticThirteen = 1 << 18,
|
|
RCTFontVariantStylisticFourteen = 1 << 19,
|
|
RCTFontVariantStylisticFifteen = 1 << 20,
|
|
RCTFontVariantStylisticSixteen = 1 << 21,
|
|
RCTFontVariantStylisticSeventeen = 1 << 22,
|
|
RCTFontVariantStylisticEighteen = 1 << 23,
|
|
RCTFontVariantStylisticNineteen = 1 << 24,
|
|
RCTFontVariantStylisticTwenty = 1 << 25,
|
|
};
|
|
struct RCTFontProperties {
|
|
NSString *family = nil;
|
|
CGFloat size = NAN;
|
|
UIFontWeight weight = NAN;
|
|
RCTFontStyle style = RCTFontStyleUndefined;
|
|
RCTFontVariant variant = RCTFontVariantUndefined;
|
|
CGFloat sizeMultiplier = NAN;
|
|
};
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTFontUtils.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTFontUtils.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTTextLayoutManager.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextPrimitivesConversions.h}:
|
|
inline static NSTextAlignment RCTNSTextAlignmentFromTextAlignment(facebook::react::TextAlignment textAlignment)
|
|
{
|
|
switch (textAlignment) {
|
|
case facebook::react::TextAlignment::Natural:
|
|
return NSTextAlignmentNatural;
|
|
case facebook::react::TextAlignment::Left:
|
|
return NSTextAlignmentLeft;
|
|
case facebook::react::TextAlignment::Right:
|
|
return NSTextAlignmentRight;
|
|
case facebook::react::TextAlignment::Center:
|
|
return NSTextAlignmentCenter;
|
|
case facebook::react::TextAlignment::Justified:
|
|
return NSTextAlignmentJustified;
|
|
}
|
|
}
|
|
inline static NSWritingDirection RCTNSWritingDirectionFromWritingDirection(
|
|
facebook::react::WritingDirection writingDirection)
|
|
{
|
|
switch (writingDirection) {
|
|
case facebook::react::WritingDirection::Natural:
|
|
return NSWritingDirectionNatural;
|
|
case facebook::react::WritingDirection::LeftToRight:
|
|
return NSWritingDirectionLeftToRight;
|
|
case facebook::react::WritingDirection::RightToLeft:
|
|
return NSWritingDirectionRightToLeft;
|
|
}
|
|
}
|
|
inline static NSLineBreakStrategy RCTNSLineBreakStrategyFromLineBreakStrategy(
|
|
facebook::react::LineBreakStrategy lineBreakStrategy)
|
|
{
|
|
switch (lineBreakStrategy) {
|
|
case facebook::react::LineBreakStrategy::None:
|
|
return NSLineBreakStrategyNone;
|
|
case facebook::react::LineBreakStrategy::PushOut:
|
|
return NSLineBreakStrategyPushOut;
|
|
case facebook::react::LineBreakStrategy::HangulWordPriority:
|
|
if (@available(iOS 14.0, *)) {
|
|
return NSLineBreakStrategyHangulWordPriority;
|
|
} else {
|
|
return NSLineBreakStrategyNone;
|
|
}
|
|
case facebook::react::LineBreakStrategy::Standard:
|
|
if (@available(iOS 14.0, *)) {
|
|
return NSLineBreakStrategyStandard;
|
|
} else {
|
|
return NSLineBreakStrategyNone;
|
|
}
|
|
}
|
|
}
|
|
inline static NSLineBreakMode RCTNSLineBreakModeFromLineBreakMode(facebook::react::LineBreakMode lineBreakMode)
|
|
{
|
|
switch (lineBreakMode) {
|
|
case facebook::react::LineBreakMode::Word:
|
|
return NSLineBreakByWordWrapping;
|
|
case facebook::react::LineBreakMode::Char:
|
|
return NSLineBreakByCharWrapping;
|
|
case facebook::react::LineBreakMode::Clip:
|
|
return NSLineBreakByClipping;
|
|
case facebook::react::LineBreakMode::Head:
|
|
return NSLineBreakByTruncatingHead;
|
|
case facebook::react::LineBreakMode::Middle:
|
|
return NSLineBreakByTruncatingMiddle;
|
|
case facebook::react::LineBreakMode::Tail:
|
|
return NSLineBreakByTruncatingTail;
|
|
}
|
|
}
|
|
inline static RCTFontStyle RCTFontStyleFromFontStyle(facebook::react::FontStyle fontStyle)
|
|
{
|
|
switch (fontStyle) {
|
|
case facebook::react::FontStyle::Normal:
|
|
return RCTFontStyleNormal;
|
|
case facebook::react::FontStyle::Italic:
|
|
return RCTFontStyleItalic;
|
|
case facebook::react::FontStyle::Oblique:
|
|
return RCTFontStyleOblique;
|
|
}
|
|
}
|
|
inline static RCTFontVariant RCTFontVariantFromFontVariant(facebook::react::FontVariant fontVariant)
|
|
{
|
|
return (RCTFontVariant)fontVariant;
|
|
}
|
|
inline static NSUnderlineStyle RCTNSUnderlineStyleFromTextDecorationStyle(
|
|
facebook::react::TextDecorationStyle textDecorationStyle)
|
|
{
|
|
switch (textDecorationStyle) {
|
|
case facebook::react::TextDecorationStyle::Solid:
|
|
return NSUnderlineStyleSingle;
|
|
case facebook::react::TextDecorationStyle::Double:
|
|
return NSUnderlineStyleDouble;
|
|
case facebook::react::TextDecorationStyle::Dashed:
|
|
return NSUnderlineStylePatternDash | NSUnderlineStyleSingle;
|
|
case facebook::react::TextDecorationStyle::Dotted:
|
|
return NSUnderlineStylePatternDot | NSUnderlineStyleSingle;
|
|
}
|
|
}
|
|
inline static UIColor *_Nullable RCTUIColorFromSharedColor(const facebook::react::SharedColor &sharedColor)
|
|
{
|
|
return RCTPlatformColorFromColor(*sharedColor);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/TextLayoutManager.h}:
|
|
namespace facebook::react {
|
|
class TextLayoutManager {
|
|
public:
|
|
TextLayoutManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer);
|
|
TextLayoutManager(const TextLayoutManager&) = delete;
|
|
TextLayoutManager& operator=(const TextLayoutManager&) = delete;
|
|
TextLayoutManager(TextLayoutManager&&) = delete;
|
|
TextLayoutManager& operator=(TextLayoutManager&&) = delete;
|
|
TextMeasurement measure(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
LinesMeasurements measureLines(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const Size& size) const;
|
|
std::shared_ptr<void> getNativeTextLayoutManager() const;
|
|
|
|
protected:
|
|
std::shared_ptr<const ContextContainer> contextContainer_;
|
|
std::shared_ptr<void> nativeTextLayoutManager_;
|
|
TextMeasureCache textMeasureCache_;
|
|
LineMeasureCache lineMeasureCache_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTAttributedTextUtils.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
NSString *const RCTAttributedStringIsHighlightedAttributeName = @"IsHighlighted";
|
|
NSString *const RCTAttributedStringEventEmitterKey = @"EventEmitter";
|
|
NSString *const RCTTextAttributesAccessibilityRoleAttributeName = @"AccessibilityRole";
|
|
NSMutableDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(
|
|
const facebook::react::TextAttributes &textAttributes);
|
|
NSAttributedString *RCTNSAttributedStringFromAttributedString(
|
|
const facebook::react::AttributedString &attributedString);
|
|
NSAttributedString *RCTNSAttributedStringFromAttributedStringBox(
|
|
const facebook::react::AttributedStringBox &attributedStringBox);
|
|
facebook::react::AttributedStringBox RCTAttributedStringBoxFromNSAttributedString(
|
|
NSAttributedString *nsAttributedString);
|
|
NSString *RCTNSStringFromStringApplyingTextTransform(NSString *string, facebook::react::TextTransform textTransform);
|
|
void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText);
|
|
BOOL RCTIsAttributedStringEffectivelySame(
|
|
NSAttributedString *text1,
|
|
NSAttributedString *text2,
|
|
NSDictionary<NSAttributedStringKey, id> *insensitiveAttributes,
|
|
const facebook::react::TextAttributes &baseTextAttributes);
|
|
@interface RCTWeakEventEmitterWrapper : NSObject
|
|
@property (nonatomic, assign) facebook::react::SharedEventEmitter eventEmitter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTFontProperties.h}:
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NS_ENUM(NSInteger, RCTFontStyle) {
|
|
RCTFontStyleUndefined = -1,
|
|
RCTFontStyleNormal,
|
|
RCTFontStyleItalic,
|
|
RCTFontStyleOblique,
|
|
};
|
|
typedef NS_OPTIONS(NSInteger, RCTFontVariant) {
|
|
RCTFontVariantUndefined = -1,
|
|
RCTFontVariantDefault = 0,
|
|
RCTFontVariantSmallCaps = 1 << 1,
|
|
RCTFontVariantOldstyleNums = 1 << 2,
|
|
RCTFontVariantLiningNums = 1 << 3,
|
|
RCTFontVariantTabularNums = 1 << 4,
|
|
RCTFontVariantProportionalNums = 1 << 5,
|
|
};
|
|
struct RCTFontProperties {
|
|
NSString *family = nil;
|
|
CGFloat size = NAN;
|
|
UIFontWeight weight = NAN;
|
|
RCTFontStyle style = RCTFontStyleUndefined;
|
|
RCTFontVariant variant = RCTFontVariantUndefined;
|
|
CGFloat sizeMultiplier = NAN;
|
|
};
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTFontUtils.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTFontUtils.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTTextLayoutManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/RCTTextPrimitivesConversions.h}:
|
|
inline static NSTextAlignment RCTNSTextAlignmentFromTextAlignment(facebook::react::TextAlignment textAlignment)
|
|
{
|
|
switch (textAlignment) {
|
|
case facebook::react::TextAlignment::Natural:
|
|
return NSTextAlignmentNatural;
|
|
case facebook::react::TextAlignment::Left:
|
|
return NSTextAlignmentLeft;
|
|
case facebook::react::TextAlignment::Right:
|
|
return NSTextAlignmentRight;
|
|
case facebook::react::TextAlignment::Center:
|
|
return NSTextAlignmentCenter;
|
|
case facebook::react::TextAlignment::Justified:
|
|
return NSTextAlignmentJustified;
|
|
}
|
|
}
|
|
inline static NSWritingDirection RCTNSWritingDirectionFromWritingDirection(
|
|
facebook::react::WritingDirection writingDirection)
|
|
{
|
|
switch (writingDirection) {
|
|
case facebook::react::WritingDirection::Natural:
|
|
return NSWritingDirectionNatural;
|
|
case facebook::react::WritingDirection::LeftToRight:
|
|
return NSWritingDirectionLeftToRight;
|
|
case facebook::react::WritingDirection::RightToLeft:
|
|
return NSWritingDirectionRightToLeft;
|
|
}
|
|
}
|
|
inline static NSLineBreakStrategy RCTNSLineBreakStrategyFromLineBreakStrategy(
|
|
facebook::react::LineBreakStrategy lineBreakStrategy)
|
|
{
|
|
switch (lineBreakStrategy) {
|
|
case facebook::react::LineBreakStrategy::None:
|
|
return NSLineBreakStrategyNone;
|
|
case facebook::react::LineBreakStrategy::PushOut:
|
|
return NSLineBreakStrategyPushOut;
|
|
case facebook::react::LineBreakStrategy::HangulWordPriority:
|
|
if (@available(iOS 14.0, macOS 11.0, *)) {
|
|
return NSLineBreakStrategyHangulWordPriority;
|
|
} else {
|
|
return NSLineBreakStrategyNone;
|
|
}
|
|
case facebook::react::LineBreakStrategy::Standard:
|
|
if (@available(iOS 14.0, macOS 11.0, *)) {
|
|
return NSLineBreakStrategyStandard;
|
|
} else {
|
|
return NSLineBreakStrategyNone;
|
|
}
|
|
}
|
|
}
|
|
inline static NSLineBreakMode RCTNSLineBreakModeFromLineBreakMode(facebook::react::LineBreakMode lineBreakMode)
|
|
{
|
|
switch (lineBreakMode) {
|
|
case facebook::react::LineBreakMode::Word:
|
|
return NSLineBreakByWordWrapping;
|
|
case facebook::react::LineBreakMode::Char:
|
|
return NSLineBreakByCharWrapping;
|
|
case facebook::react::LineBreakMode::Clip:
|
|
return NSLineBreakByClipping;
|
|
case facebook::react::LineBreakMode::Head:
|
|
return NSLineBreakByTruncatingHead;
|
|
case facebook::react::LineBreakMode::Middle:
|
|
return NSLineBreakByTruncatingMiddle;
|
|
case facebook::react::LineBreakMode::Tail:
|
|
return NSLineBreakByTruncatingTail;
|
|
}
|
|
}
|
|
inline static RCTFontStyle RCTFontStyleFromFontStyle(facebook::react::FontStyle fontStyle)
|
|
{
|
|
switch (fontStyle) {
|
|
case facebook::react::FontStyle::Normal:
|
|
return RCTFontStyleNormal;
|
|
case facebook::react::FontStyle::Italic:
|
|
return RCTFontStyleItalic;
|
|
case facebook::react::FontStyle::Oblique:
|
|
return RCTFontStyleOblique;
|
|
}
|
|
}
|
|
inline static RCTFontVariant RCTFontVariantFromFontVariant(facebook::react::FontVariant fontVariant)
|
|
{
|
|
return (RCTFontVariant)fontVariant;
|
|
}
|
|
inline static NSUnderlineStyle RCTNSUnderlineStyleFromTextDecorationStyle(
|
|
facebook::react::TextDecorationStyle textDecorationStyle)
|
|
{
|
|
switch (textDecorationStyle) {
|
|
case facebook::react::TextDecorationStyle::Solid:
|
|
return NSUnderlineStyleSingle;
|
|
case facebook::react::TextDecorationStyle::Double:
|
|
return NSUnderlineStyleDouble;
|
|
case facebook::react::TextDecorationStyle::Dashed:
|
|
return NSUnderlinePatternDash | NSUnderlineStyleSingle;
|
|
case facebook::react::TextDecorationStyle::Dotted:
|
|
return NSUnderlinePatternDot | NSUnderlineStyleSingle;
|
|
}
|
|
}
|
|
inline static RCTUIColor *_Nullable RCTUIColorFromSharedColor(const facebook::react::SharedColor &sharedColor)
|
|
{
|
|
return RCTPlatformColorFromColor(*sharedColor);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/macos/react/renderer/textlayoutmanager/TextLayoutManager.h}:
|
|
namespace facebook::react {
|
|
class TextLayoutManager {
|
|
public:
|
|
TextLayoutManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer);
|
|
TextLayoutManager(const TextLayoutManager&) = delete;
|
|
TextLayoutManager& operator=(const TextLayoutManager&) = delete;
|
|
TextLayoutManager(TextLayoutManager&&) = delete;
|
|
TextLayoutManager& operator=(TextLayoutManager&&) = delete;
|
|
TextMeasurement measure(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
LinesMeasurements measureLines(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const Size& size) const;
|
|
std::shared_ptr<void> getNativeTextLayoutManager() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/windows/third-party/TextLayoutManager.h}:
|
|
namespace facebook::react {
|
|
class TextLayoutManager {
|
|
public:
|
|
TextLayoutManager(
|
|
const std::shared_ptr<const ContextContainer>& contextContainer);
|
|
TextLayoutManager(const TextLayoutManager&) = delete;
|
|
TextLayoutManager& operator=(const TextLayoutManager&) = delete;
|
|
TextLayoutManager(TextLayoutManager&&) = delete;
|
|
TextLayoutManager& operator=(TextLayoutManager&&) = delete;
|
|
TextMeasurement measure(
|
|
const AttributedStringBox& attributedStringBox,
|
|
const ParagraphAttributes& paragraphAttributes,
|
|
const TextLayoutContext& layoutContext,
|
|
const LayoutConstraints& layoutConstraints) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/windows/third-party/TextLayoutUtil.h}:
|
|
namespace facebook::react {
|
|
class TextLayoutInlineObject : public Mso::UnknownObject<IDWriteInlineObject> {
|
|
public:
|
|
TextLayoutInlineObject(Float inWidth, Float inHeight)
|
|
: width{inWidth}, height{inHeight} {}
|
|
HRESULT Draw(
|
|
void* clientDrawingContext,
|
|
IDWriteTextRenderer* renderer,
|
|
FLOAT originX,
|
|
FLOAT originY,
|
|
BOOL isSideways,
|
|
BOOL isRightToLeft,
|
|
IUnknown* clientDrawingEffect) noexcept override {
|
|
return S_OK;
|
|
}
|
|
HRESULT GetBreakConditions(
|
|
DWRITE_BREAK_CONDITION* breakConditionBefore,
|
|
DWRITE_BREAK_CONDITION* breakConditionAfter) noexcept override {
|
|
*breakConditionBefore = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK;
|
|
*breakConditionAfter = DWRITE_BREAK_CONDITION_MAY_NOT_BREAK;
|
|
return S_OK;
|
|
}
|
|
HRESULT GetMetrics(DWRITE_INLINE_OBJECT_METRICS* metrics) noexcept override {
|
|
metrics->width = width;
|
|
metrics->height = height;
|
|
metrics->baseline = height;
|
|
metrics->supportsSideways = false;
|
|
return S_OK;
|
|
}
|
|
HRESULT GetOverhangMetrics(
|
|
DWRITE_OVERHANG_METRICS* overhangs) noexcept override {
|
|
*overhangs = DWRITE_OVERHANG_METRICS{};
|
|
return S_OK;
|
|
}
|
|
facebook::react::Float width{};
|
|
facebook::react::Float height{};
|
|
};
|
|
struct AttachmentItem {
|
|
Mso::CntPtr<TextLayoutInlineObject> inlineObject;
|
|
uint32_t position;
|
|
};
|
|
class TextLayoutUtil {
|
|
public:
|
|
static void GetTextLayout(
|
|
AttributedStringBox attributedStringBox,
|
|
ParagraphAttributes paragraphAttributes,
|
|
LayoutConstraints layoutConstraints,
|
|
std::vector<AttachmentItem>& attachments,
|
|
winrt::com_ptr<IDWriteTextLayout>& spTextLayout) noexcept;
|
|
static void InitializeCustomFonts(
|
|
const std::vector<std::wstring>& customFontPaths);
|
|
static Float GetScaledFontSize(
|
|
Float value,
|
|
Float fontScale,
|
|
std::optional<bool> allowFontScaling) noexcept;
|
|
static Microsoft::ReactNative::TextTransform ConvertTextTransform(
|
|
const std::optional<facebook::react::TextTransform>& transform) noexcept;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/AppRegistryBinding.h}:
|
|
namespace facebook::react {
|
|
class AppRegistryBinding final {
|
|
public:
|
|
AppRegistryBinding() = delete;
|
|
static void startSurface(
|
|
jsi::Runtime& runtime,
|
|
SurfaceId surfaceId,
|
|
const std::string& moduleName,
|
|
const folly::dynamic& initialProps,
|
|
DisplayMode displayMode);
|
|
static void setSurfaceProps(
|
|
jsi::Runtime& runtime,
|
|
SurfaceId surfaceId,
|
|
const std::string& moduleName,
|
|
const folly::dynamic& initialProps,
|
|
DisplayMode displayMode);
|
|
static void stopSurface(jsi::Runtime& runtime, SurfaceId surfaceId);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/LayoutAnimationStatusDelegate.h}:
|
|
namespace facebook::react {
|
|
class LayoutAnimationStatusDelegate {
|
|
public:
|
|
virtual void onAnimationStarted() = 0;
|
|
virtual void onAllAnimationsComplete() = 0;
|
|
virtual ~LayoutAnimationStatusDelegate() = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/PointerEventsProcessor.h}:
|
|
namespace facebook::react {
|
|
struct PointerEventTarget {
|
|
PointerEvent event;
|
|
std::shared_ptr<const ShadowNode> target;
|
|
};
|
|
struct ActivePointer {
|
|
PointerEvent event;
|
|
bool shouldLeaveWhenReleased{};
|
|
};
|
|
using DispatchEvent = std::function<void(
|
|
const ShadowNode& targetNode,
|
|
const std::string& type,
|
|
ReactEventPriority priority,
|
|
const EventPayload& payload)>;
|
|
using PointerIdentifier = int32_t;
|
|
using CaptureTargetOverrideRegistry =
|
|
std::unordered_map<PointerIdentifier, std::weak_ptr<const ShadowNode>>;
|
|
using ActivePointerRegistry =
|
|
std::unordered_map<PointerIdentifier, ActivePointer>;
|
|
using PointerHoverTrackerRegistry =
|
|
std::unordered_map<PointerIdentifier, PointerHoverTracker::Unique>;
|
|
class PointerEventsProcessor final {
|
|
public:
|
|
static std::shared_ptr<const ShadowNode> getShadowNodeFromEventTarget(
|
|
jsi::Runtime& runtime,
|
|
const EventTarget* target);
|
|
void interceptPointerEvent(
|
|
const std::shared_ptr<const ShadowNode>& target,
|
|
const std::string& type,
|
|
ReactEventPriority priority,
|
|
const PointerEvent& event,
|
|
const DispatchEvent& eventDispatcher,
|
|
const UIManager& uiManager);
|
|
void setPointerCapture(
|
|
PointerIdentifier pointerId,
|
|
const std::shared_ptr<const ShadowNode>& shadowNode);
|
|
void releasePointerCapture(
|
|
PointerIdentifier pointerId,
|
|
const ShadowNode* shadowNode);
|
|
bool hasPointerCapture(
|
|
PointerIdentifier pointerId,
|
|
const ShadowNode* shadowNode);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/PointerHoverTracker.h}:
|
|
namespace facebook::react {
|
|
class PointerHoverTracker {
|
|
public:
|
|
using Unique = std::unique_ptr<PointerHoverTracker>;
|
|
using EventPath = std::vector<std::reference_wrapper<const ShadowNode>>;
|
|
PointerHoverTracker(
|
|
std::shared_ptr<const ShadowNode> target,
|
|
const UIManager& uiManager);
|
|
const ShadowNode* getTarget(const UIManager& uiManager) const;
|
|
bool hasSameTarget(const PointerHoverTracker& other) const;
|
|
bool areAnyTargetsListeningToEvents(
|
|
std::initializer_list<ViewEvents::Offset> eventTypes,
|
|
const UIManager& uiManager) const;
|
|
std::tuple<EventPath, EventPath> diffEventPath(
|
|
const PointerHoverTracker& other,
|
|
const UIManager& uiManager) const;
|
|
void markAsOld();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/SurfaceRegistryBinding.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h}:
|
|
namespace facebook::react {
|
|
class UIManager final : public ShadowTreeDelegate {
|
|
public:
|
|
UIManager(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::shared_ptr<const ContextContainer> contextContainer);
|
|
~UIManager() override;
|
|
void setComponentDescriptorRegistry(
|
|
const SharedComponentDescriptorRegistry& componentDescriptorRegistry);
|
|
void setDelegate(UIManagerDelegate* delegate);
|
|
UIManagerDelegate* getDelegate();
|
|
void setAnimationDelegate(UIManagerAnimationDelegate* delegate);
|
|
void stopSurfaceForAnimationDelegate(SurfaceId surfaceId) const;
|
|
void setNativeAnimatedDelegate(
|
|
std::weak_ptr<UIManagerNativeAnimatedDelegate> delegate);
|
|
void animationTick() const;
|
|
void synchronouslyUpdateViewOnUIThread(Tag tag, const folly::dynamic& props);
|
|
void visitBinding(
|
|
const std::function<void(const UIManagerBinding& uiManagerBinding)>&
|
|
callback,
|
|
jsi::Runtime& runtime) const;
|
|
void registerCommitHook(UIManagerCommitHook& commitHook);
|
|
void unregisterCommitHook(UIManagerCommitHook& commitHook);
|
|
void registerMountHook(UIManagerMountHook& mountHook);
|
|
void unregisterMountHook(UIManagerMountHook& mountHook);
|
|
std::shared_ptr<const ShadowNode> getNewestCloneOfShadowNode(
|
|
const ShadowNode& shadowNode) const;
|
|
ShadowTreeRevisionConsistencyManager*
|
|
getShadowTreeRevisionConsistencyManager();
|
|
ShadowTreeRevisionProvider* getShadowTreeRevisionProvider();
|
|
void startSurface(
|
|
ShadowTree::Unique&& shadowTree,
|
|
const std::string& moduleName,
|
|
const folly::dynamic& props,
|
|
DisplayMode displayMode) const noexcept;
|
|
void startEmptySurface(ShadowTree::Unique&& shadowTree) const noexcept;
|
|
void setSurfaceProps(
|
|
SurfaceId surfaceId,
|
|
const std::string& moduleName,
|
|
const folly::dynamic& props,
|
|
DisplayMode displayMode) const noexcept;
|
|
ShadowTree::Unique stopSurface(SurfaceId surfaceId) const;
|
|
void shadowTreeDidFinishTransaction(
|
|
std::shared_ptr<const MountingCoordinator> mountingCoordinator,
|
|
bool mountSynchronously) const override;
|
|
RootShadowNode::Unshared shadowTreeWillCommit(
|
|
const ShadowTree& shadowTree,
|
|
const RootShadowNode::Shared& oldRootShadowNode,
|
|
const RootShadowNode::Unshared& newRootShadowNode,
|
|
const ShadowTree::CommitOptions& commitOptions) const override;
|
|
std::shared_ptr<ShadowNode> createNode(
|
|
Tag tag,
|
|
const std::string& componentName,
|
|
SurfaceId surfaceId,
|
|
RawProps props,
|
|
InstanceHandle::Shared instanceHandle) const;
|
|
std::shared_ptr<ShadowNode> cloneNode(
|
|
const ShadowNode& shadowNode,
|
|
const ShadowNode::SharedListOfShared& children,
|
|
RawProps rawProps) const;
|
|
void appendChild(
|
|
const std::shared_ptr<const ShadowNode>& parentShadowNode,
|
|
const std::shared_ptr<const ShadowNode>& childShadowNode) const;
|
|
void completeSurface(
|
|
SurfaceId surfaceId,
|
|
const ShadowNode::UnsharedListOfShared& rootChildren,
|
|
ShadowTree::CommitOptions commitOptions);
|
|
void setIsJSResponder(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
bool isJSResponder,
|
|
bool blockNativeResponder) const;
|
|
std::shared_ptr<const ShadowNode> findNodeAtPoint(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
Point point) const;
|
|
LayoutMetrics getRelativeLayoutMetrics(
|
|
const ShadowNode& shadowNode,
|
|
const ShadowNode* ancestorShadowNode,
|
|
LayoutableShadowNode::LayoutInspectingPolicy policy) const;
|
|
void updateState(const StateUpdate& stateUpdate) const;
|
|
void dispatchCommand(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args) const;
|
|
void setNativeProps_DEPRECATED(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
RawProps rawProps) const;
|
|
void sendAccessibilityEvent(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
const std::string& eventType);
|
|
std::shared_ptr<const ShadowNode> findShadowNodeByTag_DEPRECATED(
|
|
Tag tag) const;
|
|
const ShadowTreeRegistry& getShadowTreeRegistry() const;
|
|
void reportMount(SurfaceId surfaceId) const;
|
|
void updateShadowTree(
|
|
const std::unordered_map<Tag, folly::dynamic>& tagToProps);
|
|
void addEventListener(std::shared_ptr<const EventListener> listener);
|
|
void removeEventListener(
|
|
const std::shared_ptr<const EventListener>& listener);
|
|
void setOnSurfaceStartCallback(
|
|
UIManagerDelegate::OnSurfaceStartCallback&& callback);
|
|
};
|
|
UIManagerAnimationDelegate* animationDelegate_{nullptr};
|
|
std::weak_ptr<UIManagerNativeAnimatedDelegate> nativeAnimatedDelegate_;
|
|
const RuntimeExecutor runtimeExecutor_{};
|
|
ShadowTreeRegistry shadowTreeRegistry_{};
|
|
std::shared_ptr<const ContextContainer> contextContainer_;
|
|
mutable std::shared_mutex commitHookMutex_;
|
|
mutable std::vector<UIManagerCommitHook*> commitHooks_;
|
|
mutable std::shared_mutex mountHookMutex_;
|
|
mutable std::vector<UIManagerMountHook*> mountHooks_;
|
|
std::unique_ptr<LeakChecker> leakChecker_;
|
|
std::unique_ptr<LazyShadowTreeRevisionConsistencyManager>
|
|
lazyShadowTreeRevisionConsistencyManager_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerAnimationDelegate.h}:
|
|
namespace facebook::react {
|
|
class UIManagerAnimationDelegate {
|
|
public:
|
|
virtual ~UIManagerAnimationDelegate() = default;
|
|
virtual void uiManagerDidConfigureNextLayoutAnimation(
|
|
jsi::Runtime& runtime,
|
|
const RawValue& config,
|
|
const jsi::Value& successCallback,
|
|
const jsi::Value& failureCallback) const = 0;
|
|
virtual void setComponentDescriptorRegistry(
|
|
const SharedComponentDescriptorRegistry& componentDescriptorRegistry) = 0;
|
|
virtual bool shouldAnimateFrame() const = 0;
|
|
virtual void stopSurface(SurfaceId surfaceId) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.h}:
|
|
namespace facebook::react {
|
|
class UIManagerBinding : public jsi::HostObject {
|
|
public:
|
|
static void createAndInstallIfNeeded(
|
|
jsi::Runtime& runtime,
|
|
const std::shared_ptr<UIManager>& uiManager);
|
|
static std::shared_ptr<UIManagerBinding> getBinding(jsi::Runtime& runtime);
|
|
UIManagerBinding(std::shared_ptr<UIManager> uiManager);
|
|
~UIManagerBinding() override;
|
|
void dispatchEvent(
|
|
jsi::Runtime& runtime,
|
|
const EventTarget* eventTarget,
|
|
const std::string& type,
|
|
ReactEventPriority priority,
|
|
const EventPayload& payload) const;
|
|
void invalidate() const;
|
|
jsi::Value get(jsi::Runtime& runtime, const jsi::PropNameID& name) override;
|
|
UIManager& getUIManager();
|
|
PointerEventsProcessor& getPointerEventsProcessor();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerCommitHook.h}:
|
|
namespace facebook::react {
|
|
class UIManagerCommitHook {
|
|
public:
|
|
virtual void commitHookWasRegistered(const UIManager& uiManager) noexcept = 0;
|
|
virtual void commitHookWasUnregistered(
|
|
const UIManager& uiManager) noexcept = 0;
|
|
virtual RootShadowNode::Unshared shadowTreeWillCommit(
|
|
const ShadowTree& shadowTree,
|
|
const RootShadowNode::Shared& oldRootShadowNode,
|
|
const RootShadowNode::Unshared& newRootShadowNode,
|
|
const ShadowTreeCommitOptions&) noexcept {
|
|
return shadowTreeWillCommit(
|
|
shadowTree, oldRootShadowNode, newRootShadowNode);
|
|
}
|
|
virtual RootShadowNode::Unshared shadowTreeWillCommit(
|
|
const ShadowTree&,
|
|
const RootShadowNode::Shared&,
|
|
const RootShadowNode::Unshared& newRootShadowNode) noexcept {
|
|
return newRootShadowNode;
|
|
}
|
|
virtual ~UIManagerCommitHook() noexcept = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerDelegate.h}:
|
|
namespace facebook::react {
|
|
class UIManagerDelegate {
|
|
public:
|
|
virtual void uiManagerDidFinishTransaction(
|
|
std::shared_ptr<const MountingCoordinator> mountingCoordinator,
|
|
bool mountSynchronously) = 0;
|
|
virtual void uiManagerDidCreateShadowNode(const ShadowNode& shadowNode) = 0;
|
|
virtual void uiManagerDidDispatchCommand(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args) = 0;
|
|
virtual void uiManagerDidSendAccessibilityEvent(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
const std::string& eventType) = 0;
|
|
virtual void uiManagerDidSetIsJSResponder(
|
|
const std::shared_ptr<const ShadowNode>& shadowNode,
|
|
bool isJSResponder,
|
|
bool blockNativeResponder) = 0;
|
|
virtual void uiManagerShouldSynchronouslyUpdateViewOnUIThread(
|
|
Tag tag,
|
|
const folly::dynamic& props) = 0;
|
|
virtual void uiManagerDidUpdateShadowTree(
|
|
const std::unordered_map<Tag, folly::dynamic>& tagToProps) = 0;
|
|
virtual void uiManagerShouldAddEventListener(
|
|
std::shared_ptr<const EventListener> listener) = 0;
|
|
virtual void uiManagerShouldRemoveEventListener(
|
|
const std::shared_ptr<const EventListener>& listener) = 0;
|
|
virtual void uiManagerDidStartSurface(const ShadowTree& shadowTree) = 0;
|
|
using OnSurfaceStartCallback =
|
|
std::function<void(const ShadowTree& shadowTree)>;
|
|
virtual void uiManagerShouldSetOnSurfaceStartCallback(
|
|
OnSurfaceStartCallback&& callback) = 0;
|
|
virtual ~UIManagerDelegate() noexcept = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerMountHook.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/renderer/uimanager/UIManager.h}
|
|
|
|
namespace facebook::react {
|
|
class UIManagerMountHook {
|
|
public:
|
|
virtual void shadowTreeDidMount(
|
|
const RootShadowNode::Shared& rootShadowNode,
|
|
HighResTimeStamp mountTime) noexcept = 0;
|
|
virtual void shadowTreeDidUnmount(SurfaceId, HighResTimeStamp) noexcept {}
|
|
virtual ~UIManagerMountHook() noexcept = default;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerNativeAnimatedDelegate.h}:
|
|
namespace facebook::react {
|
|
class UIManagerNativeAnimatedDelegate {
|
|
public:
|
|
virtual ~UIManagerNativeAnimatedDelegate() = default;
|
|
virtual void runAnimationFrame() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/consistency/LazyShadowTreeRevisionConsistencyManager.h}:
|
|
namespace facebook::react {
|
|
class LazyShadowTreeRevisionConsistencyManager
|
|
: public ShadowTreeRevisionConsistencyManager,
|
|
public ShadowTreeRevisionProvider {
|
|
public:
|
|
explicit LazyShadowTreeRevisionConsistencyManager(
|
|
ShadowTreeRegistry& shadowTreeRegistry);
|
|
void updateCurrentRevision(
|
|
SurfaceId surfaceId,
|
|
RootShadowNode::Shared rootShadowNode);
|
|
RootShadowNode::Shared getCurrentRevision(SurfaceId surfaceId) override;
|
|
void lockRevisions() override;
|
|
void unlockRevisions() override;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/consistency/ShadowTreeRevisionProvider.h}:
|
|
namespace facebook::react {
|
|
class ShadowTreeRevisionProvider {
|
|
public:
|
|
virtual ~ShadowTreeRevisionProvider() = default;
|
|
virtual RootShadowNode::Shared getCurrentRevision(SurfaceId surfaceId) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/renderer/uimanager/primitives.h}:
|
|
namespace facebook::react {
|
|
using BackgroundExecutor =
|
|
std::function<void(std::function<void()>&& callback)>;
|
|
struct ShadowNodeListWrapper : public jsi::NativeState {
|
|
ShadowNodeListWrapper(ShadowNode::UnsharedListOfShared shadowNodeList)
|
|
: shadowNodeList(std::move(shadowNodeList)) {}
|
|
~ShadowNodeListWrapper() override;
|
|
ShadowNode::UnsharedListOfShared shadowNodeList;
|
|
};
|
|
inline static jsi::Value valueFromShadowNode(
|
|
jsi::Runtime& runtime,
|
|
std::shared_ptr<const ShadowNode> shadowNode,
|
|
bool assignRuntimeShadowNodeReference = false) {
|
|
auto wrappedShadowNode =
|
|
std::make_shared<ShadowNodeWrapper>(std::move(shadowNode));
|
|
if (assignRuntimeShadowNodeReference) {
|
|
wrappedShadowNode->shadowNode->setRuntimeShadowNodeReference(
|
|
wrappedShadowNode);
|
|
}
|
|
jsi::Object obj(runtime);
|
|
obj.setNativeState(runtime, std::move(wrappedShadowNode));
|
|
return obj;
|
|
}
|
|
inline static ShadowNode::UnsharedListOfShared shadowNodeListFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& value) {
|
|
jsi::Object object = value.asObject(runtime);
|
|
if (object.isArray(runtime)) {
|
|
auto jsArray = std::move(object).asArray(runtime);
|
|
size_t jsArrayLen = jsArray.length(runtime);
|
|
if (jsArrayLen > 0) {
|
|
auto shadowNodeArray =
|
|
std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>();
|
|
shadowNodeArray->reserve(jsArrayLen);
|
|
for (size_t i = 0; i < jsArrayLen; i++) {
|
|
shadowNodeArray->push_back(
|
|
Bridging<std::shared_ptr<const ShadowNode>>::fromJs(
|
|
runtime, jsArray.getValueAtIndex(runtime, i)));
|
|
}
|
|
return shadowNodeArray;
|
|
} else {
|
|
return std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>(
|
|
std::vector<std::shared_ptr<const ShadowNode>>({}));
|
|
;
|
|
}
|
|
} else {
|
|
return object.getNativeState<ShadowNodeListWrapper>(runtime)
|
|
->shadowNodeList;
|
|
}
|
|
}
|
|
inline static jsi::Value valueFromShadowNodeList(
|
|
jsi::Runtime& runtime,
|
|
ShadowNode::UnsharedListOfShared shadowNodeList) {
|
|
auto wrapper =
|
|
std::make_shared<ShadowNodeListWrapper>(std::move(shadowNodeList));
|
|
jsi::Object obj(runtime);
|
|
obj.setNativeState(runtime, std::move(wrapper));
|
|
return obj;
|
|
}
|
|
inline static ShadowNode::UnsharedListOfShared shadowNodeListFromWeakList(
|
|
const ShadowNode::UnsharedListOfWeak& weakShadowNodeList) {
|
|
auto result =
|
|
std::make_shared<std::vector<std::shared_ptr<const ShadowNode>>>();
|
|
for (const auto& weakShadowNode : *weakShadowNodeList) {
|
|
auto sharedShadowNode = weakShadowNode.lock();
|
|
if (!sharedShadowNode) {
|
|
return nullptr;
|
|
}
|
|
result->push_back(sharedShadowNode);
|
|
}
|
|
return result;
|
|
}
|
|
inline static ShadowNode::UnsharedListOfWeak weakShadowNodeListFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& value) {
|
|
auto shadowNodeList = shadowNodeListFromValue(runtime, value);
|
|
auto weakShadowNodeList =
|
|
std::make_shared<std::vector<std::weak_ptr<const ShadowNode>>>();
|
|
for (const auto& shadowNode : *shadowNodeList) {
|
|
weakShadowNodeList->push_back(shadowNode);
|
|
}
|
|
return weakShadowNodeList;
|
|
}
|
|
inline static Tag tagFromValue(const jsi::Value& value) {
|
|
return (Tag)value.getNumber();
|
|
}
|
|
inline static InstanceHandle::Shared instanceHandleFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& instanceHandleValue,
|
|
const jsi::Value& tagValue) {
|
|
react_native_assert(!instanceHandleValue.isNull());
|
|
if (instanceHandleValue.isNull()) {
|
|
return nullptr;
|
|
}
|
|
return std::make_shared<InstanceHandle>(
|
|
runtime, instanceHandleValue, tagFromValue(tagValue));
|
|
}
|
|
inline static SurfaceId surfaceIdFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& value) {
|
|
return (SurfaceId)value.getNumber();
|
|
}
|
|
inline static int displayModeToInt(const DisplayMode value) {
|
|
switch (value) {
|
|
case DisplayMode::Visible:
|
|
return 1;
|
|
case DisplayMode::Suspended:
|
|
return 2;
|
|
case DisplayMode::Hidden:
|
|
return 3;
|
|
default:
|
|
react_native_assert(0 && "displayModeToInt: Invalid DisplayMode");
|
|
return -1;
|
|
}
|
|
}
|
|
inline static std::string stringFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& value) {
|
|
return value.getString(runtime).utf8(runtime);
|
|
}
|
|
inline static folly::dynamic commandArgsFromValue(
|
|
jsi::Runtime& runtime,
|
|
const jsi::Value& value) {
|
|
return jsi::dynamicFromValue(runtime, value);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/BindingsInstaller.h}:
|
|
namespace facebook::react {
|
|
class BindingsInstaller {
|
|
public:
|
|
virtual ReactInstance::BindingsInstallFunc getBindingsInstallFunc() {
|
|
return nullptr;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/BridgelessNativeMethodCallInvoker.h}:
|
|
namespace facebook::react {
|
|
class BridgelessNativeMethodCallInvoker : public NativeMethodCallInvoker {
|
|
public:
|
|
explicit BridgelessNativeMethodCallInvoker(
|
|
std::shared_ptr<MessageQueueThread> messageQueueThread);
|
|
void invokeAsync(
|
|
const std::string& methodName,
|
|
NativeMethodCallFunc&& func) noexcept override;
|
|
void invokeSync(const std::string& methodName, NativeMethodCallFunc&& func)
|
|
override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/BufferedRuntimeExecutor.h}:
|
|
namespace facebook::react {
|
|
class BufferedRuntimeExecutor {
|
|
public:
|
|
using Work = std::function<void(jsi::Runtime& runtime)>;
|
|
struct BufferedWork {
|
|
uint64_t index_;
|
|
Work work_;
|
|
bool operator<(const BufferedWork& rhs) const {
|
|
return index_ > rhs.index_;
|
|
}
|
|
};
|
|
BufferedRuntimeExecutor(RuntimeExecutor runtimeExecutor);
|
|
void execute(Work&& callback);
|
|
void flush();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/PlatformTimerRegistry.h}:
|
|
namespace facebook::react {
|
|
class PlatformTimerRegistry {
|
|
public:
|
|
virtual void createTimer(uint32_t timerID, double delayMS) = 0;
|
|
virtual void deleteTimer(uint32_t timerID) = 0;
|
|
virtual void createRecurringTimer(uint32_t timerID, double delayMS) = 0;
|
|
virtual ~PlatformTimerRegistry() noexcept = default;
|
|
};
|
|
using TimerManagerDelegate = PlatformTimerRegistry;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/ReactInstance.h}:
|
|
namespace facebook::react {
|
|
class ReactInstance final : private jsinspector_modern::InstanceTargetDelegate {
|
|
public:
|
|
using BindingsInstallFunc = std::function<void(jsi::Runtime& runtime)>;
|
|
ReactInstance(
|
|
std::unique_ptr<JSRuntime> runtime,
|
|
std::shared_ptr<MessageQueueThread> jsMessageQueueThread,
|
|
std::shared_ptr<TimerManager> timerManager,
|
|
JsErrorHandler::OnJsError onJsError,
|
|
jsinspector_modern::HostTarget* parentInspectorTarget = nullptr);
|
|
RuntimeExecutor getUnbufferedRuntimeExecutor() noexcept;
|
|
RuntimeExecutor getBufferedRuntimeExecutor() noexcept;
|
|
std::shared_ptr<RuntimeScheduler> getRuntimeScheduler() noexcept;
|
|
struct JSRuntimeFlags {
|
|
bool isProfiling = false;
|
|
const std::string runtimeDiagnosticFlags = "";
|
|
};
|
|
void initializeRuntime(
|
|
JSRuntimeFlags options,
|
|
BindingsInstallFunc bindingsInstallFunc) noexcept;
|
|
void loadScript(
|
|
std::unique_ptr<const JSBigString> script,
|
|
const std::string& sourceURL,
|
|
std::function<void(jsi::Runtime& runtime)>&& beforeLoad = nullptr,
|
|
std::function<void(jsi::Runtime& runtime)>&& afterLoad = nullptr);
|
|
void registerSegment(uint32_t segmentId, const std::string& segmentPath);
|
|
void callFunctionOnModule(
|
|
const std::string& moduleName,
|
|
const std::string& methodName,
|
|
folly::dynamic&& args);
|
|
void handleMemoryPressureJs(int pressureLevel);
|
|
void unregisterFromInspector();
|
|
void* getJavaScriptContext();
|
|
};
|
|
jsinspector_modern::RuntimeTarget* runtimeInspectorTarget_{nullptr};
|
|
jsinspector_modern::HostTarget* parentInspectorTarget_{nullptr};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/TimerManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/PlatformTimerRegistry.h}
|
|
|
|
namespace facebook::react {
|
|
using TimerHandle = int;
|
|
enum class TimerSource {
|
|
Unknown,
|
|
SetTimeout,
|
|
SetInterval,
|
|
RequestAnimationFrame
|
|
};
|
|
struct TimerCallback {
|
|
TimerCallback(
|
|
jsi::Function callback,
|
|
std::vector<jsi::Value> args,
|
|
bool repeat,
|
|
TimerSource source = TimerSource::Unknown)
|
|
: callback_(std::move(callback)),
|
|
args_(std::move(args)),
|
|
repeat(repeat),
|
|
source(source) {}
|
|
void invoke(jsi::Runtime& runtime) {
|
|
callback_.call(runtime, args_.data(), args_.size());
|
|
}
|
|
jsi::Function callback_;
|
|
const std::vector<jsi::Value> args_;
|
|
bool repeat;
|
|
TimerSource source;
|
|
};
|
|
class TimerManager {
|
|
public:
|
|
explicit TimerManager(
|
|
std::unique_ptr<PlatformTimerRegistry> platformTimerRegistry) noexcept;
|
|
void setRuntimeExecutor(RuntimeExecutor runtimeExecutor) noexcept;
|
|
void callReactNativeMicrotasks(jsi::Runtime& runtime);
|
|
void callTimer(TimerHandle handle);
|
|
void attachGlobals(jsi::Runtime& runtime);
|
|
};
|
|
std::vector<TimerHandle> reactNativeMicrotasksQueue_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/hermes/HermesInstance.h}:
|
|
namespace facebook::react {
|
|
class HermesInstance {
|
|
public:
|
|
static std::unique_ptr<JSRuntime> createJSRuntime(
|
|
std::shared_ptr<::hermes::vm::CrashManager> crashManager,
|
|
std::shared_ptr<MessageQueueThread> msgQueueThread,
|
|
bool allocInOldGenBeforeTTI) noexcept;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/nativeviewconfig/LegacyUIManagerConstantsProviderBinding.h}:
|
|
namespace facebook::react::LegacyUIManagerConstantsProviderBinding {
|
|
void install(
|
|
jsi::Runtime& runtime,
|
|
const std::string& name,
|
|
std::function<jsi::Value(jsi::Runtime&)>&& provider);
|
|
void install(
|
|
jsi::Runtime& runtime,
|
|
const std::string& name,
|
|
std::function<jsi::Value(jsi::Runtime&, const std::string&)>&& provider);
|
|
} // namespace facebook::react::LegacyUIManagerConstantsProviderBinding
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/ObjCTimerRegistry.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/ObjCTimerRegistry.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTContextContainerHandling.h}:
|
|
@protocol RCTContextContainerHandling <NSObject>
|
|
- (void)didCreateContextContainer:(std::shared_ptr<facebook::react::ContextContainer>)contextContainer;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTHermesInstance.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost+Internal.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTContextContainerHandling.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInstanceRuntimeDiagnosticFlags(void);
|
|
RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
|
|
@protocol RCTInstanceDelegate <RCTContextContainerHandling>
|
|
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
|
|
- (BOOL)instance:(RCTInstance *)instance
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@interface RCTInstance : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
|
|
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)invalidate;
|
|
@property (nonatomic, readonly, strong) RCTSurfacePresenter *surfacePresenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);
|
|
@protocol RCTHostDelegate <NSObject>
|
|
- (void)hostDidStart:(RCTHost *)host;
|
|
@optional
|
|
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (void)host:(RCTHost *)host
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@protocol RCTHostRuntimeDelegate <NSObject>
|
|
- (void)host:(RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
@end
|
|
typedef std::shared_ptr<facebook::react::JSRuntimeFactory> (^RCTHostJSEngineProvider)(void);
|
|
@interface RCTHost : NSObject
|
|
- (instancetype)initWithBundleURLProvider:(RCTHostBundleURLProvider)provider
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions __deprecated;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
@property (nonatomic, weak, nullable) id<RCTHostRuntimeDelegate> runtimeDelegate;
|
|
@property (nonatomic, readonly) RCTSurfacePresenter *surfacePresenter;
|
|
@property (nonatomic, readonly) RCTModuleRegistry *moduleRegistry;
|
|
- (void)start;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName
|
|
mode:(facebook::react::DisplayMode)displayMode
|
|
initialProperties:(NSDictionary *)properties;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)properties;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
@interface RCTHost (Internal)
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)setBundleURLProvider:(RCTHostBundleURLProvider)bundleURLProvider;
|
|
- (void)setContextContainerHandler:(id<RCTContextContainerHandling>)contextContainerHandler;
|
|
- (void)reload;
|
|
@property (nonatomic, readonly) RCTBundleManager *bundleManager;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHost.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTContextContainerHandling.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInstanceRuntimeDiagnosticFlags(void);
|
|
RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
|
|
@protocol RCTInstanceDelegate <RCTContextContainerHandling>
|
|
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
|
|
- (BOOL)instance:(RCTInstance *)instance
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@interface RCTInstance : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
|
|
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)invalidate;
|
|
@property (nonatomic, readonly, strong) RCTSurfacePresenter *surfacePresenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);
|
|
@protocol RCTHostDelegate <NSObject>
|
|
- (void)hostDidStart:(RCTHost *)host;
|
|
@optional
|
|
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (void)host:(RCTHost *)host
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@protocol RCTHostRuntimeDelegate <NSObject>
|
|
- (void)host:(RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
@end
|
|
typedef std::shared_ptr<facebook::react::JSRuntimeFactory> (^RCTHostJSEngineProvider)(void);
|
|
@interface RCTHost : NSObject
|
|
- (instancetype)initWithBundleURLProvider:(RCTHostBundleURLProvider)provider
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions __deprecated;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
@property (nonatomic, weak, nullable) id<RCTHostRuntimeDelegate> runtimeDelegate;
|
|
@property (nonatomic, readonly) RCTSurfacePresenter *surfacePresenter;
|
|
@property (nonatomic, readonly) RCTModuleRegistry *moduleRegistry;
|
|
- (void)start;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName
|
|
mode:(facebook::react::DisplayMode)displayMode
|
|
initialProperties:(NSDictionary *)properties;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)properties;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTInstance.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTContextContainerHandling.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInstanceRuntimeDiagnosticFlags(void);
|
|
RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
|
|
@protocol RCTInstanceDelegate <RCTContextContainerHandling>
|
|
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (NSArray<NSString *> *)unstableModulesRequiringMainQueueSetup;
|
|
- (BOOL)instance:(RCTInstance *)instance
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@interface RCTInstance : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
|
|
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)invalidate;
|
|
@property (nonatomic, readonly, strong) RCTSurfacePresenter *surfacePresenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJSThreadManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTJSThreadManager.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJscInstance.h}:
|
|
namespace facebook::react {
|
|
class RCTJscInstance : public JSRuntimeFactory {
|
|
public:
|
|
RCTJscInstance();
|
|
std::unique_ptr<JSRuntime> createJSRuntime(
|
|
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept override;
|
|
~RCTJscInstance() {};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTLegacyUIManagerConstantsProvider.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTLegacyUIManagerConstantsProvider.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTPerformanceLoggerUtils.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTPerformanceLoggerUtils.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/metainternal/RCTJermesInstance.h}:
|
|
namespace facebook::react {
|
|
using CrashManagerProvider =
|
|
std::function<std::shared_ptr<::hermes::vm::CrashManager>()>;
|
|
class RCTJermesInstance : public JSRuntimeFactory {
|
|
public:
|
|
RCTJermesInstance();
|
|
RCTJermesInstance(CrashManagerProvider crashManagerProvider);
|
|
RCTJermesInstance(
|
|
CrashManagerProvider crashManagerProvider,
|
|
bool allocInOldGenBeforeTTI);
|
|
std::unique_ptr<JSRuntime> createJSRuntime(
|
|
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept override;
|
|
~RCTJermesInstance() override {};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/ObjCTimerRegistry.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/ObjCTimerRegistry.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTContextContainerHandling.h}:
|
|
@protocol RCTContextContainerHandling <NSObject>
|
|
@optional
|
|
- (void)didCreateContextContainer:(std::shared_ptr<facebook::react::ContextContainer>)contextContainer;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTHermesInstance.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTHermesInstance.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTHost+Internal.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTContextContainerHandling.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInstanceRuntimeDiagnosticFlags(void);
|
|
RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
|
|
@protocol RCTInstanceDelegate <RCTContextContainerHandling>
|
|
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (BOOL)instance:(RCTInstance *)instance
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@interface RCTInstance : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
|
|
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)invalidate;
|
|
@property (nonatomic, readonly, strong) RCTSurfacePresenter *surfacePresenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);
|
|
@protocol RCTHostDelegate <NSObject>
|
|
- (void)hostDidStart:(RCTHost *)host;
|
|
@optional
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (void)host:(RCTHost *)host
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@protocol RCTHostRuntimeDelegate <NSObject>
|
|
- (void)host:(RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
@end
|
|
typedef std::shared_ptr<facebook::react::JSRuntimeFactory> (^RCTHostJSEngineProvider)(void);
|
|
@interface RCTHost : NSObject
|
|
- (instancetype)initWithBundleURLProvider:(RCTHostBundleURLProvider)provider
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions __deprecated;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
@property (nonatomic, weak, nullable) id<RCTHostRuntimeDelegate> runtimeDelegate;
|
|
@property (nonatomic, readonly) RCTSurfacePresenter *surfacePresenter;
|
|
@property (nonatomic, readonly) RCTModuleRegistry *moduleRegistry;
|
|
- (void)start;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName
|
|
mode:(facebook::react::DisplayMode)displayMode
|
|
initialProperties:(NSDictionary *)properties;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)properties;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
@interface RCTHost (Internal)
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)setBundleURLProvider:(RCTHostBundleURLProvider)bundleURLProvider;
|
|
- (void)setContextContainerHandler:(id<RCTContextContainerHandling>)contextContainerHandler;
|
|
- (void)reload;
|
|
@property (nonatomic, readonly) RCTBundleManager *bundleManager;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTHost.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTContextContainerHandling.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInstanceRuntimeDiagnosticFlags(void);
|
|
RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
|
|
@protocol RCTInstanceDelegate <RCTContextContainerHandling>
|
|
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (BOOL)instance:(RCTInstance *)instance
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@interface RCTInstance : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
|
|
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)invalidate;
|
|
@property (nonatomic, readonly, strong) RCTSurfacePresenter *surfacePresenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
typedef NSURL *_Nullable (^RCTHostBundleURLProvider)(void);
|
|
@protocol RCTHostDelegate <NSObject>
|
|
- (void)hostDidStart:(RCTHost *)host;
|
|
@optional
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (void)host:(RCTHost *)host
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@protocol RCTHostRuntimeDelegate <NSObject>
|
|
- (void)host:(RCTHost *)host didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
@end
|
|
typedef std::shared_ptr<facebook::react::JSRuntimeFactory> (^RCTHostJSEngineProvider)(void);
|
|
@interface RCTHost : NSObject
|
|
- (instancetype)initWithBundleURLProvider:(RCTHostBundleURLProvider)provider
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions NS_DESIGNATED_INITIALIZER;
|
|
- (instancetype)initWithBundleURL:(NSURL *)bundleURL
|
|
hostDelegate:(id<RCTHostDelegate>)hostDelegate
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
jsEngineProvider:(RCTHostJSEngineProvider)jsEngineProvider
|
|
launchOptions:(nullable NSDictionary *)launchOptions __deprecated;
|
|
- (instancetype)init NS_UNAVAILABLE;
|
|
+ (instancetype)new NS_UNAVAILABLE;
|
|
@property (nonatomic, weak, nullable) id<RCTHostRuntimeDelegate> runtimeDelegate;
|
|
@property (nonatomic, readonly) RCTSurfacePresenter *surfacePresenter;
|
|
@property (nonatomic, readonly) RCTModuleRegistry *moduleRegistry;
|
|
- (void)start;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName
|
|
mode:(facebook::react::DisplayMode)displayMode
|
|
initialProperties:(NSDictionary *)properties;
|
|
- (RCTFabricSurface *)createSurfaceWithModuleName:(NSString *)moduleName initialProperties:(NSDictionary *)properties;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTInstance.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTContextContainerHandling.h}
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
RCT_EXTERN NSString *RCTInstanceRuntimeDiagnosticFlags(void);
|
|
RCT_EXTERN void RCTInstanceSetRuntimeDiagnosticFlags(NSString *_Nullable flags);
|
|
@protocol RCTInstanceDelegate <RCTContextContainerHandling>
|
|
- (void)instance:(RCTInstance *)instance didInitializeRuntime:(facebook::jsi::Runtime &)runtime;
|
|
- (void)loadBundleAtURL:(NSURL *)sourceURL
|
|
onProgress:(RCTSourceLoadProgressBlock)onProgress
|
|
onComplete:(RCTSourceLoadBlock)loadCallback;
|
|
- (BOOL)instance:(RCTInstance *)instance
|
|
didReceiveJSErrorStack:(NSArray<NSDictionary<NSString *, id> *> *)stack
|
|
message:(NSString *)message
|
|
originalMessage:(NSString *_Nullable)originalMessage
|
|
name:(NSString *_Nullable)name
|
|
componentStack:(NSString *_Nullable)componentStack
|
|
exceptionId:(NSUInteger)exceptionId
|
|
isFatal:(BOOL)isFatal
|
|
extraData:(NSDictionary<NSString *, id> *)extraData __attribute__((deprecated));
|
|
@end
|
|
@interface RCTInstance : NSObject
|
|
- (instancetype)initWithDelegate:(id<RCTInstanceDelegate>)delegate
|
|
jsRuntimeFactory:(std::shared_ptr<facebook::react::JSRuntimeFactory>)jsRuntimeFactory
|
|
bundleManager:(RCTBundleManager *)bundleManager
|
|
turboModuleManagerDelegate:(id<RCTTurboModuleManagerDelegate>)turboModuleManagerDelegate
|
|
moduleRegistry:(RCTModuleRegistry *)moduleRegistry
|
|
parentInspectorTarget:(facebook::react::jsinspector_modern::HostTarget *)parentInspectorTarget
|
|
launchOptions:(nullable NSDictionary *)launchOptions;
|
|
- (void)callFunctionOnJSModule:(NSString *)moduleName method:(NSString *)method args:(NSArray *)args;
|
|
- (void)callFunctionOnBufferedRuntimeExecutor:(std::function<void(facebook::jsi::Runtime &runtime)> &&)executor;
|
|
- (void)registerSegmentWithId:(NSNumber *)segmentId path:(NSString *)path;
|
|
- (void)invalidate;
|
|
@property (nonatomic, readonly, strong) RCTSurfacePresenter *surfacePresenter;
|
|
@end
|
|
NS_ASSUME_NONNULL_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTJSThreadManager.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTJSThreadManager.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTJscInstance.h}:
|
|
namespace facebook {
|
|
namespace react {
|
|
class RCTJscInstance : public JSRuntimeFactory {
|
|
public:
|
|
RCTJscInstance();
|
|
std::unique_ptr<JSRuntime> createJSRuntime(
|
|
std::shared_ptr<MessageQueueThread> msgQueueThread) noexcept override;
|
|
~RCTJscInstance() {};
|
|
};
|
|
} // namespace react
|
|
} // namespace facebook
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTLegacyUIManagerConstantsProvider.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTLegacyUIManagerConstantsProvider.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/runtime/platform/macos/ReactCommon/RCTPerformanceLoggerUtils.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/runtime/platform/ios/ReactCommon/RCTPerformanceLoggerUtils.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/test_utils/ios/Memory/RCTMemoryUtils.h}:
|
|
RCT_EXTERN_C_BEGIN
|
|
int RCTGetRetainCount(id _Nullable object);
|
|
void RCTAutoReleasePoolPush(void);
|
|
void RCTAutoReleasePoolPop(void);
|
|
RCT_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/test_utils/ios/RCTSwizzleHelpers.h}:
|
|
RCT_EXTERN_C_BEGIN
|
|
void RCTSwizzleInstanceSelector(
|
|
Class targetClass,
|
|
Class swizzleClass,
|
|
SEL selector);
|
|
RCT_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/test_utils/ios/Shims/ShimRCTInstance.h}:
|
|
@interface ShimRCTInstance : NSObject
|
|
@property int initCount;
|
|
@property int invalidateCount;
|
|
@property NSDictionary *launchOptions;
|
|
@property NSString *jsModuleName;
|
|
@property NSString *method;
|
|
@property NSArray *args;
|
|
- (void)reset;
|
|
@end
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/timing/primitives.h}:
|
|
namespace facebook::react {
|
|
class HighResDuration {
|
|
friend
|
|
friend constexpr HighResDuration operator-(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResTimeStamp& rhs);
|
|
friend constexpr HighResTimeStamp operator+(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResDuration& rhs);
|
|
friend constexpr HighResTimeStamp operator-(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResDuration& rhs);
|
|
|
|
public:
|
|
constexpr HighResDuration()
|
|
: chronoDuration_(std::chrono::steady_clock::duration()) {}
|
|
static constexpr HighResDuration zero() {
|
|
return HighResDuration(std::chrono::steady_clock::duration::zero());
|
|
}
|
|
static constexpr HighResDuration fromChrono(
|
|
std::chrono::steady_clock::duration chronoDuration) {
|
|
return HighResDuration(chronoDuration);
|
|
}
|
|
static constexpr HighResDuration fromNanoseconds(int64_t units) {
|
|
return HighResDuration(std::chrono::nanoseconds(units));
|
|
}
|
|
static constexpr HighResDuration fromMilliseconds(int64_t units) {
|
|
return HighResDuration(std::chrono::milliseconds(units));
|
|
}
|
|
constexpr int64_t toNanoseconds() const {
|
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(chronoDuration_)
|
|
.count();
|
|
}
|
|
static constexpr HighResDuration fromDOMHighResTimeStamp(double units) {
|
|
auto nanoseconds = static_cast<int64_t>(units * 1e6);
|
|
return fromNanoseconds(nanoseconds);
|
|
}
|
|
constexpr double toDOMHighResTimeStamp() const {
|
|
return static_cast<std::chrono::duration<double, std::milli>>(
|
|
chronoDuration_)
|
|
.count();
|
|
}
|
|
constexpr HighResDuration operator+(const HighResDuration& rhs) const {
|
|
return HighResDuration(chronoDuration_ + rhs.chronoDuration_);
|
|
}
|
|
constexpr HighResDuration operator+(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return HighResDuration(chronoDuration_ + rhs);
|
|
}
|
|
constexpr HighResDuration operator-(const HighResDuration& rhs) const {
|
|
return HighResDuration(chronoDuration_ - rhs.chronoDuration_);
|
|
}
|
|
constexpr HighResDuration operator-(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return HighResDuration(chronoDuration_ - rhs);
|
|
}
|
|
constexpr HighResDuration& operator+=(const HighResDuration& rhs) {
|
|
chronoDuration_ += rhs.chronoDuration_;
|
|
return *this;
|
|
}
|
|
constexpr HighResDuration& operator+=(
|
|
const std::chrono::steady_clock::duration& rhs) {
|
|
chronoDuration_ += rhs;
|
|
return *this;
|
|
}
|
|
constexpr HighResDuration& operator-=(const HighResDuration& rhs) {
|
|
chronoDuration_ -= rhs.chronoDuration_;
|
|
return *this;
|
|
}
|
|
constexpr HighResDuration& operator-=(
|
|
const std::chrono::steady_clock::duration& rhs) {
|
|
chronoDuration_ -= rhs;
|
|
return *this;
|
|
}
|
|
constexpr bool operator==(const HighResDuration& rhs) const {
|
|
return chronoDuration_ == rhs.chronoDuration_;
|
|
}
|
|
constexpr bool operator==(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return chronoDuration_ == rhs;
|
|
}
|
|
constexpr bool operator!=(const HighResDuration& rhs) const {
|
|
return chronoDuration_ != rhs.chronoDuration_;
|
|
}
|
|
constexpr bool operator!=(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return chronoDuration_ != rhs;
|
|
}
|
|
constexpr bool operator<(const HighResDuration& rhs) const {
|
|
return chronoDuration_ < rhs.chronoDuration_;
|
|
}
|
|
constexpr bool operator<(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return chronoDuration_ < rhs;
|
|
}
|
|
constexpr bool operator<=(const HighResDuration& rhs) const {
|
|
return chronoDuration_ <= rhs.chronoDuration_;
|
|
}
|
|
constexpr bool operator<=(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return chronoDuration_ <= rhs;
|
|
}
|
|
constexpr bool operator>(const HighResDuration& rhs) const {
|
|
return chronoDuration_ > rhs.chronoDuration_;
|
|
}
|
|
constexpr bool operator>(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return chronoDuration_ > rhs;
|
|
}
|
|
constexpr bool operator>=(const HighResDuration& rhs) const {
|
|
return chronoDuration_ >= rhs.chronoDuration_;
|
|
}
|
|
constexpr bool operator>=(
|
|
const std::chrono::steady_clock::duration& rhs) const {
|
|
return chronoDuration_ >= rhs;
|
|
}
|
|
constexpr operator std::chrono::steady_clock::duration() const {
|
|
return chronoDuration_;
|
|
}
|
|
};
|
|
class HighResTimeStamp {
|
|
friend constexpr HighResDuration operator-(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResTimeStamp& rhs);
|
|
friend constexpr HighResTimeStamp operator+(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResDuration& rhs);
|
|
friend constexpr HighResTimeStamp operator-(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResDuration& rhs);
|
|
|
|
public:
|
|
HighResTimeStamp() noexcept
|
|
: chronoTimePoint_(std::chrono::steady_clock::now()) {}
|
|
static constexpr HighResTimeStamp now() noexcept {
|
|
return HighResTimeStamp(std::chrono::steady_clock::now());
|
|
}
|
|
static constexpr HighResTimeStamp min() noexcept {
|
|
return HighResTimeStamp(std::chrono::steady_clock::time_point::min());
|
|
}
|
|
static constexpr HighResTimeStamp max() noexcept {
|
|
return HighResTimeStamp(std::chrono::steady_clock::time_point::max());
|
|
}
|
|
static constexpr HighResTimeStamp fromDOMHighResTimeStamp(double units) {
|
|
auto nanoseconds = static_cast<int64_t>(units * 1e6);
|
|
return HighResTimeStamp(std::chrono::steady_clock::time_point(
|
|
std::chrono::nanoseconds(nanoseconds)));
|
|
}
|
|
constexpr double toDOMHighResTimeStamp() const {
|
|
return HighResDuration(chronoTimePoint_.time_since_epoch())
|
|
.toDOMHighResTimeStamp();
|
|
}
|
|
static constexpr HighResTimeStamp fromChronoSteadyClockTimePoint(
|
|
std::chrono::steady_clock::time_point chronoTimePoint) {
|
|
return HighResTimeStamp(chronoTimePoint);
|
|
}
|
|
constexpr std::chrono::steady_clock::time_point toChronoSteadyClockTimePoint()
|
|
const {
|
|
return chronoTimePoint_;
|
|
}
|
|
constexpr bool operator==(const HighResTimeStamp& rhs) const {
|
|
return chronoTimePoint_ == rhs.chronoTimePoint_;
|
|
}
|
|
constexpr bool operator!=(const HighResTimeStamp& rhs) const {
|
|
return chronoTimePoint_ != rhs.chronoTimePoint_;
|
|
}
|
|
constexpr bool operator<(const HighResTimeStamp& rhs) const {
|
|
return chronoTimePoint_ < rhs.chronoTimePoint_;
|
|
}
|
|
constexpr bool operator<=(const HighResTimeStamp& rhs) const {
|
|
return chronoTimePoint_ <= rhs.chronoTimePoint_;
|
|
}
|
|
constexpr bool operator>(const HighResTimeStamp& rhs) const {
|
|
return chronoTimePoint_ > rhs.chronoTimePoint_;
|
|
}
|
|
constexpr bool operator>=(const HighResTimeStamp& rhs) const {
|
|
return chronoTimePoint_ >= rhs.chronoTimePoint_;
|
|
}
|
|
constexpr HighResTimeStamp& operator+=(const HighResDuration& rhs) {
|
|
chronoTimePoint_ += rhs.chronoDuration_;
|
|
return *this;
|
|
}
|
|
constexpr HighResTimeStamp& operator-=(const HighResDuration& rhs) {
|
|
chronoTimePoint_ -= rhs.chronoDuration_;
|
|
return *this;
|
|
}
|
|
};
|
|
inline constexpr HighResDuration operator-(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResTimeStamp& rhs) {
|
|
return HighResDuration(lhs.chronoTimePoint_ - rhs.chronoTimePoint_);
|
|
}
|
|
inline constexpr HighResTimeStamp operator+(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResDuration& rhs) {
|
|
return HighResTimeStamp(lhs.chronoTimePoint_ + rhs.chronoDuration_);
|
|
}
|
|
inline constexpr HighResTimeStamp operator-(
|
|
const HighResTimeStamp& lhs,
|
|
const HighResDuration& rhs) {
|
|
return HighResTimeStamp(lhs.chronoTimePoint_ - rhs.chronoDuration_);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/LowPriorityExecutor.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/utils/platform/cxx/react/utils/LowPriorityExecutor.h}:
|
|
namespace facebook::react::LowPriorityExecutor {
|
|
inline void execute(std::function<void()>&& workItem) {
|
|
workItem();
|
|
}
|
|
} // namespace facebook::react::LowPriorityExecutor
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/FollyConvert.h}:
|
|
namespace facebook::react {
|
|
folly::dynamic convertIdToFollyDynamic(id json);
|
|
id convertFollyDynamicToId(const folly::dynamic &dyn);
|
|
NSArray<NSString *> *extractKeysFromFollyDynamic(const folly::dynamic &dyn);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/utils/platform/ios/react/utils/LowPriorityExecutor.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/react/utils/platform/windows/third-party/react/utils/LowPriorityExecutor.h}:
|
|
/// @dep {packages/react-native/ReactCommon/react/utils/platform/android/react/utils/LowPriorityExecutor.h}
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/fusebox/FuseboxTracer.h}:
|
|
namespace facebook::react {
|
|
struct BufferEvent {
|
|
uint64_t start;
|
|
uint64_t end;
|
|
std::string name;
|
|
std::string track;
|
|
};
|
|
class FuseboxTracer {
|
|
public:
|
|
FuseboxTracer(const FuseboxTracer&) = delete;
|
|
bool isTracing();
|
|
bool startTracing();
|
|
bool stopTracing(const std::function<void(const folly::dynamic& eventsChunk)>&
|
|
resultCallback);
|
|
bool stopTracingAndWriteToFile(const std::string& path);
|
|
void addEvent(
|
|
const std::string_view& name,
|
|
uint64_t start,
|
|
uint64_t end,
|
|
const std::optional<std::string_view>& track);
|
|
static FuseboxTracer& getFuseboxTracer();
|
|
};
|
|
std::vector<BufferEvent> buffer_;
|
|
std::mutex mutex_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/BridgeNativeModulePerfLogger.h}:
|
|
/// @dep {packages/react-native/ReactCommon/reactperflogger/reactperflogger/NativeModulePerfLogger.h}
|
|
|
|
namespace facebook::react::BridgeNativeModulePerfLogger {
|
|
void enableLogging(std::unique_ptr<NativeModulePerfLogger>&& logger);
|
|
void disableLogging();
|
|
void moduleDataCreateStart(const char* moduleName, int32_t id);
|
|
void moduleDataCreateEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateStart(const char* moduleName, int32_t id);
|
|
void moduleCreateCacheHit(const char* moduleName, int32_t id);
|
|
void moduleCreateConstructStart(const char* moduleName, int32_t id);
|
|
void moduleCreateConstructEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateSetUpStart(const char* moduleName, int32_t id);
|
|
void moduleCreateSetUpEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateEnd(const char* moduleName, int32_t id);
|
|
void moduleCreateFail(const char* moduleName, int32_t id);
|
|
void moduleJSRequireBeginningStart(const char* moduleName);
|
|
void moduleJSRequireBeginningCacheHit(const char* moduleName);
|
|
void moduleJSRequireBeginningEnd(const char* moduleName);
|
|
void moduleJSRequireBeginningFail(const char* moduleName);
|
|
void moduleJSRequireEndingStart(const char* moduleName);
|
|
void moduleJSRequireEndingEnd(const char* moduleName);
|
|
void moduleJSRequireEndingFail(const char* moduleName);
|
|
void syncMethodCallStart(const char* moduleName, const char* methodName);
|
|
void syncMethodCallArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallExecutionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallExecutionEnd(const char* moduleName, const char* methodName);
|
|
void syncMethodCallReturnConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallReturnConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void syncMethodCallEnd(const char* moduleName, const char* methodName);
|
|
void syncMethodCallFail(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallStart(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void asyncMethodCallArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName);
|
|
void asyncMethodCallDispatch(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallEnd(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallFail(const char* moduleName, const char* methodName);
|
|
void asyncMethodCallBatchPreprocessStart();
|
|
void asyncMethodCallBatchPreprocessEnd(int batchSize);
|
|
void asyncMethodCallExecutionStart(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionEnd(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
void asyncMethodCallExecutionFail(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id);
|
|
} // namespace facebook::react::BridgeNativeModulePerfLogger
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/FuseboxPerfettoDataSource.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/HermesPerfettoDataSource.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/NativeModulePerfLogger.h}:
|
|
namespace facebook::react {
|
|
class NativeModulePerfLogger {
|
|
public:
|
|
virtual ~NativeModulePerfLogger() = default;
|
|
virtual void moduleDataCreateStart(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleDataCreateEnd(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateStart(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateCacheHit(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateConstructStart(
|
|
const char* moduleName,
|
|
int32_t id) = 0;
|
|
virtual void moduleCreateConstructEnd(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateSetUpStart(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateSetUpEnd(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateEnd(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleCreateFail(const char* moduleName, int32_t id) = 0;
|
|
virtual void moduleJSRequireBeginningStart(const char* moduleName) = 0;
|
|
virtual void moduleJSRequireBeginningCacheHit(const char* moduleName) = 0;
|
|
virtual void moduleJSRequireBeginningEnd(const char* moduleName) = 0;
|
|
virtual void moduleJSRequireBeginningFail(const char* moduleName) = 0;
|
|
virtual void moduleJSRequireEndingStart(const char* moduleName) = 0;
|
|
virtual void moduleJSRequireEndingEnd(const char* moduleName) = 0;
|
|
virtual void moduleJSRequireEndingFail(const char* moduleName) = 0;
|
|
virtual void syncMethodCallStart(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallExecutionStart(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallExecutionEnd(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallReturnConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallReturnConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallEnd(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void syncMethodCallFail(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallStart(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallDispatch(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallEnd(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallFail(
|
|
const char* moduleName,
|
|
const char* methodName) = 0;
|
|
virtual void asyncMethodCallBatchPreprocessStart() = 0;
|
|
virtual void asyncMethodCallBatchPreprocessEnd(int batchSize) = 0;
|
|
virtual void asyncMethodCallExecutionStart(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id) = 0;
|
|
virtual void asyncMethodCallExecutionArgConversionStart(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id) = 0;
|
|
virtual void asyncMethodCallExecutionArgConversionEnd(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id) = 0;
|
|
virtual void asyncMethodCallExecutionEnd(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id) = 0;
|
|
virtual void asyncMethodCallExecutionFail(
|
|
const char* moduleName,
|
|
const char* methodName,
|
|
int32_t id) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfetto.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfettoCategories.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/reactperflogger/reactperflogger/ReactPerfettoLogger.h}:
|
|
namespace facebook::react {
|
|
class ReactPerfettoLogger {
|
|
public:
|
|
static bool isTracing();
|
|
static void mark(
|
|
const std::string_view& eventName,
|
|
HighResTimeStamp startTime,
|
|
const std::optional<std::string_view>& trackName = std::nullopt,
|
|
const std::optional<std::string_view>& trackGroup = std::nullopt);
|
|
static void measure(
|
|
const std::string_view& eventName,
|
|
HighResTimeStamp startTime,
|
|
HighResTimeStamp endTime,
|
|
const std::optional<std::string_view>& trackName = std::nullopt,
|
|
const std::optional<std::string_view>& trackGroup = std::nullopt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h}:
|
|
namespace facebook::react {
|
|
using RuntimeExecutor =
|
|
std::function<void(std::function<void(jsi::Runtime& runtime)>&& callback)>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/runtimeexecutor/platform/cxx/ReactCommon/RuntimeExecutorSyncUIThreadUtils.h}:
|
|
namespace facebook::react {
|
|
void executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<void(jsi::Runtime&)>&& runtimeWork);
|
|
template <typename DataT>
|
|
inline static DataT executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<DataT(jsi::Runtime&)>&& runtimeWork) {
|
|
DataT data;
|
|
executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
runtimeExecutor,
|
|
[&](jsi::Runtime& runtime) { data = runtimeWork(runtime); });
|
|
return data;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/runtimeexecutor/platform/ios/ReactCommon/RuntimeExecutorSyncUIThreadUtils.h}:
|
|
namespace facebook::react {
|
|
void executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<void(jsi::Runtime&)>&& runtimeWork);
|
|
template <typename DataT>
|
|
inline static DataT executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
const RuntimeExecutor& runtimeExecutor,
|
|
std::function<DataT(jsi::Runtime&)>&& runtimeWork) {
|
|
DataT data;
|
|
executeSynchronouslyOnSameThread_CAN_DEADLOCK(
|
|
runtimeExecutor,
|
|
[&](jsi::Runtime& runtime) { data = runtimeWork(runtime); });
|
|
return data;
|
|
}
|
|
void unsafeExecuteOnMainThreadSync(std::function<void()> work);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGConfig.h}:
|
|
YG_EXTERN_C_BEGIN
|
|
typedef struct YGNode* YGNodeRef;
|
|
typedef const struct YGNode* YGNodeConstRef;
|
|
typedef struct YGConfig* YGConfigRef;
|
|
typedef const struct YGConfig* YGConfigConstRef;
|
|
YG_EXPORT YGConfigRef YGConfigNew(void);
|
|
YG_EXPORT void YGConfigFree(YGConfigRef config);
|
|
YG_EXPORT YGConfigConstRef YGConfigGetDefault(void);
|
|
YG_EXPORT void YGConfigSetUseWebDefaults(YGConfigRef config, bool enabled);
|
|
YG_EXPORT bool YGConfigGetUseWebDefaults(YGConfigConstRef config);
|
|
YG_EXPORT void YGConfigSetPointScaleFactor(
|
|
YGConfigRef config,
|
|
float pixelsInPoint);
|
|
YG_EXPORT float YGConfigGetPointScaleFactor(YGConfigConstRef config);
|
|
YG_EXPORT void YGConfigSetErrata(YGConfigRef config, YGErrata errata);
|
|
YG_EXPORT YGErrata YGConfigGetErrata(YGConfigConstRef config);
|
|
typedef int (*YGLogger)(
|
|
YGConfigConstRef config,
|
|
YGNodeConstRef node,
|
|
YGLogLevel level,
|
|
const char* format,
|
|
va_list args);
|
|
YG_EXPORT void YGConfigSetLogger(YGConfigRef config, YGLogger logger);
|
|
YG_EXPORT void YGConfigSetContext(YGConfigRef config, void* context);
|
|
YG_EXPORT void* YGConfigGetContext(YGConfigConstRef config);
|
|
typedef YGNodeRef (*YGCloneNodeFunc)(
|
|
YGNodeConstRef oldNode,
|
|
YGNodeConstRef owner,
|
|
size_t childIndex);
|
|
YG_EXPORT void YGConfigSetExperimentalFeatureEnabled(
|
|
YGConfigRef config,
|
|
YGExperimentalFeature feature,
|
|
bool enabled);
|
|
YG_EXPORT bool YGConfigIsExperimentalFeatureEnabled(
|
|
YGConfigConstRef config,
|
|
YGExperimentalFeature feature);
|
|
YG_EXPORT void YGConfigSetCloneNodeFunc(
|
|
YGConfigRef config,
|
|
YGCloneNodeFunc callback);
|
|
YG_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGEnums.h}:
|
|
YG_EXTERN_C_BEGIN
|
|
YG_ENUM_DECL(
|
|
YGAlign,
|
|
YGAlignAuto,
|
|
YGAlignFlexStart,
|
|
YGAlignCenter,
|
|
YGAlignFlexEnd,
|
|
YGAlignStretch,
|
|
YGAlignBaseline,
|
|
YGAlignSpaceBetween,
|
|
YGAlignSpaceAround,
|
|
YGAlignSpaceEvenly)
|
|
YG_ENUM_DECL(YGBoxSizing, YGBoxSizingBorderBox, YGBoxSizingContentBox)
|
|
YG_ENUM_DECL(YGDimension, YGDimensionWidth, YGDimensionHeight)
|
|
YG_ENUM_DECL(YGDirection, YGDirectionInherit, YGDirectionLTR, YGDirectionRTL)
|
|
YG_ENUM_DECL(YGDisplay, YGDisplayFlex, YGDisplayNone, YGDisplayContents)
|
|
YG_ENUM_DECL(
|
|
YGEdge,
|
|
YGEdgeLeft,
|
|
YGEdgeTop,
|
|
YGEdgeRight,
|
|
YGEdgeBottom,
|
|
YGEdgeStart,
|
|
YGEdgeEnd,
|
|
YGEdgeHorizontal,
|
|
YGEdgeVertical,
|
|
YGEdgeAll)
|
|
YG_ENUM_DECL(
|
|
YGErrata,
|
|
YGErrataNone = 0,
|
|
YGErrataStretchFlexBasis = 1,
|
|
YGErrataAbsolutePositionWithoutInsetsExcludesPadding = 2,
|
|
YGErrataAbsolutePercentAgainstInnerSize = 4,
|
|
YGErrataAll = 2147483647,
|
|
YGErrataClassic = 2147483646)
|
|
YG_DEFINE_ENUM_FLAG_OPERATORS(YGErrata)
|
|
YG_ENUM_DECL(YGExperimentalFeature, YGExperimentalFeatureWebFlexBasis)
|
|
YG_ENUM_DECL(
|
|
YGFlexDirection,
|
|
YGFlexDirectionColumn,
|
|
YGFlexDirectionColumnReverse,
|
|
YGFlexDirectionRow,
|
|
YGFlexDirectionRowReverse)
|
|
YG_ENUM_DECL(YGGutter, YGGutterColumn, YGGutterRow, YGGutterAll)
|
|
YG_ENUM_DECL(
|
|
YGJustify,
|
|
YGJustifyFlexStart,
|
|
YGJustifyCenter,
|
|
YGJustifyFlexEnd,
|
|
YGJustifySpaceBetween,
|
|
YGJustifySpaceAround,
|
|
YGJustifySpaceEvenly)
|
|
YG_ENUM_DECL(
|
|
YGLogLevel,
|
|
YGLogLevelError,
|
|
YGLogLevelWarn,
|
|
YGLogLevelInfo,
|
|
YGLogLevelDebug,
|
|
YGLogLevelVerbose,
|
|
YGLogLevelFatal)
|
|
YG_ENUM_DECL(
|
|
YGMeasureMode,
|
|
YGMeasureModeUndefined,
|
|
YGMeasureModeExactly,
|
|
YGMeasureModeAtMost)
|
|
YG_ENUM_DECL(YGNodeType, YGNodeTypeDefault, YGNodeTypeText)
|
|
YG_ENUM_DECL(YGOverflow, YGOverflowVisible, YGOverflowHidden, YGOverflowScroll)
|
|
YG_ENUM_DECL(
|
|
YGPositionType,
|
|
YGPositionTypeStatic,
|
|
YGPositionTypeRelative,
|
|
YGPositionTypeAbsolute)
|
|
YG_ENUM_DECL(
|
|
YGUnit,
|
|
YGUnitUndefined,
|
|
YGUnitPoint,
|
|
YGUnitPercent,
|
|
YGUnitAuto,
|
|
YGUnitMaxContent,
|
|
YGUnitFitContent,
|
|
YGUnitStretch)
|
|
YG_ENUM_DECL(YGWrap, YGWrapNoWrap, YGWrapWrap, YGWrapWrapReverse)
|
|
YG_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGMacros.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGNode.h}:
|
|
YG_EXTERN_C_BEGIN
|
|
typedef struct YGNode* YGNodeRef;
|
|
typedef const struct YGNode* YGNodeConstRef;
|
|
YG_EXPORT YGNodeRef YGNodeNew(void);
|
|
YG_EXPORT YGNodeRef YGNodeNewWithConfig(YGConfigConstRef config);
|
|
YG_EXPORT YGNodeRef YGNodeClone(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeFree(YGNodeRef node);
|
|
YG_EXPORT void YGNodeFreeRecursive(YGNodeRef node);
|
|
YG_EXPORT void YGNodeFinalize(YGNodeRef node);
|
|
YG_EXPORT void YGNodeReset(YGNodeRef node);
|
|
YG_EXPORT void YGNodeCalculateLayout(
|
|
YGNodeRef node,
|
|
float availableWidth,
|
|
float availableHeight,
|
|
YGDirection ownerDirection);
|
|
YG_EXPORT bool YGNodeGetHasNewLayout(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeSetHasNewLayout(YGNodeRef node, bool hasNewLayout);
|
|
YG_EXPORT bool YGNodeIsDirty(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeMarkDirty(YGNodeRef node);
|
|
typedef void (*YGDirtiedFunc)(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeSetDirtiedFunc(YGNodeRef node, YGDirtiedFunc dirtiedFunc);
|
|
YG_EXPORT YGDirtiedFunc YGNodeGetDirtiedFunc(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeInsertChild(YGNodeRef node, YGNodeRef child, size_t index);
|
|
YG_EXPORT void YGNodeSwapChild(YGNodeRef node, YGNodeRef child, size_t index);
|
|
YG_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child);
|
|
YG_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node);
|
|
YG_EXPORT void
|
|
YGNodeSetChildren(YGNodeRef owner, const YGNodeRef* children, size_t count);
|
|
YG_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, size_t index);
|
|
YG_EXPORT size_t YGNodeGetChildCount(YGNodeConstRef node);
|
|
YG_EXPORT YGNodeRef YGNodeGetOwner(YGNodeRef node);
|
|
YG_EXPORT YGNodeRef YGNodeGetParent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeSetConfig(YGNodeRef node, YGConfigRef config);
|
|
YG_EXPORT YGConfigConstRef YGNodeGetConfig(YGNodeRef node);
|
|
YG_EXPORT void YGNodeSetContext(YGNodeRef node, void* context);
|
|
YG_EXPORT void* YGNodeGetContext(YGNodeConstRef node);
|
|
typedef struct YGSize {
|
|
float width;
|
|
float height;
|
|
} YGSize;
|
|
typedef YGSize (*YGMeasureFunc)(
|
|
YGNodeConstRef node,
|
|
float width,
|
|
YGMeasureMode widthMode,
|
|
float height,
|
|
YGMeasureMode heightMode);
|
|
YG_EXPORT void YGNodeSetMeasureFunc(YGNodeRef node, YGMeasureFunc measureFunc);
|
|
YG_EXPORT bool YGNodeHasMeasureFunc(YGNodeConstRef node);
|
|
typedef float (*YGBaselineFunc)(YGNodeConstRef node, float width, float height);
|
|
YG_EXPORT void YGNodeSetBaselineFunc(
|
|
YGNodeRef node,
|
|
YGBaselineFunc baselineFunc);
|
|
YG_EXPORT bool YGNodeHasBaselineFunc(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeSetIsReferenceBaseline(
|
|
YGNodeRef node,
|
|
bool isReferenceBaseline);
|
|
YG_EXPORT bool YGNodeIsReferenceBaseline(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeSetNodeType(YGNodeRef node, YGNodeType nodeType);
|
|
YG_EXPORT YGNodeType YGNodeGetNodeType(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeSetAlwaysFormsContainingBlock(
|
|
YGNodeRef node,
|
|
bool alwaysFormsContainingBlock);
|
|
YG_EXPORT bool YGNodeGetAlwaysFormsContainingBlock(YGNodeConstRef node);
|
|
YG_DEPRECATED(
|
|
"YGNodeCanUseCachedMeasurement may be removed in a future version of Yoga")
|
|
YG_EXPORT bool YGNodeCanUseCachedMeasurement(
|
|
YGMeasureMode widthMode,
|
|
float availableWidth,
|
|
YGMeasureMode heightMode,
|
|
float availableHeight,
|
|
YGMeasureMode lastWidthMode,
|
|
float lastAvailableWidth,
|
|
YGMeasureMode lastHeightMode,
|
|
float lastAvailableHeight,
|
|
float lastComputedWidth,
|
|
float lastComputedHeight,
|
|
float marginRow,
|
|
float marginColumn,
|
|
YGConfigRef config);
|
|
YG_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGNodeLayout.h}:
|
|
YG_EXTERN_C_BEGIN
|
|
YG_EXPORT float YGNodeLayoutGetLeft(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetTop(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetRight(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetBottom(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetWidth(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetHeight(YGNodeConstRef node);
|
|
YG_EXPORT YGDirection YGNodeLayoutGetDirection(YGNodeConstRef node);
|
|
YG_EXPORT bool YGNodeLayoutGetHadOverflow(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetMargin(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT float YGNodeLayoutGetBorder(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT float YGNodeLayoutGetPadding(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT float YGNodeLayoutGetRawHeight(YGNodeConstRef node);
|
|
YG_EXPORT float YGNodeLayoutGetRawWidth(YGNodeConstRef node);
|
|
YG_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGNodeStyle.h}:
|
|
YG_EXTERN_C_BEGIN
|
|
YG_EXPORT void YGNodeCopyStyle(YGNodeRef dstNode, YGNodeConstRef srcNode);
|
|
YG_EXPORT void YGNodeStyleSetDirection(YGNodeRef node, YGDirection direction);
|
|
YG_EXPORT YGDirection YGNodeStyleGetDirection(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexDirection(
|
|
YGNodeRef node,
|
|
YGFlexDirection flexDirection);
|
|
YG_EXPORT YGFlexDirection YGNodeStyleGetFlexDirection(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetJustifyContent(
|
|
YGNodeRef node,
|
|
YGJustify justifyContent);
|
|
YG_EXPORT YGJustify YGNodeStyleGetJustifyContent(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetAlignContent(YGNodeRef node, YGAlign alignContent);
|
|
YG_EXPORT YGAlign YGNodeStyleGetAlignContent(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetAlignItems(YGNodeRef node, YGAlign alignItems);
|
|
YG_EXPORT YGAlign YGNodeStyleGetAlignItems(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetAlignSelf(YGNodeRef node, YGAlign alignSelf);
|
|
YG_EXPORT YGAlign YGNodeStyleGetAlignSelf(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetPositionType(
|
|
YGNodeRef node,
|
|
YGPositionType positionType);
|
|
YG_EXPORT YGPositionType YGNodeStyleGetPositionType(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexWrap(YGNodeRef node, YGWrap flexWrap);
|
|
YG_EXPORT YGWrap YGNodeStyleGetFlexWrap(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetOverflow(YGNodeRef node, YGOverflow overflow);
|
|
YG_EXPORT YGOverflow YGNodeStyleGetOverflow(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetDisplay(YGNodeRef node, YGDisplay display);
|
|
YG_EXPORT YGDisplay YGNodeStyleGetDisplay(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlex(YGNodeRef node, float flex);
|
|
YG_EXPORT float YGNodeStyleGetFlex(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexGrow(YGNodeRef node, float flexGrow);
|
|
YG_EXPORT float YGNodeStyleGetFlexGrow(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexShrink(YGNodeRef node, float flexShrink);
|
|
YG_EXPORT float YGNodeStyleGetFlexShrink(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexBasis(YGNodeRef node, float flexBasis);
|
|
YG_EXPORT void YGNodeStyleSetFlexBasisPercent(YGNodeRef node, float flexBasis);
|
|
YG_EXPORT void YGNodeStyleSetFlexBasisAuto(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexBasisMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexBasisFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetFlexBasisStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetFlexBasis(YGNodeConstRef node);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float position);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float position);
|
|
YG_EXPORT YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT void YGNodeStyleSetPositionAuto(YGNodeRef node, YGEdge edge);
|
|
YG_EXPORT
|
|
void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float margin);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float margin);
|
|
YG_EXPORT void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge);
|
|
YG_EXPORT YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float padding);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float padding);
|
|
YG_EXPORT YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT void YGNodeStyleSetBorder(YGNodeRef node, YGEdge edge, float border);
|
|
YG_EXPORT float YGNodeStyleGetBorder(YGNodeConstRef node, YGEdge edge);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetGap(YGNodeRef node, YGGutter gutter, float gapLength);
|
|
YG_EXPORT void
|
|
YGNodeStyleSetGapPercent(YGNodeRef node, YGGutter gutter, float gapLength);
|
|
YG_EXPORT YGValue YGNodeStyleGetGap(YGNodeConstRef node, YGGutter gutter);
|
|
YG_EXPORT void YGNodeStyleSetBoxSizing(YGNodeRef node, YGBoxSizing boxSizing);
|
|
YG_EXPORT YGBoxSizing YGNodeStyleGetBoxSizing(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetWidth(YGNodeRef node, float width);
|
|
YG_EXPORT void YGNodeStyleSetWidthPercent(YGNodeRef node, float width);
|
|
YG_EXPORT void YGNodeStyleSetWidthAuto(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetWidthMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetWidthFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetWidthStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetWidth(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetHeight(YGNodeRef node, float height);
|
|
YG_EXPORT void YGNodeStyleSetHeightPercent(YGNodeRef node, float height);
|
|
YG_EXPORT void YGNodeStyleSetHeightAuto(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetHeightMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetHeightFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetHeightStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetHeight(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetMinWidth(YGNodeRef node, float minWidth);
|
|
YG_EXPORT void YGNodeStyleSetMinWidthPercent(YGNodeRef node, float minWidth);
|
|
YG_EXPORT void YGNodeStyleSetMinWidthMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMinWidthFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMinWidthStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetMinWidth(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetMinHeight(YGNodeRef node, float minHeight);
|
|
YG_EXPORT void YGNodeStyleSetMinHeightPercent(YGNodeRef node, float minHeight);
|
|
YG_EXPORT void YGNodeStyleSetMinHeightMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMinHeightFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMinHeightStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetMinHeight(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetMaxWidth(YGNodeRef node, float maxWidth);
|
|
YG_EXPORT void YGNodeStyleSetMaxWidthPercent(YGNodeRef node, float maxWidth);
|
|
YG_EXPORT void YGNodeStyleSetMaxWidthMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMaxWidthFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMaxWidthStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetMaxWidth(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetMaxHeight(YGNodeRef node, float maxHeight);
|
|
YG_EXPORT void YGNodeStyleSetMaxHeightPercent(YGNodeRef node, float maxHeight);
|
|
YG_EXPORT void YGNodeStyleSetMaxHeightMaxContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMaxHeightFitContent(YGNodeRef node);
|
|
YG_EXPORT void YGNodeStyleSetMaxHeightStretch(YGNodeRef node);
|
|
YG_EXPORT YGValue YGNodeStyleGetMaxHeight(YGNodeConstRef node);
|
|
YG_EXPORT void YGNodeStyleSetAspectRatio(YGNodeRef node, float aspectRatio);
|
|
YG_EXPORT float YGNodeStyleGetAspectRatio(YGNodeConstRef node);
|
|
YG_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGPixelGrid.h}:
|
|
YG_EXTERN_C_BEGIN
|
|
YG_EXPORT float YGRoundValueToPixelGrid(
|
|
double value,
|
|
double pointScaleFactor,
|
|
bool forceCeil,
|
|
bool forceFloor);
|
|
YG_EXTERN_C_END
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/YGValue.h}:
|
|
constexpr float YGUndefined = std::numeric_limits<float>::quiet_NaN();
|
|
YG_EXTERN_C_BEGIN
|
|
typedef struct YGValue {
|
|
float value;
|
|
YGUnit unit;
|
|
} YGValue;
|
|
YG_EXPORT extern const YGValue YGValueAuto;
|
|
YG_EXPORT extern const YGValue YGValueUndefined;
|
|
YG_EXPORT extern const YGValue YGValueZero;
|
|
YG_EXPORT bool YGFloatIsUndefined(float value);
|
|
YG_EXTERN_C_END
|
|
inline bool operator==(const YGValue& lhs, const YGValue& rhs) {
|
|
if (lhs.unit != rhs.unit) {
|
|
return false;
|
|
}
|
|
switch (lhs.unit) {
|
|
case YGUnitUndefined:
|
|
case YGUnitAuto:
|
|
case YGUnitFitContent:
|
|
case YGUnitMaxContent:
|
|
case YGUnitStretch:
|
|
return true;
|
|
case YGUnitPoint:
|
|
case YGUnitPercent:
|
|
return lhs.value == rhs.value;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
inline bool operator!=(const YGValue& lhs, const YGValue& rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
inline YGValue operator-(const YGValue& value) {
|
|
return {-value.value, value.unit};
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/Yoga.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/AbsoluteLayout.h}:
|
|
namespace facebook::yoga {
|
|
void layoutAbsoluteChild(
|
|
const yoga::Node* containingNode,
|
|
const yoga::Node* node,
|
|
yoga::Node* child,
|
|
float containingBlockWidth,
|
|
float containingBlockHeight,
|
|
SizingMode widthMode,
|
|
Direction direction,
|
|
LayoutData& layoutMarkerData,
|
|
uint32_t depth,
|
|
uint32_t generationCount);
|
|
bool layoutAbsoluteDescendants(
|
|
yoga::Node* containingNode,
|
|
yoga::Node* currentNode,
|
|
SizingMode widthSizingMode,
|
|
Direction currentNodeDirection,
|
|
LayoutData& layoutMarkerData,
|
|
uint32_t currentDepth,
|
|
uint32_t generationCount,
|
|
float currentNodeMainOffsetFromContainingBlock,
|
|
float currentNodeCrossOffsetFromContainingBlock,
|
|
float containingNodeAvailableInnerWidth,
|
|
float containingNodeAvailableInnerHeight);
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/Align.h}:
|
|
namespace facebook::yoga {
|
|
inline Align resolveChildAlignment(
|
|
const yoga::Node* node,
|
|
const yoga::Node* child) {
|
|
const Align align = child->style().alignSelf() == Align::Auto
|
|
? node->style().alignItems()
|
|
: child->style().alignSelf();
|
|
if (align == Align::Baseline && isColumn(node->style().flexDirection())) {
|
|
return Align::FlexStart;
|
|
}
|
|
return align;
|
|
}
|
|
constexpr Align fallbackAlignment(Align align) {
|
|
switch (align) {
|
|
case Align::SpaceBetween:
|
|
case Align::Stretch:
|
|
return Align::FlexStart;
|
|
case Align::SpaceAround:
|
|
case Align::SpaceEvenly:
|
|
return Align::FlexStart;
|
|
default:
|
|
return align;
|
|
}
|
|
}
|
|
constexpr Justify fallbackAlignment(Justify align) {
|
|
switch (align) {
|
|
case Justify::SpaceBetween:
|
|
return Justify::FlexStart;
|
|
case Justify::SpaceAround:
|
|
case Justify::SpaceEvenly:
|
|
return Justify::FlexStart;
|
|
default:
|
|
return align;
|
|
}
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/Baseline.h}:
|
|
namespace facebook::yoga {
|
|
float calculateBaseline(const yoga::Node* node);
|
|
bool isBaselineLayout(const yoga::Node* node);
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/BoundAxis.h}:
|
|
namespace facebook::yoga {
|
|
inline float paddingAndBorderForAxis(
|
|
const yoga::Node* const node,
|
|
const FlexDirection axis,
|
|
const Direction direction,
|
|
const float widthSize) {
|
|
return node->style().computeInlineStartPaddingAndBorder(
|
|
axis, direction, widthSize) +
|
|
node->style().computeInlineEndPaddingAndBorder(
|
|
axis, direction, widthSize);
|
|
}
|
|
inline FloatOptional boundAxisWithinMinAndMax(
|
|
const yoga::Node* const node,
|
|
const Direction direction,
|
|
const FlexDirection axis,
|
|
const FloatOptional value,
|
|
const float axisSize,
|
|
const float widthSize) {
|
|
FloatOptional min;
|
|
FloatOptional max;
|
|
if (isColumn(axis)) {
|
|
min = node->style().resolvedMinDimension(
|
|
direction, Dimension::Height, axisSize, widthSize);
|
|
max = node->style().resolvedMaxDimension(
|
|
direction, Dimension::Height, axisSize, widthSize);
|
|
} else if (isRow(axis)) {
|
|
min = node->style().resolvedMinDimension(
|
|
direction, Dimension::Width, axisSize, widthSize);
|
|
max = node->style().resolvedMaxDimension(
|
|
direction, Dimension::Width, axisSize, widthSize);
|
|
}
|
|
if (max >= FloatOptional{0} && value > max) {
|
|
return max;
|
|
}
|
|
if (min >= FloatOptional{0} && value < min) {
|
|
return min;
|
|
}
|
|
return value;
|
|
}
|
|
inline float boundAxis(
|
|
const yoga::Node* const node,
|
|
const FlexDirection axis,
|
|
const Direction direction,
|
|
const float value,
|
|
const float axisSize,
|
|
const float widthSize) {
|
|
return yoga::maxOrDefined(
|
|
boundAxisWithinMinAndMax(
|
|
node, direction, axis, FloatOptional{value}, axisSize, widthSize)
|
|
.unwrap(),
|
|
paddingAndBorderForAxis(node, axis, direction, widthSize));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/Cache.h}:
|
|
namespace facebook::yoga {
|
|
bool canUseCachedMeasurement(
|
|
SizingMode widthMode,
|
|
float availableWidth,
|
|
SizingMode heightMode,
|
|
float availableHeight,
|
|
SizingMode lastWidthMode,
|
|
float lastAvailableWidth,
|
|
SizingMode lastHeightMode,
|
|
float lastAvailableHeight,
|
|
float lastComputedWidth,
|
|
float lastComputedHeight,
|
|
float marginRow,
|
|
float marginColumn,
|
|
const yoga::Config* config);
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/CalculateLayout.h}:
|
|
namespace facebook::yoga {
|
|
void calculateLayout(
|
|
yoga::Node* node,
|
|
float ownerWidth,
|
|
float ownerHeight,
|
|
Direction ownerDirection);
|
|
bool calculateLayoutInternal(
|
|
yoga::Node* node,
|
|
float availableWidth,
|
|
float availableHeight,
|
|
Direction ownerDirection,
|
|
SizingMode widthSizingMode,
|
|
SizingMode heightSizingMode,
|
|
float ownerWidth,
|
|
float ownerHeight,
|
|
bool performLayout,
|
|
LayoutPassReason reason,
|
|
LayoutData& layoutMarkerData,
|
|
uint32_t depth,
|
|
uint32_t generationCount);
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexDirection.h}:
|
|
namespace facebook::yoga {
|
|
inline bool isRow(const FlexDirection flexDirection) {
|
|
return flexDirection == FlexDirection::Row ||
|
|
flexDirection == FlexDirection::RowReverse;
|
|
}
|
|
inline bool isColumn(const FlexDirection flexDirection) {
|
|
return flexDirection == FlexDirection::Column ||
|
|
flexDirection == FlexDirection::ColumnReverse;
|
|
}
|
|
inline FlexDirection resolveDirection(
|
|
const FlexDirection flexDirection,
|
|
const Direction direction) {
|
|
if (direction == Direction::RTL) {
|
|
if (flexDirection == FlexDirection::Row) {
|
|
return FlexDirection::RowReverse;
|
|
} else if (flexDirection == FlexDirection::RowReverse) {
|
|
return FlexDirection::Row;
|
|
}
|
|
}
|
|
return flexDirection;
|
|
}
|
|
inline FlexDirection resolveCrossDirection(
|
|
const FlexDirection flexDirection,
|
|
const Direction direction) {
|
|
return isColumn(flexDirection)
|
|
? resolveDirection(FlexDirection::Row, direction)
|
|
: FlexDirection::Column;
|
|
}
|
|
inline PhysicalEdge flexStartEdge(FlexDirection flexDirection) {
|
|
switch (flexDirection) {
|
|
case FlexDirection::Column:
|
|
return PhysicalEdge::Top;
|
|
case FlexDirection::ColumnReverse:
|
|
return PhysicalEdge::Bottom;
|
|
case FlexDirection::Row:
|
|
return PhysicalEdge::Left;
|
|
case FlexDirection::RowReverse:
|
|
return PhysicalEdge::Right;
|
|
}
|
|
fatalWithMessage("Invalid FlexDirection");
|
|
}
|
|
inline PhysicalEdge flexEndEdge(FlexDirection flexDirection) {
|
|
switch (flexDirection) {
|
|
case FlexDirection::Column:
|
|
return PhysicalEdge::Bottom;
|
|
case FlexDirection::ColumnReverse:
|
|
return PhysicalEdge::Top;
|
|
case FlexDirection::Row:
|
|
return PhysicalEdge::Right;
|
|
case FlexDirection::RowReverse:
|
|
return PhysicalEdge::Left;
|
|
}
|
|
fatalWithMessage("Invalid FlexDirection");
|
|
}
|
|
inline PhysicalEdge inlineStartEdge(
|
|
FlexDirection flexDirection,
|
|
Direction direction) {
|
|
if (isRow(flexDirection)) {
|
|
return direction == Direction::RTL ? PhysicalEdge::Right
|
|
: PhysicalEdge::Left;
|
|
}
|
|
return PhysicalEdge::Top;
|
|
}
|
|
inline PhysicalEdge inlineEndEdge(
|
|
FlexDirection flexDirection,
|
|
Direction direction) {
|
|
if (isRow(flexDirection)) {
|
|
return direction == Direction::RTL ? PhysicalEdge::Left
|
|
: PhysicalEdge::Right;
|
|
}
|
|
return PhysicalEdge::Bottom;
|
|
}
|
|
inline Dimension dimension(FlexDirection flexDirection) {
|
|
switch (flexDirection) {
|
|
case FlexDirection::Column:
|
|
return Dimension::Height;
|
|
case FlexDirection::ColumnReverse:
|
|
return Dimension::Height;
|
|
case FlexDirection::Row:
|
|
return Dimension::Width;
|
|
case FlexDirection::RowReverse:
|
|
return Dimension::Width;
|
|
}
|
|
fatalWithMessage("Invalid FlexDirection");
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/FlexLine.h}:
|
|
namespace facebook::yoga {
|
|
struct FlexLineRunningLayout {
|
|
float totalFlexGrowFactors{0.0f};
|
|
float totalFlexShrinkScaledFactors{0.0f};
|
|
float remainingFreeSpace{0.0f};
|
|
float mainDim{0.0f};
|
|
float crossDim{0.0f};
|
|
};
|
|
struct FlexLine {
|
|
const std::vector<yoga::Node*> itemsInFlow{};
|
|
const float sizeConsumed{0.0f};
|
|
const size_t numberOfAutoMargins{0};
|
|
FlexLineRunningLayout layout{};
|
|
};
|
|
FlexLine calculateFlexLine(
|
|
yoga::Node* node,
|
|
Direction ownerDirection,
|
|
float ownerWidth,
|
|
float mainAxisOwnerSize,
|
|
float availableInnerWidth,
|
|
float availableInnerMainDim,
|
|
Node::LayoutableChildren::Iterator& iterator,
|
|
size_t lineCount);
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/PixelGrid.h}:
|
|
namespace facebook::yoga {
|
|
float roundValueToPixelGrid(
|
|
double value,
|
|
double pointScaleFactor,
|
|
bool forceCeil,
|
|
bool forceFloor);
|
|
void roundLayoutResultsToPixelGrid(
|
|
yoga::Node* node,
|
|
double absoluteLeft,
|
|
double absoluteTop);
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/SizingMode.h}:
|
|
namespace facebook::yoga {
|
|
enum class SizingMode {
|
|
StretchFit,
|
|
MaxContent,
|
|
FitContent,
|
|
};
|
|
inline MeasureMode measureMode(SizingMode mode) {
|
|
switch (mode) {
|
|
case SizingMode::StretchFit:
|
|
return MeasureMode::Exactly;
|
|
case SizingMode::MaxContent:
|
|
return MeasureMode::Undefined;
|
|
case SizingMode::FitContent:
|
|
return MeasureMode::AtMost;
|
|
}
|
|
fatalWithMessage("Invalid SizingMode");
|
|
}
|
|
inline SizingMode sizingMode(MeasureMode mode) {
|
|
switch (mode) {
|
|
case MeasureMode::Exactly:
|
|
return SizingMode::StretchFit;
|
|
case MeasureMode::Undefined:
|
|
return SizingMode::MaxContent;
|
|
case MeasureMode::AtMost:
|
|
return SizingMode::FitContent;
|
|
}
|
|
fatalWithMessage("Invalid MeasureMode");
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/algorithm/TrailingPosition.h}:
|
|
namespace facebook::yoga {
|
|
inline float getPositionOfOppositeEdge(
|
|
float position,
|
|
FlexDirection axis,
|
|
const yoga::Node* const containingNode,
|
|
const yoga::Node* const node) {
|
|
return containingNode->getLayout().measuredDimension(dimension(axis)) -
|
|
node->getLayout().measuredDimension(dimension(axis)) - position;
|
|
}
|
|
inline void setChildTrailingPosition(
|
|
const yoga::Node* const node,
|
|
yoga::Node* const child,
|
|
const FlexDirection axis) {
|
|
child->setLayoutPosition(
|
|
getPositionOfOppositeEdge(
|
|
child->getLayout().position(flexStartEdge(axis)), axis, node, child),
|
|
flexEndEdge(axis));
|
|
}
|
|
inline bool needsTrailingPosition(const FlexDirection axis) {
|
|
return axis == FlexDirection::RowReverse ||
|
|
axis == FlexDirection::ColumnReverse;
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/config/Config.h}:
|
|
struct YGConfig {};
|
|
namespace facebook::yoga {
|
|
using ExperimentalFeatureSet = std::bitset<ordinalCount<ExperimentalFeature>()>;
|
|
bool configUpdateInvalidatesLayout(
|
|
const Config& oldConfig,
|
|
const Config& newConfig);
|
|
class YG_EXPORT Config : public ::YGConfig {
|
|
public:
|
|
explicit Config(YGLogger logger) : logger_{logger} {}
|
|
void setUseWebDefaults(bool useWebDefaults);
|
|
bool useWebDefaults() const;
|
|
void setExperimentalFeatureEnabled(ExperimentalFeature feature, bool enabled);
|
|
bool isExperimentalFeatureEnabled(ExperimentalFeature feature) const;
|
|
ExperimentalFeatureSet getEnabledExperiments() const;
|
|
void setErrata(Errata errata);
|
|
void addErrata(Errata errata);
|
|
void removeErrata(Errata errata);
|
|
Errata getErrata() const;
|
|
bool hasErrata(Errata errata) const;
|
|
void setPointScaleFactor(float pointScaleFactor);
|
|
float getPointScaleFactor() const;
|
|
void setContext(void* context);
|
|
void* getContext() const;
|
|
uint32_t getVersion() const noexcept;
|
|
void setLogger(YGLogger logger);
|
|
void log(
|
|
const yoga::Node* node,
|
|
LogLevel logLevel,
|
|
const char* format,
|
|
va_list args) const;
|
|
void setCloneNodeCallback(YGCloneNodeFunc cloneNode);
|
|
YGNodeRef
|
|
cloneNode(YGNodeConstRef node, YGNodeConstRef owner, size_t childIndex) const;
|
|
static const Config& getDefault();
|
|
};
|
|
YGLogger logger_{};
|
|
bool useWebDefaults_ : 1 = false;
|
|
uint32_t version_ = 0;
|
|
ExperimentalFeatureSet experimentalFeatures_{};
|
|
Errata errata_ = Errata::None;
|
|
float pointScaleFactor_ = 1.0f;
|
|
void* context_ = nullptr;
|
|
};
|
|
inline Config* resolveRef(const YGConfigRef ref) {
|
|
return static_cast<Config*>(ref);
|
|
}
|
|
inline const Config* resolveRef(const YGConfigConstRef ref) {
|
|
return static_cast<const Config*>(ref);
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/debug/AssertFatal.h}:
|
|
namespace facebook::yoga {
|
|
[[noreturn]] void fatalWithMessage(const char* message);
|
|
void assertFatal(bool condition, const char* message);
|
|
void assertFatalWithNode(
|
|
const yoga::Node* node,
|
|
bool condition,
|
|
const char* message);
|
|
void assertFatalWithConfig(
|
|
const yoga::Config* config,
|
|
bool condition,
|
|
const char* message);
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/debug/Log.h}:
|
|
namespace facebook::yoga {
|
|
void log(LogLevel level, const char* format, ...) noexcept;
|
|
void log(
|
|
const yoga::Node* node,
|
|
LogLevel level,
|
|
const char* format,
|
|
...) noexcept;
|
|
void log(
|
|
const yoga::Config* config,
|
|
LogLevel level,
|
|
const char* format,
|
|
...) noexcept;
|
|
YGLogger getDefaultLogger();
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Align.h}:
|
|
namespace facebook::yoga {
|
|
enum class Align : uint8_t {
|
|
Auto = YGAlignAuto,
|
|
FlexStart = YGAlignFlexStart,
|
|
Center = YGAlignCenter,
|
|
FlexEnd = YGAlignFlexEnd,
|
|
Stretch = YGAlignStretch,
|
|
Baseline = YGAlignBaseline,
|
|
SpaceBetween = YGAlignSpaceBetween,
|
|
SpaceAround = YGAlignSpaceAround,
|
|
SpaceEvenly = YGAlignSpaceEvenly,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Align>() {
|
|
return 9;
|
|
}
|
|
constexpr Align scopedEnum(YGAlign unscoped) {
|
|
return static_cast<Align>(unscoped);
|
|
}
|
|
constexpr YGAlign unscopedEnum(Align scoped) {
|
|
return static_cast<YGAlign>(scoped);
|
|
}
|
|
inline const char* toString(Align e) {
|
|
return YGAlignToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/BoxSizing.h}:
|
|
namespace facebook::yoga {
|
|
enum class BoxSizing : uint8_t {
|
|
BorderBox = YGBoxSizingBorderBox,
|
|
ContentBox = YGBoxSizingContentBox,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<BoxSizing>() {
|
|
return 2;
|
|
}
|
|
constexpr BoxSizing scopedEnum(YGBoxSizing unscoped) {
|
|
return static_cast<BoxSizing>(unscoped);
|
|
}
|
|
constexpr YGBoxSizing unscopedEnum(BoxSizing scoped) {
|
|
return static_cast<YGBoxSizing>(scoped);
|
|
}
|
|
inline const char* toString(BoxSizing e) {
|
|
return YGBoxSizingToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Dimension.h}:
|
|
namespace facebook::yoga {
|
|
enum class Dimension : uint8_t {
|
|
Width = YGDimensionWidth,
|
|
Height = YGDimensionHeight,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Dimension>() {
|
|
return 2;
|
|
}
|
|
constexpr Dimension scopedEnum(YGDimension unscoped) {
|
|
return static_cast<Dimension>(unscoped);
|
|
}
|
|
constexpr YGDimension unscopedEnum(Dimension scoped) {
|
|
return static_cast<YGDimension>(scoped);
|
|
}
|
|
inline const char* toString(Dimension e) {
|
|
return YGDimensionToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Direction.h}:
|
|
namespace facebook::yoga {
|
|
enum class Direction : uint8_t {
|
|
Inherit = YGDirectionInherit,
|
|
LTR = YGDirectionLTR,
|
|
RTL = YGDirectionRTL,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Direction>() {
|
|
return 3;
|
|
}
|
|
constexpr Direction scopedEnum(YGDirection unscoped) {
|
|
return static_cast<Direction>(unscoped);
|
|
}
|
|
constexpr YGDirection unscopedEnum(Direction scoped) {
|
|
return static_cast<YGDirection>(scoped);
|
|
}
|
|
inline const char* toString(Direction e) {
|
|
return YGDirectionToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Display.h}:
|
|
namespace facebook::yoga {
|
|
enum class Display : uint8_t {
|
|
Flex = YGDisplayFlex,
|
|
None = YGDisplayNone,
|
|
Contents = YGDisplayContents,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Display>() {
|
|
return 3;
|
|
}
|
|
constexpr Display scopedEnum(YGDisplay unscoped) {
|
|
return static_cast<Display>(unscoped);
|
|
}
|
|
constexpr YGDisplay unscopedEnum(Display scoped) {
|
|
return static_cast<YGDisplay>(scoped);
|
|
}
|
|
inline const char* toString(Display e) {
|
|
return YGDisplayToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Edge.h}:
|
|
namespace facebook::yoga {
|
|
enum class Edge : uint8_t {
|
|
Left = YGEdgeLeft,
|
|
Top = YGEdgeTop,
|
|
Right = YGEdgeRight,
|
|
Bottom = YGEdgeBottom,
|
|
Start = YGEdgeStart,
|
|
End = YGEdgeEnd,
|
|
Horizontal = YGEdgeHorizontal,
|
|
Vertical = YGEdgeVertical,
|
|
All = YGEdgeAll,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Edge>() {
|
|
return 9;
|
|
}
|
|
constexpr Edge scopedEnum(YGEdge unscoped) {
|
|
return static_cast<Edge>(unscoped);
|
|
}
|
|
constexpr YGEdge unscopedEnum(Edge scoped) {
|
|
return static_cast<YGEdge>(scoped);
|
|
}
|
|
inline const char* toString(Edge e) {
|
|
return YGEdgeToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Errata.h}:
|
|
namespace facebook::yoga {
|
|
enum class Errata : uint32_t {
|
|
None = YGErrataNone,
|
|
StretchFlexBasis = YGErrataStretchFlexBasis,
|
|
AbsolutePositionWithoutInsetsExcludesPadding =
|
|
YGErrataAbsolutePositionWithoutInsetsExcludesPadding,
|
|
AbsolutePercentAgainstInnerSize = YGErrataAbsolutePercentAgainstInnerSize,
|
|
All = YGErrataAll,
|
|
Classic = YGErrataClassic,
|
|
};
|
|
YG_DEFINE_ENUM_FLAG_OPERATORS(Errata)
|
|
constexpr Errata scopedEnum(YGErrata unscoped) {
|
|
return static_cast<Errata>(unscoped);
|
|
}
|
|
constexpr YGErrata unscopedEnum(Errata scoped) {
|
|
return static_cast<YGErrata>(scoped);
|
|
}
|
|
inline const char* toString(Errata e) {
|
|
return YGErrataToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/ExperimentalFeature.h}:
|
|
namespace facebook::yoga {
|
|
enum class ExperimentalFeature : uint8_t {
|
|
WebFlexBasis = YGExperimentalFeatureWebFlexBasis,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<ExperimentalFeature>() {
|
|
return 1;
|
|
}
|
|
constexpr ExperimentalFeature scopedEnum(YGExperimentalFeature unscoped) {
|
|
return static_cast<ExperimentalFeature>(unscoped);
|
|
}
|
|
constexpr YGExperimentalFeature unscopedEnum(ExperimentalFeature scoped) {
|
|
return static_cast<YGExperimentalFeature>(scoped);
|
|
}
|
|
inline const char* toString(ExperimentalFeature e) {
|
|
return YGExperimentalFeatureToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/FlexDirection.h}:
|
|
namespace facebook::yoga {
|
|
enum class FlexDirection : uint8_t {
|
|
Column = YGFlexDirectionColumn,
|
|
ColumnReverse = YGFlexDirectionColumnReverse,
|
|
Row = YGFlexDirectionRow,
|
|
RowReverse = YGFlexDirectionRowReverse,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<FlexDirection>() {
|
|
return 4;
|
|
}
|
|
constexpr FlexDirection scopedEnum(YGFlexDirection unscoped) {
|
|
return static_cast<FlexDirection>(unscoped);
|
|
}
|
|
constexpr YGFlexDirection unscopedEnum(FlexDirection scoped) {
|
|
return static_cast<YGFlexDirection>(scoped);
|
|
}
|
|
inline const char* toString(FlexDirection e) {
|
|
return YGFlexDirectionToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Gutter.h}:
|
|
namespace facebook::yoga {
|
|
enum class Gutter : uint8_t {
|
|
Column = YGGutterColumn,
|
|
Row = YGGutterRow,
|
|
All = YGGutterAll,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Gutter>() {
|
|
return 3;
|
|
}
|
|
constexpr Gutter scopedEnum(YGGutter unscoped) {
|
|
return static_cast<Gutter>(unscoped);
|
|
}
|
|
constexpr YGGutter unscopedEnum(Gutter scoped) {
|
|
return static_cast<YGGutter>(scoped);
|
|
}
|
|
inline const char* toString(Gutter e) {
|
|
return YGGutterToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Justify.h}:
|
|
namespace facebook::yoga {
|
|
enum class Justify : uint8_t {
|
|
FlexStart = YGJustifyFlexStart,
|
|
Center = YGJustifyCenter,
|
|
FlexEnd = YGJustifyFlexEnd,
|
|
SpaceBetween = YGJustifySpaceBetween,
|
|
SpaceAround = YGJustifySpaceAround,
|
|
SpaceEvenly = YGJustifySpaceEvenly,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Justify>() {
|
|
return 6;
|
|
}
|
|
constexpr Justify scopedEnum(YGJustify unscoped) {
|
|
return static_cast<Justify>(unscoped);
|
|
}
|
|
constexpr YGJustify unscopedEnum(Justify scoped) {
|
|
return static_cast<YGJustify>(scoped);
|
|
}
|
|
inline const char* toString(Justify e) {
|
|
return YGJustifyToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/LogLevel.h}:
|
|
namespace facebook::yoga {
|
|
enum class LogLevel : uint8_t {
|
|
Error = YGLogLevelError,
|
|
Warn = YGLogLevelWarn,
|
|
Info = YGLogLevelInfo,
|
|
Debug = YGLogLevelDebug,
|
|
Verbose = YGLogLevelVerbose,
|
|
Fatal = YGLogLevelFatal,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<LogLevel>() {
|
|
return 6;
|
|
}
|
|
constexpr LogLevel scopedEnum(YGLogLevel unscoped) {
|
|
return static_cast<LogLevel>(unscoped);
|
|
}
|
|
constexpr YGLogLevel unscopedEnum(LogLevel scoped) {
|
|
return static_cast<YGLogLevel>(scoped);
|
|
}
|
|
inline const char* toString(LogLevel e) {
|
|
return YGLogLevelToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/MeasureMode.h}:
|
|
namespace facebook::yoga {
|
|
enum class MeasureMode : uint8_t {
|
|
Undefined = YGMeasureModeUndefined,
|
|
Exactly = YGMeasureModeExactly,
|
|
AtMost = YGMeasureModeAtMost,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<MeasureMode>() {
|
|
return 3;
|
|
}
|
|
constexpr MeasureMode scopedEnum(YGMeasureMode unscoped) {
|
|
return static_cast<MeasureMode>(unscoped);
|
|
}
|
|
constexpr YGMeasureMode unscopedEnum(MeasureMode scoped) {
|
|
return static_cast<YGMeasureMode>(scoped);
|
|
}
|
|
inline const char* toString(MeasureMode e) {
|
|
return YGMeasureModeToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/NodeType.h}:
|
|
namespace facebook::yoga {
|
|
enum class NodeType : uint8_t {
|
|
Default = YGNodeTypeDefault,
|
|
Text = YGNodeTypeText,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<NodeType>() {
|
|
return 2;
|
|
}
|
|
constexpr NodeType scopedEnum(YGNodeType unscoped) {
|
|
return static_cast<NodeType>(unscoped);
|
|
}
|
|
constexpr YGNodeType unscopedEnum(NodeType scoped) {
|
|
return static_cast<YGNodeType>(scoped);
|
|
}
|
|
inline const char* toString(NodeType e) {
|
|
return YGNodeTypeToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Overflow.h}:
|
|
namespace facebook::yoga {
|
|
enum class Overflow : uint8_t {
|
|
Visible = YGOverflowVisible,
|
|
Hidden = YGOverflowHidden,
|
|
Scroll = YGOverflowScroll,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Overflow>() {
|
|
return 3;
|
|
}
|
|
constexpr Overflow scopedEnum(YGOverflow unscoped) {
|
|
return static_cast<Overflow>(unscoped);
|
|
}
|
|
constexpr YGOverflow unscopedEnum(Overflow scoped) {
|
|
return static_cast<YGOverflow>(scoped);
|
|
}
|
|
inline const char* toString(Overflow e) {
|
|
return YGOverflowToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/PhysicalEdge.h}:
|
|
namespace facebook::yoga {
|
|
enum class PhysicalEdge : uint32_t {
|
|
Left = yoga::to_underlying(Edge::Left),
|
|
Top = yoga::to_underlying(Edge::Top),
|
|
Right = yoga::to_underlying(Edge::Right),
|
|
Bottom = yoga::to_underlying(Edge::Bottom),
|
|
};
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/PositionType.h}:
|
|
namespace facebook::yoga {
|
|
enum class PositionType : uint8_t {
|
|
Static = YGPositionTypeStatic,
|
|
Relative = YGPositionTypeRelative,
|
|
Absolute = YGPositionTypeAbsolute,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<PositionType>() {
|
|
return 3;
|
|
}
|
|
constexpr PositionType scopedEnum(YGPositionType unscoped) {
|
|
return static_cast<PositionType>(unscoped);
|
|
}
|
|
constexpr YGPositionType unscopedEnum(PositionType scoped) {
|
|
return static_cast<YGPositionType>(scoped);
|
|
}
|
|
inline const char* toString(PositionType e) {
|
|
return YGPositionTypeToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Unit.h}:
|
|
namespace facebook::yoga {
|
|
enum class Unit : uint8_t {
|
|
Undefined = YGUnitUndefined,
|
|
Point = YGUnitPoint,
|
|
Percent = YGUnitPercent,
|
|
Auto = YGUnitAuto,
|
|
MaxContent = YGUnitMaxContent,
|
|
FitContent = YGUnitFitContent,
|
|
Stretch = YGUnitStretch,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Unit>() {
|
|
return 7;
|
|
}
|
|
constexpr Unit scopedEnum(YGUnit unscoped) {
|
|
return static_cast<Unit>(unscoped);
|
|
}
|
|
constexpr YGUnit unscopedEnum(Unit scoped) {
|
|
return static_cast<YGUnit>(scoped);
|
|
}
|
|
inline const char* toString(Unit e) {
|
|
return YGUnitToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/Wrap.h}:
|
|
namespace facebook::yoga {
|
|
enum class Wrap : uint8_t {
|
|
NoWrap = YGWrapNoWrap,
|
|
Wrap = YGWrapWrap,
|
|
WrapReverse = YGWrapWrapReverse,
|
|
};
|
|
template <>
|
|
constexpr int32_t ordinalCount<Wrap>() {
|
|
return 3;
|
|
}
|
|
constexpr Wrap scopedEnum(YGWrap unscoped) {
|
|
return static_cast<Wrap>(unscoped);
|
|
}
|
|
constexpr YGWrap unscopedEnum(Wrap scoped) {
|
|
return static_cast<YGWrap>(scoped);
|
|
}
|
|
inline const char* toString(Wrap e) {
|
|
return YGWrapToString(unscopedEnum(e));
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/enums/YogaEnums.h}:
|
|
namespace facebook::yoga {
|
|
template <typename EnumT>
|
|
concept Enumeration = std::is_enum_v<EnumT>;
|
|
template <Enumeration EnumT>
|
|
constexpr int32_t ordinalCount();
|
|
template <typename EnumT>
|
|
concept HasOrdinality = (ordinalCount<EnumT>() > 0);
|
|
template <HasOrdinality EnumT>
|
|
constexpr int32_t bitCount() {
|
|
return std::bit_width(
|
|
static_cast<std::underlying_type_t<EnumT>>(ordinalCount<EnumT>() - 1));
|
|
}
|
|
constexpr auto to_underlying(Enumeration auto e) noexcept {
|
|
return static_cast<std::underlying_type_t<decltype(e)>>(e);
|
|
}
|
|
template <HasOrdinality EnumT>
|
|
auto ordinals() {
|
|
struct Iterator {
|
|
EnumT e{};
|
|
EnumT operator*() const {
|
|
return e;
|
|
}
|
|
Iterator& operator++() {
|
|
e = static_cast<EnumT>(to_underlying(e) + 1);
|
|
return *this;
|
|
}
|
|
bool operator==(const Iterator& other) const = default;
|
|
bool operator!=(const Iterator& other) const = default;
|
|
};
|
|
struct Range {
|
|
Iterator begin() const {
|
|
return Iterator{};
|
|
}
|
|
Iterator end() const {
|
|
return Iterator{static_cast<EnumT>(ordinalCount<EnumT>())};
|
|
}
|
|
};
|
|
return Range{};
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/event/event.h}:
|
|
namespace facebook::yoga {
|
|
enum struct LayoutType : int {
|
|
kLayout = 0,
|
|
kMeasure = 1,
|
|
kCachedLayout = 2,
|
|
kCachedMeasure = 3
|
|
};
|
|
enum struct LayoutPassReason : int {
|
|
kInitial = 0,
|
|
kAbsLayout = 1,
|
|
kStretch = 2,
|
|
kMultilineStretch = 3,
|
|
kFlexLayout = 4,
|
|
kMeasureChild = 5,
|
|
kAbsMeasureChild = 6,
|
|
kFlexMeasure = 7,
|
|
COUNT
|
|
};
|
|
struct LayoutData {
|
|
int layouts = 0;
|
|
int measures = 0;
|
|
uint32_t maxMeasureCache = 0;
|
|
int cachedLayouts = 0;
|
|
int cachedMeasures = 0;
|
|
int measureCallbacks = 0;
|
|
std::array<int, static_cast<uint8_t>(LayoutPassReason::COUNT)>
|
|
measureCallbackReasonsCount;
|
|
};
|
|
const char* LayoutPassReasonToString(LayoutPassReason value);
|
|
struct YG_EXPORT Event {
|
|
enum Type {
|
|
NodeAllocation,
|
|
NodeDeallocation,
|
|
NodeLayout,
|
|
LayoutPassStart,
|
|
LayoutPassEnd,
|
|
MeasureCallbackStart,
|
|
MeasureCallbackEnd,
|
|
NodeBaselineStart,
|
|
NodeBaselineEnd,
|
|
};
|
|
using Subscriber = void(YGNodeConstRef, Type, Data);
|
|
using Subscribers = std::vector<std::function<Subscriber>>;
|
|
template <Type E>
|
|
struct TypedData {};
|
|
class Data {
|
|
const void* data_;
|
|
|
|
public:
|
|
template <Type E>
|
|
explicit Data(const TypedData<E>& data) : data_{&data} {}
|
|
template <Type E>
|
|
const TypedData<E>& get() const {
|
|
return *static_cast<const TypedData<E>*>(data_);
|
|
}
|
|
};
|
|
static void reset();
|
|
static void subscribe(std::function<Subscriber>&& subscriber);
|
|
template <Type E>
|
|
static void publish(YGNodeConstRef node, const TypedData<E>& eventData = {}) {
|
|
publish(node, E, Data{eventData});
|
|
}
|
|
};
|
|
template <>
|
|
struct Event::TypedData<Event::NodeAllocation> {
|
|
YGConfigConstRef config;
|
|
};
|
|
template <>
|
|
struct Event::TypedData<Event::NodeDeallocation> {
|
|
YGConfigConstRef config;
|
|
};
|
|
template <>
|
|
struct Event::TypedData<Event::LayoutPassEnd> {
|
|
LayoutData* layoutData;
|
|
};
|
|
template <>
|
|
struct Event::TypedData<Event::MeasureCallbackEnd> {
|
|
float width;
|
|
YGMeasureMode widthMeasureMode;
|
|
float height;
|
|
YGMeasureMode heightMeasureMode;
|
|
float measuredWidth;
|
|
float measuredHeight;
|
|
const LayoutPassReason reason;
|
|
};
|
|
template <>
|
|
struct Event::TypedData<Event::NodeLayout> {
|
|
LayoutType layoutType;
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/node/CachedMeasurement.h}:
|
|
namespace facebook::yoga {
|
|
struct CachedMeasurement {
|
|
float availableWidth{-1};
|
|
float availableHeight{-1};
|
|
SizingMode widthSizingMode{SizingMode::MaxContent};
|
|
SizingMode heightSizingMode{SizingMode::MaxContent};
|
|
float computedWidth{-1};
|
|
float computedHeight{-1};
|
|
bool operator==(CachedMeasurement measurement) const {
|
|
bool isEqual = widthSizingMode == measurement.widthSizingMode &&
|
|
heightSizingMode == measurement.heightSizingMode;
|
|
if (!yoga::isUndefined(availableWidth) ||
|
|
!yoga::isUndefined(measurement.availableWidth)) {
|
|
isEqual = isEqual && availableWidth == measurement.availableWidth;
|
|
}
|
|
if (!yoga::isUndefined(availableHeight) ||
|
|
!yoga::isUndefined(measurement.availableHeight)) {
|
|
isEqual = isEqual && availableHeight == measurement.availableHeight;
|
|
}
|
|
if (!yoga::isUndefined(computedWidth) ||
|
|
!yoga::isUndefined(measurement.computedWidth)) {
|
|
isEqual = isEqual && computedWidth == measurement.computedWidth;
|
|
}
|
|
if (!yoga::isUndefined(computedHeight) ||
|
|
!yoga::isUndefined(measurement.computedHeight)) {
|
|
isEqual = isEqual && computedHeight == measurement.computedHeight;
|
|
}
|
|
return isEqual;
|
|
}
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/node/LayoutResults.h}:
|
|
namespace facebook::yoga {
|
|
struct LayoutResults {
|
|
static constexpr int32_t MaxCachedMeasurements = 8;
|
|
uint32_t computedFlexBasisGeneration = 0;
|
|
FloatOptional computedFlexBasis = {};
|
|
uint32_t generationCount = 0;
|
|
uint32_t configVersion = 0;
|
|
Direction lastOwnerDirection = Direction::Inherit;
|
|
uint32_t nextCachedMeasurementsIndex = 0;
|
|
std::array<CachedMeasurement, MaxCachedMeasurements> cachedMeasurements = {};
|
|
CachedMeasurement cachedLayout{};
|
|
Direction direction() const {
|
|
return direction_;
|
|
}
|
|
void setDirection(Direction direction) {
|
|
direction_ = direction;
|
|
}
|
|
bool hadOverflow() const {
|
|
return hadOverflow_;
|
|
}
|
|
void setHadOverflow(bool hadOverflow) {
|
|
hadOverflow_ = hadOverflow;
|
|
}
|
|
float dimension(Dimension axis) const {
|
|
return dimensions_[yoga::to_underlying(axis)];
|
|
}
|
|
void setDimension(Dimension axis, float dimension) {
|
|
dimensions_[yoga::to_underlying(axis)] = dimension;
|
|
}
|
|
float measuredDimension(Dimension axis) const {
|
|
return measuredDimensions_[yoga::to_underlying(axis)];
|
|
}
|
|
float rawDimension(Dimension axis) const {
|
|
return rawDimensions_[yoga::to_underlying(axis)];
|
|
}
|
|
void setMeasuredDimension(Dimension axis, float dimension) {
|
|
measuredDimensions_[yoga::to_underlying(axis)] = dimension;
|
|
}
|
|
void setRawDimension(Dimension axis, float dimension) {
|
|
rawDimensions_[yoga::to_underlying(axis)] = dimension;
|
|
}
|
|
float position(PhysicalEdge physicalEdge) const {
|
|
return position_[yoga::to_underlying(physicalEdge)];
|
|
}
|
|
void setPosition(PhysicalEdge physicalEdge, float dimension) {
|
|
position_[yoga::to_underlying(physicalEdge)] = dimension;
|
|
}
|
|
float margin(PhysicalEdge physicalEdge) const {
|
|
return margin_[yoga::to_underlying(physicalEdge)];
|
|
}
|
|
void setMargin(PhysicalEdge physicalEdge, float dimension) {
|
|
margin_[yoga::to_underlying(physicalEdge)] = dimension;
|
|
}
|
|
float border(PhysicalEdge physicalEdge) const {
|
|
return border_[yoga::to_underlying(physicalEdge)];
|
|
}
|
|
void setBorder(PhysicalEdge physicalEdge, float dimension) {
|
|
border_[yoga::to_underlying(physicalEdge)] = dimension;
|
|
}
|
|
float padding(PhysicalEdge physicalEdge) const {
|
|
return padding_[yoga::to_underlying(physicalEdge)];
|
|
}
|
|
void setPadding(PhysicalEdge physicalEdge, float dimension) {
|
|
padding_[yoga::to_underlying(physicalEdge)] = dimension;
|
|
}
|
|
bool operator==(LayoutResults layout) const;
|
|
bool operator!=(LayoutResults layout) const {
|
|
return !(*this == layout);
|
|
}
|
|
};
|
|
std::array<float, 2> measuredDimensions_ = {{YGUndefined, YGUndefined}};
|
|
std::array<float, 2> rawDimensions_ = {{YGUndefined, YGUndefined}};
|
|
std::array<float, 4> position_ = {};
|
|
std::array<float, 4> margin_ = {};
|
|
std::array<float, 4> border_ = {};
|
|
std::array<float, 4> padding_ = {};
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/node/LayoutableChildren.h}:
|
|
namespace facebook::yoga {
|
|
template <typename T>
|
|
class LayoutableChildren {
|
|
public:
|
|
struct Iterator {
|
|
using iterator_category = std::input_iterator_tag;
|
|
using difference_type = std::ptrdiff_t;
|
|
using value_type = T*;
|
|
using pointer = T*;
|
|
using reference = T*;
|
|
Iterator() = default;
|
|
Iterator(const T* node, size_t childIndex)
|
|
: node_(node), childIndex_(childIndex) {}
|
|
T* operator*() const {
|
|
return node_->getChild(childIndex_);
|
|
}
|
|
Iterator& operator++() {
|
|
next();
|
|
return *this;
|
|
}
|
|
Iterator operator++(int) {
|
|
Iterator tmp = *this;
|
|
++(*this);
|
|
return tmp;
|
|
}
|
|
friend bool operator==(const Iterator& a, const Iterator& b) {
|
|
return a.node_ == b.node_ && a.childIndex_ == b.childIndex_;
|
|
}
|
|
friend bool operator!=(const Iterator& a, const Iterator& b) {
|
|
return a.node_ != b.node_ || a.childIndex_ != b.childIndex_;
|
|
}
|
|
|
|
private:
|
|
void next() {
|
|
if (childIndex_ + 1 >= node_->getChildCount()) {
|
|
if (backtrack_.empty()) [[likely]] {
|
|
*this = Iterator{};
|
|
} else {
|
|
const auto& back = backtrack_.front();
|
|
node_ = back.first;
|
|
childIndex_ = back.second;
|
|
backtrack_.pop_front();
|
|
next();
|
|
}
|
|
} else {
|
|
++childIndex_;
|
|
if (node_->getChild(childIndex_)->style().display() ==
|
|
Display::Contents) [[unlikely]] {
|
|
skipContentsNodes();
|
|
}
|
|
}
|
|
}
|
|
void skipContentsNodes() {
|
|
auto currentNode = node_->getChild(childIndex_);
|
|
while (currentNode->style().display() == Display::Contents &&
|
|
currentNode->getChildCount() > 0) {
|
|
backtrack_.push_front({node_, childIndex_});
|
|
node_ = currentNode;
|
|
childIndex_ = 0;
|
|
currentNode = currentNode->getChild(childIndex_);
|
|
}
|
|
if (currentNode->style().display() == Display::Contents) {
|
|
next();
|
|
}
|
|
}
|
|
const T* node_{nullptr};
|
|
size_t childIndex_{0};
|
|
std::forward_list<std::pair<const T*, size_t>> backtrack_;
|
|
friend LayoutableChildren;
|
|
};
|
|
explicit LayoutableChildren(const T* node) : node_(node) {
|
|
static_assert(std::input_iterator<LayoutableChildren<T>::Iterator>);
|
|
static_assert(
|
|
std::is_base_of<Node, T>::value,
|
|
"Type parameter of LayoutableChildren must derive from yoga::Node");
|
|
}
|
|
Iterator begin() const {
|
|
if (node_->getChildCount() > 0) {
|
|
auto result = Iterator(node_, 0);
|
|
if (node_->getChild(0)->style().display() == Display::Contents)
|
|
[[unlikely]] {
|
|
result.skipContentsNodes();
|
|
}
|
|
return result;
|
|
} else {
|
|
return Iterator{};
|
|
}
|
|
}
|
|
Iterator end() const {
|
|
return Iterator{};
|
|
}
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/node/Node.h}:
|
|
struct YGNode {};
|
|
namespace facebook::yoga {
|
|
class YG_EXPORT Node : public ::YGNode {
|
|
public:
|
|
using LayoutableChildren = yoga::LayoutableChildren<Node>;
|
|
Node();
|
|
explicit Node(const Config* config);
|
|
Node(Node&& node) noexcept;
|
|
Node(const Node& node) = default;
|
|
Node& operator=(const Node&) = delete;
|
|
void* getContext() const {
|
|
return context_;
|
|
}
|
|
bool alwaysFormsContainingBlock() const {
|
|
return alwaysFormsContainingBlock_;
|
|
}
|
|
bool getHasNewLayout() const {
|
|
return hasNewLayout_;
|
|
}
|
|
NodeType getNodeType() const {
|
|
return nodeType_;
|
|
}
|
|
bool hasMeasureFunc() const noexcept {
|
|
return measureFunc_ != nullptr;
|
|
}
|
|
YGSize measure(
|
|
float availableWidth,
|
|
MeasureMode widthMode,
|
|
float availableHeight,
|
|
MeasureMode heightMode);
|
|
bool hasBaselineFunc() const noexcept {
|
|
return baselineFunc_ != nullptr;
|
|
}
|
|
float baseline(float width, float height) const;
|
|
float dimensionWithMargin(FlexDirection axis, float widthSize);
|
|
bool isLayoutDimensionDefined(FlexDirection axis);
|
|
inline bool hasDefiniteLength(Dimension dimension, float ownerSize) {
|
|
auto usedValue = getProcessedDimension(dimension).resolve(ownerSize);
|
|
return usedValue.isDefined() && usedValue.unwrap() >= 0.0f;
|
|
}
|
|
bool hasErrata(Errata errata) const {
|
|
return config_->hasErrata(errata);
|
|
}
|
|
bool hasContentsChildren() const {
|
|
return contentsChildrenCount_ != 0;
|
|
}
|
|
YGDirtiedFunc getDirtiedFunc() const {
|
|
return dirtiedFunc_;
|
|
}
|
|
Style& style() {
|
|
return style_;
|
|
}
|
|
const Style& style() const {
|
|
return style_;
|
|
}
|
|
LayoutResults& getLayout() {
|
|
return layout_;
|
|
}
|
|
const LayoutResults& getLayout() const {
|
|
return layout_;
|
|
}
|
|
size_t getLineIndex() const {
|
|
return lineIndex_;
|
|
}
|
|
bool isReferenceBaseline() const {
|
|
return isReferenceBaseline_;
|
|
}
|
|
Node* getOwner() const {
|
|
return owner_;
|
|
}
|
|
const std::vector<Node*>& getChildren() const {
|
|
return children_;
|
|
}
|
|
Node* getChild(size_t index) const {
|
|
return children_.at(index);
|
|
}
|
|
size_t getChildCount() const {
|
|
return children_.size();
|
|
}
|
|
LayoutableChildren getLayoutChildren() const {
|
|
return LayoutableChildren(this);
|
|
}
|
|
size_t getLayoutChildCount() const {
|
|
if (contentsChildrenCount_ == 0) {
|
|
return children_.size();
|
|
} else {
|
|
size_t count = 0;
|
|
for (auto iter = getLayoutChildren().begin();
|
|
iter != getLayoutChildren().end();
|
|
iter++) {
|
|
count++;
|
|
}
|
|
return count;
|
|
}
|
|
}
|
|
const Config* getConfig() const {
|
|
return config_;
|
|
}
|
|
bool isDirty() const {
|
|
return isDirty_;
|
|
}
|
|
Style::SizeLength getProcessedDimension(Dimension dimension) const {
|
|
return processedDimensions_[static_cast<size_t>(dimension)];
|
|
}
|
|
FloatOptional getResolvedDimension(
|
|
Direction direction,
|
|
Dimension dimension,
|
|
float referenceLength,
|
|
float ownerWidth) const {
|
|
FloatOptional value =
|
|
getProcessedDimension(dimension).resolve(referenceLength);
|
|
if (style_.boxSizing() == BoxSizing::BorderBox) {
|
|
return value;
|
|
}
|
|
FloatOptional dimensionPaddingAndBorder =
|
|
FloatOptional{style_.computePaddingAndBorderForDimension(
|
|
direction, dimension, ownerWidth)};
|
|
return value +
|
|
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
|
|
: FloatOptional{0.0});
|
|
}
|
|
void setContext(void* context) {
|
|
context_ = context;
|
|
}
|
|
void setAlwaysFormsContainingBlock(bool alwaysFormsContainingBlock) {
|
|
alwaysFormsContainingBlock_ = alwaysFormsContainingBlock;
|
|
}
|
|
void setHasNewLayout(bool hasNewLayout) {
|
|
hasNewLayout_ = hasNewLayout;
|
|
}
|
|
void setNodeType(NodeType nodeType) {
|
|
nodeType_ = nodeType;
|
|
}
|
|
void setMeasureFunc(YGMeasureFunc measureFunc);
|
|
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
|
|
baselineFunc_ = baseLineFunc;
|
|
}
|
|
void setDirtiedFunc(YGDirtiedFunc dirtiedFunc) {
|
|
dirtiedFunc_ = dirtiedFunc;
|
|
}
|
|
void setStyle(const Style& style) {
|
|
style_ = style;
|
|
}
|
|
void setLayout(const LayoutResults& layout) {
|
|
layout_ = layout;
|
|
}
|
|
void setLineIndex(size_t lineIndex) {
|
|
lineIndex_ = lineIndex;
|
|
}
|
|
void setIsReferenceBaseline(bool isReferenceBaseline) {
|
|
isReferenceBaseline_ = isReferenceBaseline;
|
|
}
|
|
void setOwner(Node* owner) {
|
|
owner_ = owner;
|
|
}
|
|
void setConfig(Config* config);
|
|
void setDirty(bool isDirty);
|
|
void setChildren(const std::vector<Node*>& children);
|
|
void setLayoutLastOwnerDirection(Direction direction);
|
|
void setLayoutComputedFlexBasis(FloatOptional computedFlexBasis);
|
|
void setLayoutComputedFlexBasisGeneration(
|
|
uint32_t computedFlexBasisGeneration);
|
|
void setLayoutMeasuredDimension(float measuredDimension, Dimension dimension);
|
|
void setLayoutHadOverflow(bool hadOverflow);
|
|
void setLayoutDimension(float lengthValue, Dimension dimension);
|
|
void setLayoutDirection(Direction direction);
|
|
void setLayoutMargin(float margin, PhysicalEdge edge);
|
|
void setLayoutBorder(float border, PhysicalEdge edge);
|
|
void setLayoutPadding(float padding, PhysicalEdge edge);
|
|
void setLayoutPosition(float position, PhysicalEdge edge);
|
|
void setPosition(Direction direction, float ownerWidth, float ownerHeight);
|
|
Style::SizeLength processFlexBasis() const;
|
|
FloatOptional resolveFlexBasis(
|
|
Direction direction,
|
|
FlexDirection flexDirection,
|
|
float referenceLength,
|
|
float ownerWidth) const;
|
|
void processDimensions();
|
|
Direction resolveDirection(Direction ownerDirection);
|
|
void clearChildren();
|
|
void replaceChild(Node* oldChild, Node* newChild);
|
|
void replaceChild(Node* child, size_t index);
|
|
void insertChild(Node* child, size_t index);
|
|
bool removeChild(Node* child);
|
|
void removeChild(size_t index);
|
|
void cloneChildrenIfNeeded();
|
|
void cloneContentsChildrenIfNeeded();
|
|
void markDirtyAndPropagate();
|
|
float resolveFlexGrow() const;
|
|
float resolveFlexShrink() const;
|
|
bool isNodeFlexible();
|
|
void reset();
|
|
};
|
|
};
|
|
inline Node* resolveRef(const YGNodeRef ref) {
|
|
return static_cast<Node*>(ref);
|
|
}
|
|
inline const Node* resolveRef(const YGNodeConstRef ref) {
|
|
return static_cast<const Node*>(ref);
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/numeric/Comparison.h}:
|
|
namespace facebook::yoga {
|
|
constexpr bool isUndefined(std::floating_point auto value) {
|
|
return value != value;
|
|
}
|
|
constexpr bool isDefined(std::floating_point auto value) {
|
|
return !isUndefined(value);
|
|
}
|
|
constexpr bool isinf(auto value) {
|
|
return value == +std::numeric_limits<decltype(value)>::infinity() ||
|
|
value == -std::numeric_limits<decltype(value)>::infinity();
|
|
}
|
|
constexpr auto maxOrDefined(
|
|
std::floating_point auto a,
|
|
std::floating_point auto b) {
|
|
if (yoga::isDefined(a) && yoga::isDefined(b)) {
|
|
return std::max(a, b);
|
|
}
|
|
return yoga::isUndefined(a) ? b : a;
|
|
}
|
|
constexpr auto minOrDefined(
|
|
std::floating_point auto a,
|
|
std::floating_point auto b) {
|
|
if (yoga::isDefined(a) && yoga::isDefined(b)) {
|
|
return std::min(a, b);
|
|
}
|
|
return yoga::isUndefined(a) ? b : a;
|
|
}
|
|
inline bool inexactEquals(float a, float b) {
|
|
if (yoga::isDefined(a) && yoga::isDefined(b)) {
|
|
return std::abs(a - b) < 0.0001f;
|
|
}
|
|
return yoga::isUndefined(a) && yoga::isUndefined(b);
|
|
}
|
|
inline bool inexactEquals(double a, double b) {
|
|
if (yoga::isDefined(a) && yoga::isDefined(b)) {
|
|
return std::abs(a - b) < 0.0001;
|
|
}
|
|
return yoga::isUndefined(a) && yoga::isUndefined(b);
|
|
}
|
|
template <std::size_t Size, typename ElementT>
|
|
bool inexactEquals(
|
|
const std::array<ElementT, Size>& val1,
|
|
const std::array<ElementT, Size>& val2) {
|
|
bool areEqual = true;
|
|
for (std::size_t i = 0; i < Size && areEqual; ++i) {
|
|
areEqual = inexactEquals(val1[i], val2[i]);
|
|
}
|
|
return areEqual;
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/numeric/FloatOptional.h}:
|
|
namespace facebook::yoga {
|
|
struct FloatOptional { public:
|
|
explicit constexpr FloatOptional(float value) : value_(value) {}
|
|
constexpr FloatOptional() = default;
|
|
constexpr float unwrap() const {
|
|
return value_;
|
|
}
|
|
constexpr float unwrapOrDefault(float defaultValue) const {
|
|
return isUndefined() ? defaultValue : value_;
|
|
}
|
|
constexpr bool isUndefined() const {
|
|
return yoga::isUndefined(value_);
|
|
}
|
|
constexpr bool isDefined() const {
|
|
return yoga::isDefined(value_);
|
|
}
|
|
};
|
|
constexpr bool operator==(FloatOptional lhs, FloatOptional rhs) {
|
|
return lhs.unwrap() == rhs.unwrap() ||
|
|
(lhs.isUndefined() && rhs.isUndefined());
|
|
}
|
|
constexpr bool operator!=(FloatOptional lhs, FloatOptional rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
constexpr bool operator==(FloatOptional lhs, float rhs) {
|
|
return lhs == FloatOptional{rhs};
|
|
}
|
|
constexpr bool operator!=(FloatOptional lhs, float rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
constexpr bool operator==(float lhs, FloatOptional rhs) {
|
|
return rhs == lhs;
|
|
}
|
|
constexpr bool operator!=(float lhs, FloatOptional rhs) {
|
|
return !(lhs == rhs);
|
|
}
|
|
constexpr FloatOptional operator+(FloatOptional lhs, FloatOptional rhs) {
|
|
return FloatOptional{lhs.unwrap() + rhs.unwrap()};
|
|
}
|
|
constexpr bool operator>(FloatOptional lhs, FloatOptional rhs) {
|
|
return lhs.unwrap() > rhs.unwrap();
|
|
}
|
|
constexpr bool operator<(FloatOptional lhs, FloatOptional rhs) {
|
|
return lhs.unwrap() < rhs.unwrap();
|
|
}
|
|
constexpr bool operator>=(FloatOptional lhs, FloatOptional rhs) {
|
|
return lhs > rhs || lhs == rhs;
|
|
}
|
|
constexpr bool operator<=(FloatOptional lhs, FloatOptional rhs) {
|
|
return lhs < rhs || lhs == rhs;
|
|
}
|
|
constexpr FloatOptional maxOrDefined(FloatOptional lhs, FloatOptional rhs) {
|
|
return FloatOptional{yoga::maxOrDefined(lhs.unwrap(), rhs.unwrap())};
|
|
}
|
|
inline bool inexactEquals(FloatOptional lhs, FloatOptional rhs) {
|
|
return yoga::inexactEquals(lhs.unwrap(), rhs.unwrap());
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/style/SmallValueBuffer.h}:
|
|
namespace facebook::yoga {
|
|
template <size_t BufferSize>
|
|
class SmallValueBuffer {
|
|
public:
|
|
SmallValueBuffer() = default;
|
|
SmallValueBuffer(const SmallValueBuffer& other) {
|
|
*this = other;
|
|
}
|
|
SmallValueBuffer(SmallValueBuffer&& other) noexcept = default;
|
|
uint16_t push(uint32_t value) {
|
|
const auto index = count_++;
|
|
assert(index < 4096 && "SmallValueBuffer can only hold up to 4096 chunks");
|
|
if (index < buffer_.size()) {
|
|
buffer_[index] = value;
|
|
return index;
|
|
}
|
|
if (overflow_ == nullptr) {
|
|
overflow_ = std::make_unique<SmallValueBuffer::Overflow>();
|
|
}
|
|
overflow_->buffer_.push_back(value);
|
|
overflow_->wideElements_.push_back(false);
|
|
return index;
|
|
}
|
|
uint16_t push(uint64_t value) {
|
|
const auto lsb = static_cast<uint32_t>(value & 0xFFFFFFFF);
|
|
const auto msb = static_cast<uint32_t>(value >> 32);
|
|
const auto lsbIndex = push(lsb);
|
|
[[maybe_unused]] const auto msbIndex = push(msb);
|
|
assert(
|
|
msbIndex < 4096 && "SmallValueBuffer can only hold up to 4096 chunks");
|
|
if (lsbIndex < buffer_.size()) {
|
|
wideElements_[lsbIndex] = true;
|
|
} else {
|
|
overflow_->wideElements_[lsbIndex - buffer_.size()] = true;
|
|
}
|
|
return lsbIndex;
|
|
}
|
|
[[nodiscard]] uint16_t replace(uint16_t index, uint32_t value) {
|
|
if (index < buffer_.size()) {
|
|
buffer_[index] = value;
|
|
} else {
|
|
overflow_->buffer_.at(index - buffer_.size()) = value;
|
|
}
|
|
return index;
|
|
}
|
|
[[nodiscard]] uint16_t replace(uint16_t index, uint64_t value) {
|
|
const bool isWide = index < wideElements_.size()
|
|
? wideElements_[index]
|
|
: overflow_->wideElements_.at(index - buffer_.size());
|
|
if (isWide) {
|
|
const auto lsb = static_cast<uint32_t>(value & 0xFFFFFFFF);
|
|
const auto msb = static_cast<uint32_t>(value >> 32);
|
|
[[maybe_unused]] auto lsbIndex = replace(index, lsb);
|
|
[[maybe_unused]] auto msbIndex = replace(index + 1, msb);
|
|
return index;
|
|
} else {
|
|
return push(value);
|
|
}
|
|
}
|
|
uint32_t get32(uint16_t index) const {
|
|
if (index < buffer_.size()) {
|
|
return buffer_[index];
|
|
} else {
|
|
return overflow_->buffer_.at(index - buffer_.size());
|
|
}
|
|
}
|
|
uint64_t get64(uint16_t index) const {
|
|
const auto lsb = get32(index);
|
|
const auto msb = get32(index + 1);
|
|
return (static_cast<uint64_t>(msb) << 32) | lsb;
|
|
}
|
|
SmallValueBuffer& operator=(const SmallValueBuffer& other) {
|
|
count_ = other.count_;
|
|
buffer_ = other.buffer_;
|
|
wideElements_ = other.wideElements_;
|
|
overflow_ = other.overflow_ ? std::make_unique<Overflow>(*other.overflow_)
|
|
: nullptr;
|
|
return *this;
|
|
}
|
|
SmallValueBuffer& operator=(SmallValueBuffer&& other) noexcept = default;
|
|
};
|
|
uint16_t count_{0};
|
|
std::array<uint32_t, BufferSize> buffer_{};
|
|
std::bitset<BufferSize> wideElements_;
|
|
std::unique_ptr<Overflow> overflow_;
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/style/Style.h}:
|
|
namespace facebook::yoga {
|
|
class YG_EXPORT Style {
|
|
public:
|
|
using Length = StyleLength;
|
|
using SizeLength = StyleSizeLength;
|
|
static constexpr float DefaultFlexGrow = 0.0f;
|
|
static constexpr float DefaultFlexShrink = 0.0f;
|
|
static constexpr float WebDefaultFlexShrink = 1.0f;
|
|
Direction direction() const {
|
|
return direction_;
|
|
}
|
|
void setDirection(Direction value) {
|
|
direction_ = value;
|
|
}
|
|
FlexDirection flexDirection() const {
|
|
return flexDirection_;
|
|
}
|
|
void setFlexDirection(FlexDirection value) {
|
|
flexDirection_ = value;
|
|
}
|
|
Justify justifyContent() const {
|
|
return justifyContent_;
|
|
}
|
|
void setJustifyContent(Justify value) {
|
|
justifyContent_ = value;
|
|
}
|
|
Align alignContent() const {
|
|
return alignContent_;
|
|
}
|
|
void setAlignContent(Align value) {
|
|
alignContent_ = value;
|
|
}
|
|
Align alignItems() const {
|
|
return alignItems_;
|
|
}
|
|
void setAlignItems(Align value) {
|
|
alignItems_ = value;
|
|
}
|
|
Align alignSelf() const {
|
|
return alignSelf_;
|
|
}
|
|
void setAlignSelf(Align value) {
|
|
alignSelf_ = value;
|
|
}
|
|
PositionType positionType() const {
|
|
return positionType_;
|
|
}
|
|
void setPositionType(PositionType value) {
|
|
positionType_ = value;
|
|
}
|
|
Wrap flexWrap() const {
|
|
return flexWrap_;
|
|
}
|
|
void setFlexWrap(Wrap value) {
|
|
flexWrap_ = value;
|
|
}
|
|
Overflow overflow() const {
|
|
return overflow_;
|
|
}
|
|
void setOverflow(Overflow value) {
|
|
overflow_ = value;
|
|
}
|
|
Display display() const {
|
|
return display_;
|
|
}
|
|
void setDisplay(Display value) {
|
|
display_ = value;
|
|
}
|
|
FloatOptional flex() const {
|
|
return pool_.getNumber(flex_);
|
|
}
|
|
void setFlex(FloatOptional value) {
|
|
pool_.store(flex_, value);
|
|
}
|
|
FloatOptional flexGrow() const {
|
|
return pool_.getNumber(flexGrow_);
|
|
}
|
|
void setFlexGrow(FloatOptional value) {
|
|
pool_.store(flexGrow_, value);
|
|
}
|
|
FloatOptional flexShrink() const {
|
|
return pool_.getNumber(flexShrink_);
|
|
}
|
|
void setFlexShrink(FloatOptional value) {
|
|
pool_.store(flexShrink_, value);
|
|
}
|
|
Style::SizeLength flexBasis() const {
|
|
return pool_.getSize(flexBasis_);
|
|
}
|
|
void setFlexBasis(Style::SizeLength value) {
|
|
pool_.store(flexBasis_, value);
|
|
}
|
|
Style::Length margin(Edge edge) const {
|
|
return pool_.getLength(margin_[yoga::to_underlying(edge)]);
|
|
}
|
|
void setMargin(Edge edge, Style::Length value) {
|
|
pool_.store(margin_[yoga::to_underlying(edge)], value);
|
|
}
|
|
Style::Length position(Edge edge) const {
|
|
return pool_.getLength(position_[yoga::to_underlying(edge)]);
|
|
}
|
|
void setPosition(Edge edge, Style::Length value) {
|
|
pool_.store(position_[yoga::to_underlying(edge)], value);
|
|
}
|
|
Style::Length padding(Edge edge) const {
|
|
return pool_.getLength(padding_[yoga::to_underlying(edge)]);
|
|
}
|
|
void setPadding(Edge edge, Style::Length value) {
|
|
pool_.store(padding_[yoga::to_underlying(edge)], value);
|
|
}
|
|
Style::Length border(Edge edge) const {
|
|
return pool_.getLength(border_[yoga::to_underlying(edge)]);
|
|
}
|
|
void setBorder(Edge edge, Style::Length value) {
|
|
pool_.store(border_[yoga::to_underlying(edge)], value);
|
|
}
|
|
Style::Length gap(Gutter gutter) const {
|
|
return pool_.getLength(gap_[yoga::to_underlying(gutter)]);
|
|
}
|
|
void setGap(Gutter gutter, Style::Length value) {
|
|
pool_.store(gap_[yoga::to_underlying(gutter)], value);
|
|
}
|
|
Style::SizeLength dimension(Dimension axis) const {
|
|
return pool_.getSize(dimensions_[yoga::to_underlying(axis)]);
|
|
}
|
|
void setDimension(Dimension axis, Style::SizeLength value) {
|
|
pool_.store(dimensions_[yoga::to_underlying(axis)], value);
|
|
}
|
|
Style::SizeLength minDimension(Dimension axis) const {
|
|
return pool_.getSize(minDimensions_[yoga::to_underlying(axis)]);
|
|
}
|
|
void setMinDimension(Dimension axis, Style::SizeLength value) {
|
|
pool_.store(minDimensions_[yoga::to_underlying(axis)], value);
|
|
}
|
|
FloatOptional resolvedMinDimension(
|
|
Direction direction,
|
|
Dimension axis,
|
|
float referenceLength,
|
|
float ownerWidth) const {
|
|
FloatOptional value = minDimension(axis).resolve(referenceLength);
|
|
if (boxSizing() == BoxSizing::BorderBox) {
|
|
return value;
|
|
}
|
|
FloatOptional dimensionPaddingAndBorder = FloatOptional{
|
|
computePaddingAndBorderForDimension(direction, axis, ownerWidth)};
|
|
return value +
|
|
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
|
|
: FloatOptional{0.0});
|
|
}
|
|
Style::SizeLength maxDimension(Dimension axis) const {
|
|
return pool_.getSize(maxDimensions_[yoga::to_underlying(axis)]);
|
|
}
|
|
void setMaxDimension(Dimension axis, Style::SizeLength value) {
|
|
pool_.store(maxDimensions_[yoga::to_underlying(axis)], value);
|
|
}
|
|
FloatOptional resolvedMaxDimension(
|
|
Direction direction,
|
|
Dimension axis,
|
|
float referenceLength,
|
|
float ownerWidth) const {
|
|
FloatOptional value = maxDimension(axis).resolve(referenceLength);
|
|
if (boxSizing() == BoxSizing::BorderBox) {
|
|
return value;
|
|
}
|
|
FloatOptional dimensionPaddingAndBorder = FloatOptional{
|
|
computePaddingAndBorderForDimension(direction, axis, ownerWidth)};
|
|
return value +
|
|
(dimensionPaddingAndBorder.isDefined() ? dimensionPaddingAndBorder
|
|
: FloatOptional{0.0});
|
|
}
|
|
FloatOptional aspectRatio() const {
|
|
return pool_.getNumber(aspectRatio_);
|
|
}
|
|
void setAspectRatio(FloatOptional value) {
|
|
pool_.store(
|
|
aspectRatio_,
|
|
value == 0.0f || std::isinf(value.unwrap()) ? FloatOptional{} : value);
|
|
}
|
|
BoxSizing boxSizing() const {
|
|
return boxSizing_;
|
|
}
|
|
void setBoxSizing(BoxSizing value) {
|
|
boxSizing_ = value;
|
|
}
|
|
bool horizontalInsetsDefined() const {
|
|
return position_[yoga::to_underlying(Edge::Left)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::Right)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::All)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::Horizontal)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::Start)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::End)].isDefined();
|
|
}
|
|
bool verticalInsetsDefined() const {
|
|
return position_[yoga::to_underlying(Edge::Top)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::Bottom)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::All)].isDefined() ||
|
|
position_[yoga::to_underlying(Edge::Vertical)].isDefined();
|
|
}
|
|
bool isFlexStartPositionDefined(FlexDirection axis, Direction direction)
|
|
const {
|
|
return computePosition(flexStartEdge(axis), direction).isDefined();
|
|
}
|
|
bool isFlexStartPositionAuto(FlexDirection axis, Direction direction) const {
|
|
return computePosition(flexStartEdge(axis), direction).isAuto();
|
|
}
|
|
bool isInlineStartPositionDefined(FlexDirection axis, Direction direction)
|
|
const {
|
|
return computePosition(inlineStartEdge(axis, direction), direction)
|
|
.isDefined();
|
|
}
|
|
bool isInlineStartPositionAuto(FlexDirection axis, Direction direction)
|
|
const {
|
|
return computePosition(inlineStartEdge(axis, direction), direction)
|
|
.isAuto();
|
|
}
|
|
bool isFlexEndPositionDefined(FlexDirection axis, Direction direction) const {
|
|
return computePosition(flexEndEdge(axis), direction).isDefined();
|
|
}
|
|
bool isFlexEndPositionAuto(FlexDirection axis, Direction direction) const {
|
|
return computePosition(flexEndEdge(axis), direction).isAuto();
|
|
}
|
|
bool isInlineEndPositionDefined(FlexDirection axis, Direction direction)
|
|
const {
|
|
return computePosition(inlineEndEdge(axis, direction), direction)
|
|
.isDefined();
|
|
}
|
|
bool isInlineEndPositionAuto(FlexDirection axis, Direction direction) const {
|
|
return computePosition(inlineEndEdge(axis, direction), direction).isAuto();
|
|
}
|
|
float computeFlexStartPosition(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float axisSize) const {
|
|
return computePosition(flexStartEdge(axis), direction)
|
|
.resolve(axisSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeInlineStartPosition(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float axisSize) const {
|
|
return computePosition(inlineStartEdge(axis, direction), direction)
|
|
.resolve(axisSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeFlexEndPosition(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float axisSize) const {
|
|
return computePosition(flexEndEdge(axis), direction)
|
|
.resolve(axisSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeInlineEndPosition(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float axisSize) const {
|
|
return computePosition(inlineEndEdge(axis, direction), direction)
|
|
.resolve(axisSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeFlexStartMargin(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeMargin(flexStartEdge(axis), direction)
|
|
.resolve(widthSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeInlineStartMargin(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeMargin(inlineStartEdge(axis, direction), direction)
|
|
.resolve(widthSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeFlexEndMargin(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeMargin(flexEndEdge(axis), direction)
|
|
.resolve(widthSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeInlineEndMargin(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeMargin(inlineEndEdge(axis, direction), direction)
|
|
.resolve(widthSize)
|
|
.unwrapOrDefault(0.0f);
|
|
}
|
|
float computeFlexStartBorder(FlexDirection axis, Direction direction) const {
|
|
return maxOrDefined(
|
|
computeBorder(flexStartEdge(axis), direction).resolve(0.0f).unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeInlineStartBorder(FlexDirection axis, Direction direction)
|
|
const {
|
|
return maxOrDefined(
|
|
computeBorder(inlineStartEdge(axis, direction), direction)
|
|
.resolve(0.0f)
|
|
.unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeFlexEndBorder(FlexDirection axis, Direction direction) const {
|
|
return maxOrDefined(
|
|
computeBorder(flexEndEdge(axis), direction).resolve(0.0f).unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeInlineEndBorder(FlexDirection axis, Direction direction) const {
|
|
return maxOrDefined(
|
|
computeBorder(inlineEndEdge(axis, direction), direction)
|
|
.resolve(0.0f)
|
|
.unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeFlexStartPadding(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return maxOrDefined(
|
|
computePadding(flexStartEdge(axis), direction)
|
|
.resolve(widthSize)
|
|
.unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeInlineStartPadding(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return maxOrDefined(
|
|
computePadding(inlineStartEdge(axis, direction), direction)
|
|
.resolve(widthSize)
|
|
.unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeFlexEndPadding(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return maxOrDefined(
|
|
computePadding(flexEndEdge(axis), direction)
|
|
.resolve(widthSize)
|
|
.unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeInlineEndPadding(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return maxOrDefined(
|
|
computePadding(inlineEndEdge(axis, direction), direction)
|
|
.resolve(widthSize)
|
|
.unwrap(),
|
|
0.0f);
|
|
}
|
|
float computeInlineStartPaddingAndBorder(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeInlineStartPadding(axis, direction, widthSize) +
|
|
computeInlineStartBorder(axis, direction);
|
|
}
|
|
float computeFlexStartPaddingAndBorder(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeFlexStartPadding(axis, direction, widthSize) +
|
|
computeFlexStartBorder(axis, direction);
|
|
}
|
|
float computeInlineEndPaddingAndBorder(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeInlineEndPadding(axis, direction, widthSize) +
|
|
computeInlineEndBorder(axis, direction);
|
|
}
|
|
float computeFlexEndPaddingAndBorder(
|
|
FlexDirection axis,
|
|
Direction direction,
|
|
float widthSize) const {
|
|
return computeFlexEndPadding(axis, direction, widthSize) +
|
|
computeFlexEndBorder(axis, direction);
|
|
}
|
|
float computePaddingAndBorderForDimension(
|
|
Direction direction,
|
|
Dimension dimension,
|
|
float widthSize) const {
|
|
FlexDirection flexDirectionForDimension = dimension == Dimension::Width
|
|
? FlexDirection::Row
|
|
: FlexDirection::Column;
|
|
return computeFlexStartPaddingAndBorder(
|
|
flexDirectionForDimension, direction, widthSize) +
|
|
computeFlexEndPaddingAndBorder(
|
|
flexDirectionForDimension, direction, widthSize);
|
|
}
|
|
float computeBorderForAxis(FlexDirection axis) const {
|
|
return computeInlineStartBorder(axis, Direction::LTR) +
|
|
computeInlineEndBorder(axis, Direction::LTR);
|
|
}
|
|
float computeMarginForAxis(FlexDirection axis, float widthSize) const {
|
|
return computeInlineStartMargin(axis, Direction::LTR, widthSize) +
|
|
computeInlineEndMargin(axis, Direction::LTR, widthSize);
|
|
}
|
|
float computeGapForAxis(FlexDirection axis, float ownerSize) const {
|
|
auto gap = isRow(axis) ? computeColumnGap() : computeRowGap();
|
|
return maxOrDefined(gap.resolve(ownerSize).unwrap(), 0.0f);
|
|
}
|
|
bool flexStartMarginIsAuto(FlexDirection axis, Direction direction) const {
|
|
return computeMargin(flexStartEdge(axis), direction).isAuto();
|
|
}
|
|
bool flexEndMarginIsAuto(FlexDirection axis, Direction direction) const {
|
|
return computeMargin(flexEndEdge(axis), direction).isAuto();
|
|
}
|
|
bool operator==(const Style& other) const {
|
|
return direction_ == other.direction_ &&
|
|
flexDirection_ == other.flexDirection_ &&
|
|
justifyContent_ == other.justifyContent_ &&
|
|
alignContent_ == other.alignContent_ &&
|
|
alignItems_ == other.alignItems_ && alignSelf_ == other.alignSelf_ &&
|
|
positionType_ == other.positionType_ && flexWrap_ == other.flexWrap_ &&
|
|
overflow_ == other.overflow_ && display_ == other.display_ &&
|
|
numbersEqual(flex_, pool_, other.flex_, other.pool_) &&
|
|
numbersEqual(flexGrow_, pool_, other.flexGrow_, other.pool_) &&
|
|
numbersEqual(flexShrink_, pool_, other.flexShrink_, other.pool_) &&
|
|
lengthsEqual(flexBasis_, pool_, other.flexBasis_, other.pool_) &&
|
|
lengthsEqual(margin_, pool_, other.margin_, other.pool_) &&
|
|
lengthsEqual(position_, pool_, other.position_, other.pool_) &&
|
|
lengthsEqual(padding_, pool_, other.padding_, other.pool_) &&
|
|
lengthsEqual(border_, pool_, other.border_, other.pool_) &&
|
|
lengthsEqual(gap_, pool_, other.gap_, other.pool_) &&
|
|
lengthsEqual(dimensions_, pool_, other.dimensions_, other.pool_) &&
|
|
lengthsEqual(
|
|
minDimensions_, pool_, other.minDimensions_, other.pool_) &&
|
|
lengthsEqual(
|
|
maxDimensions_, pool_, other.maxDimensions_, other.pool_) &&
|
|
numbersEqual(aspectRatio_, pool_, other.aspectRatio_, other.pool_);
|
|
}
|
|
bool operator!=(const Style& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
StyleValueHandle flexGrow_{};
|
|
StyleValueHandle flexShrink_{};
|
|
StyleValueHandle flexBasis_{StyleValueHandle::ofAuto()};
|
|
Edges margin_{};
|
|
Edges position_{};
|
|
Edges padding_{};
|
|
Edges border_{};
|
|
Gutters gap_{};
|
|
Dimensions dimensions_{
|
|
StyleValueHandle::ofAuto(),
|
|
StyleValueHandle::ofAuto()};
|
|
Dimensions minDimensions_{};
|
|
Dimensions maxDimensions_{};
|
|
StyleValueHandle aspectRatio_{};
|
|
StyleValuePool pool_;
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/style/StyleLength.h}:
|
|
namespace facebook::yoga {
|
|
class StyleLength {
|
|
public:
|
|
constexpr StyleLength() = default;
|
|
constexpr static StyleLength points(float value) {
|
|
return yoga::isUndefined(value) || yoga::isinf(value)
|
|
? undefined()
|
|
: StyleLength{FloatOptional{value}, Unit::Point};
|
|
}
|
|
constexpr static StyleLength percent(float value) {
|
|
return yoga::isUndefined(value) || yoga::isinf(value)
|
|
? undefined()
|
|
: StyleLength{FloatOptional{value}, Unit::Percent};
|
|
}
|
|
constexpr static StyleLength ofAuto() {
|
|
return StyleLength{{}, Unit::Auto};
|
|
}
|
|
constexpr static StyleLength undefined() {
|
|
return StyleLength{{}, Unit::Undefined};
|
|
}
|
|
constexpr bool isAuto() const {
|
|
return unit_ == Unit::Auto;
|
|
}
|
|
constexpr bool isUndefined() const {
|
|
return unit_ == Unit::Undefined;
|
|
}
|
|
constexpr bool isPoints() const {
|
|
return unit_ == Unit::Point;
|
|
}
|
|
constexpr bool isPercent() const {
|
|
return unit_ == Unit::Percent;
|
|
}
|
|
constexpr bool isDefined() const {
|
|
return !isUndefined();
|
|
}
|
|
constexpr FloatOptional value() const {
|
|
return value_;
|
|
}
|
|
constexpr FloatOptional resolve(float referenceLength) {
|
|
switch (unit_) {
|
|
case Unit::Point:
|
|
return value_;
|
|
case Unit::Percent:
|
|
return FloatOptional{value_.unwrap() * referenceLength * 0.01f};
|
|
default:
|
|
return FloatOptional{};
|
|
}
|
|
}
|
|
explicit constexpr operator YGValue() const {
|
|
return YGValue{value_.unwrap(), unscopedEnum(unit_)};
|
|
}
|
|
constexpr bool operator==(const StyleLength& rhs) const {
|
|
return value_ == rhs.value_ && unit_ == rhs.unit_;
|
|
}
|
|
constexpr bool inexactEquals(const StyleLength& other) const {
|
|
return unit_ == other.unit_ &&
|
|
facebook::yoga::inexactEquals(value_, other.value_);
|
|
}
|
|
};
|
|
Unit unit_{Unit::Undefined};
|
|
};
|
|
inline bool inexactEquals(const StyleLength& a, const StyleLength& b) {
|
|
return a.inexactEquals(b);
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/style/StyleSizeLength.h}:
|
|
namespace facebook::yoga {
|
|
class StyleSizeLength {
|
|
public:
|
|
constexpr StyleSizeLength() = default;
|
|
constexpr static StyleSizeLength points(float value) {
|
|
return yoga::isUndefined(value) || yoga::isinf(value)
|
|
? undefined()
|
|
: StyleSizeLength{FloatOptional{value}, Unit::Point};
|
|
}
|
|
constexpr static StyleSizeLength percent(float value) {
|
|
return yoga::isUndefined(value) || yoga::isinf(value)
|
|
? undefined()
|
|
: StyleSizeLength{FloatOptional{value}, Unit::Percent};
|
|
}
|
|
constexpr static StyleSizeLength ofAuto() {
|
|
return StyleSizeLength{{}, Unit::Auto};
|
|
}
|
|
constexpr static StyleSizeLength ofMaxContent() {
|
|
return StyleSizeLength{{}, Unit::MaxContent};
|
|
}
|
|
constexpr static StyleSizeLength ofFitContent() {
|
|
return StyleSizeLength{{}, Unit::FitContent};
|
|
}
|
|
constexpr static StyleSizeLength ofStretch() {
|
|
return StyleSizeLength{{}, Unit::Stretch};
|
|
}
|
|
constexpr static StyleSizeLength undefined() {
|
|
return StyleSizeLength{{}, Unit::Undefined};
|
|
}
|
|
constexpr bool isAuto() const {
|
|
return unit_ == Unit::Auto;
|
|
}
|
|
constexpr bool isMaxContent() const {
|
|
return unit_ == Unit::MaxContent;
|
|
}
|
|
constexpr bool isFitContent() const {
|
|
return unit_ == Unit::FitContent;
|
|
}
|
|
constexpr bool isStretch() const {
|
|
return unit_ == Unit::Stretch;
|
|
}
|
|
constexpr bool isUndefined() const {
|
|
return unit_ == Unit::Undefined;
|
|
}
|
|
constexpr bool isDefined() const {
|
|
return !isUndefined();
|
|
}
|
|
constexpr bool isPoints() const {
|
|
return unit_ == Unit::Point;
|
|
}
|
|
constexpr bool isPercent() const {
|
|
return unit_ == Unit::Percent;
|
|
}
|
|
constexpr FloatOptional value() const {
|
|
return value_;
|
|
}
|
|
constexpr FloatOptional resolve(float referenceLength) {
|
|
switch (unit_) {
|
|
case Unit::Point:
|
|
return value_;
|
|
case Unit::Percent:
|
|
return FloatOptional{value_.unwrap() * referenceLength * 0.01f};
|
|
default:
|
|
return FloatOptional{};
|
|
}
|
|
}
|
|
explicit constexpr operator YGValue() const {
|
|
return YGValue{value_.unwrap(), unscopedEnum(unit_)};
|
|
}
|
|
constexpr bool operator==(const StyleSizeLength& rhs) const {
|
|
return value_ == rhs.value_ && unit_ == rhs.unit_;
|
|
}
|
|
constexpr bool inexactEquals(const StyleSizeLength& other) const {
|
|
return unit_ == other.unit_ &&
|
|
facebook::yoga::inexactEquals(value_, other.value_);
|
|
}
|
|
};
|
|
Unit unit_{Unit::Undefined};
|
|
};
|
|
inline bool inexactEquals(const StyleSizeLength& a, const StyleSizeLength& b) {
|
|
return a.inexactEquals(b);
|
|
}
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/style/StyleValueHandle.h}:
|
|
namespace facebook::yoga {
|
|
#pragma pack(push)
|
|
#pragma pack(1)
|
|
class StyleValueHandle {
|
|
public:
|
|
static constexpr StyleValueHandle ofAuto() {
|
|
StyleValueHandle handle;
|
|
handle.setType(Type::Auto);
|
|
return handle;
|
|
}
|
|
constexpr bool isUndefined() const {
|
|
return type() == Type::Undefined;
|
|
}
|
|
constexpr bool isDefined() const {
|
|
return !isUndefined();
|
|
}
|
|
constexpr bool isAuto() const {
|
|
return type() == Type::Auto;
|
|
}
|
|
};
|
|
enum class Keyword : uint8_t { MaxContent, FitContent, Stretch };
|
|
constexpr bool isKeyword(Keyword keyword) const {
|
|
return type() == Type::Keyword && value() == static_cast<uint16_t>(keyword);
|
|
}
|
|
constexpr Type type() const {
|
|
return static_cast<Type>(repr_ & kHandleTypeMask);
|
|
}
|
|
constexpr void setType(Type handleType) {
|
|
repr_ &= (~kHandleTypeMask);
|
|
repr_ |= static_cast<uint8_t>(handleType);
|
|
}
|
|
constexpr uint16_t value() const {
|
|
return repr_ >> 4;
|
|
}
|
|
constexpr void setValue(uint16_t value) {
|
|
repr_ &= (~kHandleValueMask);
|
|
repr_ |= (value << 4);
|
|
}
|
|
constexpr bool isValueIndexed() const {
|
|
return (repr_ & kHandleIndexedMask) != 0;
|
|
}
|
|
constexpr void setValueIsIndexed() {
|
|
repr_ |= kHandleIndexedMask;
|
|
}
|
|
uint16_t repr_{0};
|
|
};
|
|
#pragma pack(pop)
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCommon/yoga/yoga/style/StyleValuePool.h}:
|
|
namespace facebook::yoga {
|
|
class StyleValuePool {
|
|
public:
|
|
void store(StyleValueHandle& handle, StyleLength length) {
|
|
if (length.isUndefined()) {
|
|
handle.setType(StyleValueHandle::Type::Undefined);
|
|
} else if (length.isAuto()) {
|
|
handle.setType(StyleValueHandle::Type::Auto);
|
|
} else {
|
|
auto type = length.isPoints() ? StyleValueHandle::Type::Point
|
|
: StyleValueHandle::Type::Percent;
|
|
storeValue(handle, length.value().unwrap(), type);
|
|
}
|
|
}
|
|
void store(StyleValueHandle& handle, StyleSizeLength sizeValue) {
|
|
if (sizeValue.isUndefined()) {
|
|
handle.setType(StyleValueHandle::Type::Undefined);
|
|
} else if (sizeValue.isAuto()) {
|
|
handle.setType(StyleValueHandle::Type::Auto);
|
|
} else if (sizeValue.isMaxContent()) {
|
|
storeKeyword(handle, StyleValueHandle::Keyword::MaxContent);
|
|
} else if (sizeValue.isStretch()) {
|
|
storeKeyword(handle, StyleValueHandle::Keyword::Stretch);
|
|
} else if (sizeValue.isFitContent()) {
|
|
storeKeyword(handle, StyleValueHandle::Keyword::FitContent);
|
|
} else {
|
|
auto type = sizeValue.isPoints() ? StyleValueHandle::Type::Point
|
|
: StyleValueHandle::Type::Percent;
|
|
storeValue(handle, sizeValue.value().unwrap(), type);
|
|
}
|
|
}
|
|
void store(StyleValueHandle& handle, FloatOptional number) {
|
|
if (number.isUndefined()) {
|
|
handle.setType(StyleValueHandle::Type::Undefined);
|
|
} else {
|
|
storeValue(handle, number.unwrap(), StyleValueHandle::Type::Number);
|
|
}
|
|
}
|
|
StyleLength getLength(StyleValueHandle handle) const {
|
|
if (handle.isUndefined()) {
|
|
return StyleLength::undefined();
|
|
} else if (handle.isAuto()) {
|
|
return StyleLength::ofAuto();
|
|
} else {
|
|
assert(
|
|
handle.type() == StyleValueHandle::Type::Point ||
|
|
handle.type() == StyleValueHandle::Type::Percent);
|
|
float value = (handle.isValueIndexed())
|
|
? std::bit_cast<float>(buffer_.get32(handle.value()))
|
|
: unpackInlineInteger(handle.value());
|
|
return handle.type() == StyleValueHandle::Type::Point
|
|
? StyleLength::points(value)
|
|
: StyleLength::percent(value);
|
|
}
|
|
}
|
|
StyleSizeLength getSize(StyleValueHandle handle) const {
|
|
if (handle.isUndefined()) {
|
|
return StyleSizeLength::undefined();
|
|
} else if (handle.isAuto()) {
|
|
return StyleSizeLength::ofAuto();
|
|
} else if (handle.isKeyword(StyleValueHandle::Keyword::MaxContent)) {
|
|
return StyleSizeLength::ofMaxContent();
|
|
} else if (handle.isKeyword(StyleValueHandle::Keyword::FitContent)) {
|
|
return StyleSizeLength::ofFitContent();
|
|
} else if (handle.isKeyword(StyleValueHandle::Keyword::Stretch)) {
|
|
return StyleSizeLength::ofStretch();
|
|
} else {
|
|
assert(
|
|
handle.type() == StyleValueHandle::Type::Point ||
|
|
handle.type() == StyleValueHandle::Type::Percent);
|
|
float value = (handle.isValueIndexed())
|
|
? std::bit_cast<float>(buffer_.get32(handle.value()))
|
|
: unpackInlineInteger(handle.value());
|
|
return handle.type() == StyleValueHandle::Type::Point
|
|
? StyleSizeLength::points(value)
|
|
: StyleSizeLength::percent(value);
|
|
}
|
|
}
|
|
FloatOptional getNumber(StyleValueHandle handle) const {
|
|
if (handle.isUndefined()) {
|
|
return FloatOptional{};
|
|
} else {
|
|
assert(handle.type() == StyleValueHandle::Type::Number);
|
|
float value = (handle.isValueIndexed())
|
|
? std::bit_cast<float>(buffer_.get32(handle.value()))
|
|
: unpackInlineInteger(handle.value());
|
|
return FloatOptional{value};
|
|
}
|
|
}
|
|
};
|
|
} // namespace facebook::yoga
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/coremodules/AppStateModule.h}:
|
|
namespace facebook::react {
|
|
using AppStateConstants = NativeAppStateAppStateConstants<std::string>;
|
|
template <>
|
|
struct Bridging<AppStateConstants>
|
|
: NativeAppStateAppStateConstantsBridging<AppStateConstants> {};
|
|
using AppState = NativeAppStateAppState<std::string>;
|
|
template <>
|
|
struct Bridging<AppState> : NativeAppStateAppStateBridging<AppState> {};
|
|
class AppStateModule : public NativeAppStateCxxSpec<AppStateModule> {
|
|
public:
|
|
explicit AppStateModule(std::shared_ptr<CallInvoker> jsInvoker)
|
|
: NativeAppStateCxxSpec(jsInvoker) {}
|
|
AppStateConstants getConstants(jsi::Runtime& rt);
|
|
void getCurrentAppState(
|
|
jsi::Runtime& rt,
|
|
const AsyncCallback<AppState>& success,
|
|
jsi::Function error);
|
|
void addListener(jsi::Runtime& rt, const std::string& eventName);
|
|
void removeListeners(jsi::Runtime& rt, double count);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/coremodules/DeviceInfoModule.h}:
|
|
namespace facebook::react {
|
|
using DisplayMetrics =
|
|
NativeDeviceInfoDisplayMetrics<double, double, double, double>;
|
|
using DisplayMetricsAndroid = NativeDeviceInfoDisplayMetricsAndroid<
|
|
double,
|
|
double,
|
|
double,
|
|
double,
|
|
double>;
|
|
using DimensionsPayload = NativeDeviceInfoDimensionsPayload<
|
|
std::optional<DisplayMetrics>,
|
|
std::optional<DisplayMetrics>,
|
|
std::optional<DisplayMetricsAndroid>,
|
|
std::optional<DisplayMetricsAndroid>>;
|
|
using DeviceInfoConstants = NativeDeviceInfoDeviceInfoConstants<
|
|
DimensionsPayload,
|
|
std::optional<bool>,
|
|
std::optional<bool>>;
|
|
template <>
|
|
struct Bridging<DisplayMetrics>
|
|
: NativeDeviceInfoDisplayMetricsBridging<DisplayMetrics> {};
|
|
template <>
|
|
struct Bridging<DisplayMetricsAndroid>
|
|
: NativeDeviceInfoDisplayMetricsAndroidBridging<DisplayMetricsAndroid> {};
|
|
template <>
|
|
struct Bridging<DimensionsPayload>
|
|
: NativeDeviceInfoDimensionsPayloadBridging<DimensionsPayload> {};
|
|
template <>
|
|
struct Bridging<DeviceInfoConstants>
|
|
: NativeDeviceInfoDeviceInfoConstantsBridging<DeviceInfoConstants> {};
|
|
class DeviceInfoModule : public NativeDeviceInfoCxxSpec<DeviceInfoModule> {
|
|
public:
|
|
explicit DeviceInfoModule(std::shared_ptr<CallInvoker> jsInvoker)
|
|
: NativeDeviceInfoCxxSpec(jsInvoker) {}
|
|
DeviceInfoConstants getConstants(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/coremodules/PlatformConstantsModule.h}:
|
|
namespace facebook::react {
|
|
using ReactNativeVersionAndroid =
|
|
NativePlatformConstantsAndroidReactNativeVersionAndroid<
|
|
int,
|
|
int,
|
|
int,
|
|
std::optional<int>>;
|
|
template <>
|
|
struct Bridging<ReactNativeVersionAndroid>
|
|
: NativePlatformConstantsAndroidReactNativeVersionAndroidBridging<
|
|
ReactNativeVersionAndroid> {};
|
|
using PlatformConstantsAndroid =
|
|
NativePlatformConstantsAndroidPlatformConstantsAndroid<
|
|
bool,
|
|
std::optional<bool>,
|
|
ReactNativeVersionAndroid,
|
|
int,
|
|
std::string,
|
|
std::string,
|
|
std::string,
|
|
std::string,
|
|
std::optional<std::string>,
|
|
std::string,
|
|
std::string,
|
|
std::string>;
|
|
template <>
|
|
struct Bridging<PlatformConstantsAndroid>
|
|
: NativePlatformConstantsAndroidPlatformConstantsAndroidBridging<
|
|
PlatformConstantsAndroid> {};
|
|
class PlatformConstantsModule
|
|
: public NativePlatformConstantsAndroidCxxSpec<PlatformConstantsModule> {
|
|
public:
|
|
explicit PlatformConstantsModule(std::shared_ptr<CallInvoker> jsInvoker)
|
|
: NativePlatformConstantsAndroidCxxSpec(jsInvoker) {}
|
|
std::string getAndroidID(jsi::Runtime&) {
|
|
return "";
|
|
}
|
|
PlatformConstantsAndroid getConstants(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/DevLoadingViewModule.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/devsupport/IDevUIDelegate.h}
|
|
namespace facebook::react {
|
|
class DevLoadingViewModule
|
|
: public NativeDevLoadingViewCxxSpec<DevLoadingViewModule> {
|
|
public:
|
|
DevLoadingViewModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
std::weak_ptr<IDevUIDelegate> devUIDelegate);
|
|
~DevLoadingViewModule() override;
|
|
void showMessage(
|
|
jsi::Runtime& rt,
|
|
const std::string& message,
|
|
std::optional<int32_t> textColor,
|
|
std::optional<int32_t> backgroundColor);
|
|
void hide(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/DevServerHelper.h}:
|
|
namespace facebook::react {
|
|
class DevServerHelper {
|
|
public:
|
|
enum class DownloadProgressStatus : short { STARTED, FAILED, FINISHED };
|
|
using DownloadProgressCallback = std::function<void(DownloadProgressStatus)>;
|
|
DevServerHelper(
|
|
std::string appId,
|
|
std::string deviceName,
|
|
std::string devServerHost,
|
|
uint32_t devServerPort,
|
|
const HttpClientFactory& httpClientFactory,
|
|
JavaScriptModuleCallback javaScriptModuleCallback) noexcept;
|
|
~DevServerHelper() noexcept = default;
|
|
std::future<std::string> downloadBundleResourceSync(
|
|
const std::string& jsBundleUrl,
|
|
DownloadProgressCallback&& downloadProgressCallback = nullptr);
|
|
std::string getInspectorUrl() const;
|
|
std::string getBundleUrl() const;
|
|
std::string getPackagerConnectionUrl() const;
|
|
void openDebugger() const;
|
|
void setSourcePath(const std::string& sourcePath) {
|
|
sourcePath_ = sourcePath;
|
|
}
|
|
void setupHMRClient() const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/DevSettingsModule.h}:
|
|
namespace facebook::react {
|
|
class DevSettingsModule : public NativeDevSettingsCxxSpec<DevSettingsModule> {
|
|
using LiveReloadCallback = std::function<void()>;
|
|
|
|
public:
|
|
DevSettingsModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
std::weak_ptr<DevServerHelper> devServerHelper,
|
|
LiveReloadCallback&& liveReloadCallback)
|
|
: NativeDevSettingsCxxSpec(jsInvoker),
|
|
devServerHelper_(std::move(devServerHelper)),
|
|
liveReloadCallback_(std::move(liveReloadCallback)) {}
|
|
void reload(jsi::Runtime& rt);
|
|
void reloadWithReason(jsi::Runtime& rt, const std::string& reason);
|
|
void onFastRefresh(jsi::Runtime& rt);
|
|
void setHotLoadingEnabled(jsi::Runtime& rt, bool isHotLoadingEnabled);
|
|
void setIsDebuggingRemotely(
|
|
jsi::Runtime& rt,
|
|
bool isDebuggingRemotelyEnabled);
|
|
void setProfilingEnabled(jsi::Runtime& rt, bool isProfilingEnabled);
|
|
void toggleElementInspector(jsi::Runtime& rt);
|
|
void addMenuItem(jsi::Runtime& rt, const std::string& title);
|
|
void setIsShakeToShowDevMenuEnabled(jsi::Runtime& rt, bool enabled);
|
|
void openDebugger(jsi::Runtime& rt);
|
|
void addListener(jsi::Runtime& rt, const std::string& eventName);
|
|
void removeListeners(jsi::Runtime& rt, double count);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/IDevUIDelegate.h}:
|
|
namespace facebook::react {
|
|
struct IDevUIDelegate {
|
|
virtual ~IDevUIDelegate() noexcept = default;
|
|
virtual void showDownloadBundleProgress() = 0;
|
|
virtual void hideDownloadBundleProgress() = 0;
|
|
virtual void showLoadingView(
|
|
const std::string& message,
|
|
SharedColor textColor,
|
|
SharedColor backgroundColor) = 0;
|
|
virtual void hideLoadingView() = 0;
|
|
virtual void showDebuggerOverlay(
|
|
std::function<void()>&& resumeDebuggerFn) = 0;
|
|
virtual void hideDebuggerOverlay() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/LogBoxModule.h}:
|
|
namespace facebook::react {
|
|
class LogBoxModule : public NativeLogBoxCxxSpec<LogBoxModule> {
|
|
public:
|
|
LogBoxModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
std::shared_ptr<SurfaceDelegate> surfaceDelegate);
|
|
~LogBoxModule() override;
|
|
void show(jsi::Runtime& rt);
|
|
void hide(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/PackagerConnection.h}:
|
|
namespace facebook::react {
|
|
class PackagerConnection {
|
|
using LiveReloadCallback = std::function<void()>;
|
|
using ShowDevMenuCallback = std::function<void()>;
|
|
|
|
public:
|
|
PackagerConnection(
|
|
const WebSocketClientFactory& webSocketClientFactory,
|
|
const std::string& packagerConnectionUrl,
|
|
LiveReloadCallback&& liveReloadCallback,
|
|
ShowDevMenuCallback&& showDevMenuCallback);
|
|
~PackagerConnection() noexcept;
|
|
PackagerConnection(const PackagerConnection& other) = delete;
|
|
PackagerConnection& operator=(PackagerConnection& other) = delete;
|
|
PackagerConnection(PackagerConnection&& other) = delete;
|
|
PackagerConnection& operator=(PackagerConnection&& other) = delete;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/SourceCodeModule.h}:
|
|
namespace facebook::react {
|
|
using SourceCodeConstants = NativeSourceCodeSourceCodeConstants<std::string>;
|
|
template <>
|
|
struct Bridging<SourceCodeConstants>
|
|
: NativeSourceCodeSourceCodeConstantsBridging<SourceCodeConstants> {};
|
|
class SourceCodeModule : public NativeSourceCodeCxxSpec<SourceCodeModule> {
|
|
public:
|
|
explicit SourceCodeModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
std::shared_ptr<DevServerHelper> devServerHelper = nullptr)
|
|
: NativeSourceCodeCxxSpec(jsInvoker), devServerHelper_(devServerHelper) {}
|
|
SourceCodeConstants getConstants(jsi::Runtime& rt);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/inspector/Inspector.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/devsupport/inspector/InspectorThread.h}
|
|
namespace facebook::react {
|
|
using ToggleDebuggerOverlayFn =
|
|
std::function<void(bool, std::function<void()>&&)>;
|
|
using LiveReloadCallbackFn = std::function<void()>;
|
|
class Inspector : public InspectorThread,
|
|
public std::enable_shared_from_this<Inspector> {
|
|
public:
|
|
Inspector(
|
|
std::string appName,
|
|
std::string deviceName,
|
|
WebSocketClientFactory webSocketClientFactory,
|
|
HttpClientFactory httpClientFactory) noexcept;
|
|
~Inspector() noexcept override;
|
|
Inspector(const Inspector& other) = delete;
|
|
Inspector& operator=(Inspector& other) = delete;
|
|
Inspector(Inspector&& other) = delete;
|
|
Inspector& operator=(Inspector&& other) = delete;
|
|
void connectDebugger(const std::string& inspectorUrl) noexcept;
|
|
void ensureHostTarget(
|
|
LiveReloadCallbackFn&& liveReloadCallbackFn,
|
|
ToggleDebuggerOverlayFn&& toggleDebuggerOverlayFn) noexcept;
|
|
std::shared_ptr<jsinspector_modern::HostTarget> inspectorTarget() const;
|
|
};
|
|
std::string appName_;
|
|
std::string deviceName_;
|
|
WebSocketClientFactory webSocketClientFactory_;
|
|
HttpClientFactory httpClientFactory_;
|
|
std::shared_ptr<jsinspector_modern::HostTargetDelegate> hostDelegate_;
|
|
std::shared_ptr<jsinspector_modern::HostTarget> target_;
|
|
std::optional<int32_t> pageId_;
|
|
std::unique_ptr<jsinspector_modern::InspectorPackagerConnection>
|
|
packagerConnection_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/inspector/InspectorPackagerConnectionDelegate.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/devsupport/inspector/InspectorThread.h}
|
|
namespace facebook::react {
|
|
class InspectorPackagerConnectionDelegate final
|
|
: public jsinspector_modern::InspectorPackagerConnectionDelegate {
|
|
class WebSocket : public jsinspector_modern::IWebSocket {
|
|
public:
|
|
WebSocket(
|
|
const std::string& url,
|
|
std::weak_ptr<jsinspector_modern::IWebSocketDelegate> webSocketDelegate,
|
|
std::weak_ptr<InspectorThread> inspectorThread,
|
|
const WebSocketClientFactory& webSocketClientFactory);
|
|
~WebSocket() override;
|
|
WebSocket(const WebSocket& other) = delete;
|
|
WebSocket& operator=(WebSocket& other) = delete;
|
|
WebSocket(WebSocket&& other) = delete;
|
|
WebSocket& operator=(WebSocket&& other) = delete;
|
|
void send(std::string_view message) override;
|
|
|
|
private:
|
|
std::weak_ptr<jsinspector_modern::IWebSocketDelegate> webSocketDelegate_;
|
|
std::weak_ptr<InspectorThread> inspectorThread_;
|
|
std::unique_ptr<IWebSocketClient> websocket_;
|
|
};
|
|
|
|
public:
|
|
InspectorPackagerConnectionDelegate(
|
|
std::weak_ptr<InspectorThread> inspectorThread,
|
|
WebSocketClientFactory webSocketClientFactory) noexcept;
|
|
std::unique_ptr<jsinspector_modern::IWebSocket> connectWebSocket(
|
|
const std::string& url,
|
|
std::weak_ptr<jsinspector_modern::IWebSocketDelegate> delegate) override;
|
|
void scheduleCallback(
|
|
std::function<void(void)> callback,
|
|
std::chrono::milliseconds delayMs =
|
|
std::chrono::milliseconds::zero()) override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/devsupport/inspector/InspectorThread.h}:
|
|
namespace facebook::react {
|
|
class InspectorThread {
|
|
public:
|
|
InspectorThread() noexcept = default;
|
|
virtual ~InspectorThread() = default;
|
|
InspectorThread(const InspectorThread& other) = delete;
|
|
InspectorThread& operator=(InspectorThread& other) = delete;
|
|
InspectorThread(InspectorThread&& other) = delete;
|
|
InspectorThread& operator=(InspectorThread&& other) = delete;
|
|
virtual void invokeElsePost(
|
|
TaskDispatchThread::TaskFn&& callback,
|
|
std::chrono::milliseconds delayMs = std::chrono::milliseconds(0)) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/http/IHttpClient.h}:
|
|
namespace facebook::react {
|
|
namespace http {
|
|
using Headers = std::vector<std::pair<std::string, std::string>>;
|
|
struct FormDataField {
|
|
std::string fieldName;
|
|
Headers headers;
|
|
std::optional<std::string> string;
|
|
std::optional<std::string> uri;
|
|
};
|
|
using FormData = std::vector<FormDataField>;
|
|
struct Body {
|
|
std::optional<std::string> string;
|
|
std::optional<std::string> blob;
|
|
std::optional<FormData> formData;
|
|
std::optional<std::string> base64;
|
|
};
|
|
using OnUploadProgress = std::function<void(int64_t progress, int64_t size)>;
|
|
using OnResponse = std::function<void(uint16_t responseCode, Headers headers)>;
|
|
using OnBody = std::function<void(std::unique_ptr<folly::IOBuf> body)>;
|
|
using OnBodyIncremental = std::function<int64_t(
|
|
int64_t progress,
|
|
int64_t total,
|
|
std::unique_ptr<folly::IOBuf> body)>;
|
|
using OnBodyProgress = std::function<void(int64_t loaded, int64_t total)>;
|
|
using OnResponseComplete =
|
|
std::function<void(std::string error, bool timeoutError)>;
|
|
struct NetworkCallbacks {
|
|
OnUploadProgress onUploadProgress{nullptr};
|
|
OnResponse onResponse{nullptr};
|
|
OnBody onBody{nullptr};
|
|
OnBodyIncremental onBodyIncremental{nullptr};
|
|
OnBodyProgress onBodyProgress{nullptr};
|
|
OnResponseComplete onResponseComplete{nullptr};
|
|
bool sendIncrementalUpdates{false};
|
|
bool sendProgressUpdates{false};
|
|
};
|
|
struct IRequestToken {
|
|
virtual ~IRequestToken() = default;
|
|
virtual void cancel() noexcept = 0;
|
|
};
|
|
} // namespace http
|
|
struct IHttpClient {
|
|
virtual ~IHttpClient() = default;
|
|
virtual std::unique_ptr<http::IRequestToken> sendRequest(
|
|
http::NetworkCallbacks&& callback,
|
|
const std::string& method,
|
|
const std::string& url,
|
|
const http::Headers& headers = {},
|
|
const http::Body& body = {},
|
|
uint32_t timeout = 0,
|
|
std::optional<std::string> loggingId = std::nullopt) = 0;
|
|
};
|
|
extern const char HttpClientFactoryKey[];
|
|
using HttpClientFactory = std::function<std::unique_ptr<IHttpClient>()>;
|
|
HttpClientFactory getHttpClientFactory();
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/http/IWebSocketClient.h}:
|
|
namespace facebook::react {
|
|
class IWebSocketClient {
|
|
public:
|
|
using OnConnectCallback = std::function<void(bool, const std::string&)>;
|
|
using OnClosedCallback = std::function<void(const std::string&)>;
|
|
using OnMessageCallback = std::function<void(const std::string&)>;
|
|
virtual ~IWebSocketClient() = default;
|
|
virtual void setOnClosedCallback(OnClosedCallback&& callback) noexcept = 0;
|
|
virtual void setOnMessageCallback(OnMessageCallback&& callback) noexcept = 0;
|
|
virtual void connect(
|
|
const std::string& url,
|
|
OnConnectCallback&& = nullptr) = 0;
|
|
virtual void close(const std::string& reason) = 0;
|
|
virtual void send(const std::string& message) = 0;
|
|
virtual void ping() = 0;
|
|
};
|
|
extern const char WebSocketClientFactoryKey[];
|
|
using WebSocketClientFactory =
|
|
std::function<std::unique_ptr<IWebSocketClient>()>;
|
|
WebSocketClientFactory getWebSocketClientFactory();
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/io/IImageLoader.h}:
|
|
namespace facebook::react {
|
|
using IImageLoaderOnLoadCallback = std::function<
|
|
void(double imageWidth, double imageHeight, const char* errorMessage)>;
|
|
class IImageLoader {
|
|
public:
|
|
enum class CacheStatus {
|
|
None = 0,
|
|
Disk = 0x1,
|
|
Memory = 0x1 << 1,
|
|
};
|
|
virtual ~IImageLoader() = default;
|
|
virtual void loadImage(
|
|
const std::string& uri,
|
|
const IImageLoaderOnLoadCallback&& onLoad) = 0;
|
|
virtual CacheStatus getCacheStatus(const std::string& uri) = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/io/ImageLoaderModule.h}:
|
|
namespace facebook::react {
|
|
using ImageSize = NativeImageLoaderAndroidImageSize<double, double>;
|
|
template <>
|
|
struct Bridging<ImageSize>
|
|
: NativeImageLoaderAndroidImageSizeBridging<ImageSize> {};
|
|
class ImageLoaderModule
|
|
: public NativeImageLoaderAndroidCxxSpec<ImageLoaderModule> {
|
|
public:
|
|
explicit ImageLoaderModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
std::weak_ptr<IImageLoader> imageLoader = std::weak_ptr<IImageLoader>())
|
|
: NativeImageLoaderAndroidCxxSpec(jsInvoker),
|
|
imageLoader_(std::move(imageLoader)) {}
|
|
jsi::Object getConstants(jsi::Runtime& rt);
|
|
void abortRequest(jsi::Runtime& rt, int32_t requestId);
|
|
AsyncPromise<ImageSize> getSize(jsi::Runtime& rt, const std::string& uri);
|
|
AsyncPromise<ImageSize> getSizeWithHeaders(
|
|
jsi::Runtime& rt,
|
|
const std::string& uri,
|
|
jsi::Object headers);
|
|
AsyncPromise<bool>
|
|
prefetchImage(jsi::Runtime& rt, const std::string& uri, int32_t requestId);
|
|
jsi::Object queryCache(
|
|
jsi::Runtime& rt,
|
|
const std::vector<std::string>& uris);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/io/NetworkingModule.h}:
|
|
namespace facebook::react {
|
|
template <>
|
|
struct Bridging<http::FormDataField> {
|
|
static http::FormDataField fromJs(
|
|
jsi::Runtime& rt,
|
|
const jsi::Object& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
auto fieldName = bridging::fromJs<std::string>(
|
|
rt, value.getProperty(rt, "fieldName"), jsInvoker);
|
|
auto headers = bridging::fromJs<http::Headers>(
|
|
rt, value.getProperty(rt, "headers"), jsInvoker);
|
|
auto string = bridging::fromJs<std::optional<std::string>>(
|
|
rt, value.getProperty(rt, "string"), jsInvoker);
|
|
auto uri = bridging::fromJs<std::optional<std::string>>(
|
|
rt, value.getProperty(rt, "uri"), jsInvoker);
|
|
return http::FormDataField{
|
|
.fieldName = fieldName,
|
|
.headers = headers,
|
|
.string = string,
|
|
.uri = uri};
|
|
}
|
|
};
|
|
template <>
|
|
struct Bridging<http::Body> {
|
|
static http::Body fromJs(
|
|
jsi::Runtime& rt,
|
|
const jsi::Object& value,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker) {
|
|
return http::Body{
|
|
.string = bridging::fromJs<std::optional<std::string>>(
|
|
rt, value.getProperty(rt, "string"), jsInvoker),
|
|
.blob = bridging::fromJs<std::optional<std::string>>(
|
|
rt, value.getProperty(rt, "blob"), jsInvoker),
|
|
.formData = bridging::fromJs<std::optional<http::FormData>>(
|
|
rt, value.getProperty(rt, "formData"), jsInvoker),
|
|
.base64 = bridging::fromJs<std::optional<std::string>>(
|
|
rt, value.getProperty(rt, "base64"), jsInvoker),
|
|
};
|
|
}
|
|
};
|
|
class Requests {
|
|
public:
|
|
Requests() noexcept = default;
|
|
~Requests();
|
|
Requests(Requests& other) = delete;
|
|
Requests& operator=(Requests& other) = delete;
|
|
Requests(Requests&& other) = delete;
|
|
Requests& operator=(Requests&& other) = delete;
|
|
bool reserve(uint32_t id);
|
|
void store(uint32_t id, std::unique_ptr<http::IRequestToken> token);
|
|
bool erase(uint32_t id);
|
|
void cancel(uint32_t id);
|
|
void stop();
|
|
bool isStopped();
|
|
};
|
|
};
|
|
class NetworkingModule
|
|
: public NativeNetworkingAndroidCxxSpec<NetworkingModule>,
|
|
public std::enable_shared_from_this<NetworkingModule> {
|
|
public:
|
|
NetworkingModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
const HttpClientFactory& httpClientFactory);
|
|
~NetworkingModule() override;
|
|
void sendRequest(
|
|
jsi::Runtime& rt,
|
|
const std::string& method,
|
|
const std::string& url,
|
|
uint32_t requestId,
|
|
const http::Headers& headers,
|
|
const http::Body& body,
|
|
const std::string& responseType,
|
|
bool useIncrementalUpdates,
|
|
uint32_t timeout,
|
|
bool withCredentials);
|
|
void abortRequest(jsi::Runtime& rt, uint32_t requestId);
|
|
void clearCookies(jsi::Runtime& rt, const AsyncCallback<bool>& callback);
|
|
void addListener(jsi::Runtime& rt, const std::string& eventName);
|
|
void removeListeners(jsi::Runtime& rt, uint32_t count);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/io/ResourceLoader.h}:
|
|
namespace facebook::react {
|
|
class ResourceLoader {
|
|
public:
|
|
static bool isDirectory(const std::string& path);
|
|
static bool isFile(const std::string& path);
|
|
static bool isAbsolutePath(const std::string& path);
|
|
static std::string getFileContents(const std::string& path);
|
|
static std::filesystem::path getCacheDirectory(
|
|
const std::string& path = std::string());
|
|
|
|
protected:
|
|
static bool isResourceDirectory(const std::string& path);
|
|
static bool isResourceFile(const std::string& path);
|
|
static std::string getResourceFileContents(const std::string& path);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/io/WebSocketModule.h}:
|
|
namespace facebook::react {
|
|
class WebSocketModule : public NativeWebSocketModuleCxxSpec<WebSocketModule>,
|
|
public std::enable_shared_from_this<WebSocketModule> {
|
|
public:
|
|
WebSocketModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
WebSocketClientFactory webSocketClientFactory);
|
|
~WebSocketModule() override;
|
|
WebSocketModule(const WebSocketModule& other) = delete;
|
|
WebSocketModule& operator=(WebSocketModule& other) = delete;
|
|
WebSocketModule(WebSocketModule&& other) = delete;
|
|
WebSocketModule& operator=(WebSocketModule&& other) = delete;
|
|
void connect(
|
|
jsi::Runtime& rt,
|
|
const std::string& url,
|
|
const std::optional<std::vector<std::string>>& protocols,
|
|
jsi::Object options,
|
|
int32_t socketID);
|
|
void send(jsi::Runtime& rt, const std::string& message, int32_t socketID);
|
|
void sendBinary(
|
|
jsi::Runtime& rt,
|
|
const std::string& base64String,
|
|
int32_t socketID);
|
|
void ping(jsi::Runtime& rt, int32_t socketID);
|
|
void close(
|
|
jsi::Runtime& rt,
|
|
int32_t code,
|
|
const std::string& reason,
|
|
int32_t socketID);
|
|
void addListener(jsi::Runtime& rt, const std::string& eventName);
|
|
void removeListeners(jsi::Runtime& rt, int32_t count);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/io/platform/android/AssetManagerHelpers.h}:
|
|
namespace facebook::react {
|
|
AAssetManager* getJavaAssetManager();
|
|
bool isDirectoryNotEmpty(const std::string& path);
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/jni/JniHelper.h}:
|
|
namespace facebook::react {
|
|
jobject getApplication(JNIEnv* env);
|
|
jni::alias_ref<jni::AContext> getContext();
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/logging/DefaultLogger.h}:
|
|
namespace facebook::react {
|
|
using Logger =
|
|
std::function<void(const std::string& message, unsigned int logLevel)>;
|
|
Logger getDefaultLogger();
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/logging/DefaultOnJsErrorHandler.h}:
|
|
namespace facebook::react {
|
|
static inline JsErrorHandler::OnJsError getDefaultOnJsErrorFunc() {
|
|
return [](jsi::Runtime&, const JsErrorHandler::ProcessedError& error) {
|
|
LOG(ERROR) << "[onJsError called]: " << error << std::endl;
|
|
};
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/logging/LogOnce.h}:
|
|
namespace facebook::react {
|
|
class LogOnceWrapper : public std::stringstream {
|
|
public:
|
|
enum class Severity { Info, Warning, Error, Fatal };
|
|
LogOnceWrapper(Severity severity = Severity::Info) : severity_(severity) {}
|
|
~LogOnceWrapper();
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/logging/NativeExceptionsManager.h}:
|
|
namespace facebook::react {
|
|
using StackFrame = NativeExceptionsManagerStackFrame<
|
|
std::optional<int32_t>,
|
|
std::optional<std::string>,
|
|
std::optional<int32_t>,
|
|
std::string,
|
|
std::optional<bool>>;
|
|
template <>
|
|
struct Bridging<StackFrame>
|
|
: NativeExceptionsManagerStackFrameBridging<StackFrame> {};
|
|
using ExceptionData = NativeExceptionsManagerExceptionData<
|
|
std::string,
|
|
std::optional<std::string>,
|
|
std::optional<std::string>,
|
|
std::optional<std::string>,
|
|
std::vector<StackFrame>,
|
|
int32_t,
|
|
bool,
|
|
std::optional<std::unordered_map<std::string, std::string>>>;
|
|
template <>
|
|
struct Bridging<ExceptionData>
|
|
: NativeExceptionsManagerExceptionDataBridging<ExceptionData> {};
|
|
class NativeExceptionsManager
|
|
: public NativeExceptionsManagerCxxSpec<NativeExceptionsManager> {
|
|
public:
|
|
NativeExceptionsManager(
|
|
JsErrorHandler::OnJsError onJsError,
|
|
std::shared_ptr<CallInvoker> jsInvoker)
|
|
: NativeExceptionsManagerCxxSpec(jsInvoker),
|
|
onJsError_(std::move(onJsError)) {}
|
|
void reportFatalException(
|
|
jsi::Runtime& rt,
|
|
std::string message,
|
|
std::vector<StackFrame> stack,
|
|
int32_t exceptionId);
|
|
void reportSoftException(
|
|
jsi::Runtime& rt,
|
|
std::string message,
|
|
std::vector<StackFrame> stack,
|
|
int32_t exceptionId);
|
|
void reportException(jsi::Runtime& runtime, const ExceptionData& data);
|
|
void updateExceptionMessage(
|
|
jsi::Runtime& rt,
|
|
jsi::String message,
|
|
jsi::Array stack,
|
|
double exceptionId) {}
|
|
void dismissRedbox(jsi::Runtime& rt) {}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/nativemodule/JavaScriptModule.h}:
|
|
namespace facebook::react {
|
|
using JavaScriptModuleCallback = std::function<void(
|
|
const std::string& moduleName,
|
|
const std::string& methodName,
|
|
folly::dynamic&& args)>;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/nativemodule/TurboModuleManager.h}:
|
|
namespace facebook::react {
|
|
using TurboModuleManagerDelegate = std::function<std::shared_ptr<TurboModule>(
|
|
const std::string& name,
|
|
const std::shared_ptr<CallInvoker>& jsInvoker)>;
|
|
using TurboModuleManagerDelegates = std::vector<TurboModuleManagerDelegate>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/profiling/FrameStats.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/profiling/perfetto.h}
|
|
namespace facebook::react {
|
|
void enableFrameStatsPrinting(bool enable = true);
|
|
void logFrameStats(double timeStampMs, double durationMs);
|
|
inline double getTimeStampMs() {
|
|
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
|
std::chrono::high_resolution_clock::now().time_since_epoch())
|
|
.count() /
|
|
1000000.0;
|
|
}
|
|
class FrameStatsBlock {
|
|
public:
|
|
FrameStatsBlock() : startTimeStamp_(getTimeStampMs()) {}
|
|
~FrameStatsBlock() {
|
|
logFrameStats(startTimeStamp_, getTimeStampMs() - startTimeStamp_);
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/profiling/RuntimeHeapInfoCollector.h}:
|
|
namespace facebook::react {
|
|
struct HeapInfo {
|
|
int64_t allocatedBytes{0};
|
|
int64_t heapSize{0};
|
|
int64_t numCollections{0};
|
|
};
|
|
inline std::ostream& operator<<(std::ostream& os, HeapInfo& heapInfo) {
|
|
os << "[heapInfo: allocatedBytes: " << heapInfo.allocatedBytes
|
|
<< ", heapSize: " << heapInfo.heapSize
|
|
<< ", numCollections: " << heapInfo.numCollections << "]";
|
|
return os;
|
|
}
|
|
class RuntimeHeapInfoCollector {
|
|
public:
|
|
RuntimeHeapInfoCollector(std::chrono::milliseconds intervalMs);
|
|
static std::unique_ptr<RuntimeHeapInfoCollector> create(
|
|
std::chrono::milliseconds intervalMs);
|
|
void collectHeapInfo(jsi::Runtime& runtime);
|
|
HeapInfo getHeapInfo() {
|
|
return heapInfo_;
|
|
}
|
|
};
|
|
std::chrono::milliseconds intervalMs_;
|
|
std::chrono::steady_clock::time_point lastCollectionTime_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/profiling/TimeSeries.h}:
|
|
namespace facebook::react {
|
|
class TimeSeries {
|
|
struct Range {
|
|
int idxFrom1{0};
|
|
int idxTo1{0};
|
|
int idxFrom2{0};
|
|
int idxTo2{0};
|
|
int size() const {
|
|
return (idxTo1 - idxFrom1) + (idxTo2 - idxFrom2);
|
|
}
|
|
bool isEmpty() const {
|
|
return size() == 0;
|
|
}
|
|
bool isContinuous() const {
|
|
return idxTo2 - idxFrom2 == 0;
|
|
}
|
|
};
|
|
|
|
public:
|
|
static constexpr int DEFAULT_CAPACITY = 100;
|
|
enum class Bound { Upper = 0, Lower = 1 };
|
|
TimeSeries(int capacity = DEFAULT_CAPACITY);
|
|
bool operator==(const TimeSeries& rhs) const;
|
|
int getCapacity() const {
|
|
return static_cast<int>(times_.capacity());
|
|
}
|
|
void setCapacity(int capacity);
|
|
void reset();
|
|
int findHistoryPointIndex(double t, Bound bound = Bound::Lower) const;
|
|
int getNumPoints() const {
|
|
return static_cast<int>(times_.size());
|
|
}
|
|
double& valueAtIndex(int idx) {
|
|
const int numPoints = getNumPoints();
|
|
return values_[(idx + position_) % numPoints];
|
|
}
|
|
double& timeAtIndex(int idx) {
|
|
const int numPoints = getNumPoints();
|
|
return times_[(idx + position_) % numPoints];
|
|
}
|
|
double valueAtIndex(int idx) const {
|
|
const int numPoints = getNumPoints();
|
|
return values_[(idx + position_) % numPoints];
|
|
}
|
|
double timeAtIndex(int idx) const {
|
|
const int numPoints = getNumPoints();
|
|
return times_[(idx + position_) % numPoints];
|
|
}
|
|
void appendValue(double time, double value);
|
|
void accumulateValue(double timeFrom, double timeTo, double value);
|
|
double getValue(double time) const;
|
|
double getPercentile(unsigned int percentile) const;
|
|
double getPercentile(unsigned int percentile, double timeFrom, double timeTo)
|
|
const;
|
|
double getAverage() const;
|
|
double getAverage(double timeFrom, double timeTo) const;
|
|
double getMax() const;
|
|
double getMax(double timeFrom, double timeTo) const;
|
|
double getMin() const;
|
|
double getMin(double timeFrom, double timeTo) const;
|
|
double getSum() const;
|
|
double getSum(double timeFrom, double timeTo) const;
|
|
int getCount(double timeFrom, double timeTo) const;
|
|
double getMaxTime() const;
|
|
double getMinTime() const;
|
|
friend std::ostream& operator<<(std::ostream& os, const TimeSeries& ts);
|
|
friend std::ostream& operator<<(
|
|
std::ostream& os,
|
|
const TimeSeries::Range& range);
|
|
};
|
|
Range findHistoryPointRange(double timeFrom, double timeTo) const;
|
|
Range wholeRange() const;
|
|
double getPercentile(unsigned int percentile, const Range& range) const;
|
|
double getAverage(const Range& range) const;
|
|
double getMax(const Range& range) const;
|
|
double getMin(const Range& range) const;
|
|
double getSum(const Range& range) const;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/profiling/perfetto.h}:
|
|
inline void initializePerfetto() {}
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/profiling/tracy_noop.h}:
|
|
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/AnimatedModule.h}:
|
|
namespace facebook::react {
|
|
class AnimatedModule : public NativeAnimatedModuleCxxSpec<AnimatedModule>,
|
|
public TurboModuleWithJSIBindings {
|
|
struct CreateAnimatedNodeOp {
|
|
Tag tag{};
|
|
folly::dynamic config;
|
|
};
|
|
struct GetValueOp {
|
|
Tag tag{};
|
|
AsyncCallback<double> callback;
|
|
};
|
|
struct StartListeningToAnimatedNodeValueOp {
|
|
Tag tag{};
|
|
};
|
|
struct StopListeningToAnimatedNodeValueOp {
|
|
Tag tag{};
|
|
};
|
|
struct ConnectAnimatedNodesOp {
|
|
Tag parentTag{};
|
|
Tag childTag{};
|
|
};
|
|
struct DisconnectAnimatedNodesOp {
|
|
Tag parentTag{};
|
|
Tag childTag{};
|
|
};
|
|
struct StartAnimatingNodeOp {
|
|
int animationId{};
|
|
Tag nodeTag{};
|
|
folly::dynamic config;
|
|
AnimationEndCallback endCallback;
|
|
};
|
|
struct StopAnimationOp {
|
|
int animationId{};
|
|
};
|
|
struct SetAnimatedNodeValueOp {
|
|
Tag nodeTag{};
|
|
double value{};
|
|
};
|
|
struct SetAnimatedNodeOffsetOp {
|
|
Tag nodeTag{};
|
|
double offset{};
|
|
};
|
|
struct FlattenAnimatedNodeOffsetOp {
|
|
Tag nodeTag{};
|
|
};
|
|
struct ExtractAnimatedNodeOffsetOp {
|
|
Tag nodeTag{};
|
|
};
|
|
struct ConnectAnimatedNodeToViewOp {
|
|
Tag nodeTag{};
|
|
Tag viewTag{};
|
|
};
|
|
struct DisconnectAnimatedNodeFromViewOp {
|
|
Tag nodeTag{};
|
|
Tag viewTag{};
|
|
};
|
|
struct RestoreDefaultValuesOp {
|
|
Tag nodeTag{};
|
|
};
|
|
struct DropAnimatedNodeOp {
|
|
Tag tag{};
|
|
};
|
|
struct AddAnimatedEventToViewOp {
|
|
Tag viewTag{};
|
|
std::string eventName;
|
|
folly::dynamic eventMapping;
|
|
};
|
|
struct RemoveAnimatedEventFromViewOp {
|
|
Tag viewTag{};
|
|
std::string eventName;
|
|
Tag animatedNodeTag{};
|
|
};
|
|
using Operation = std::variant<
|
|
CreateAnimatedNodeOp,
|
|
GetValueOp,
|
|
StartListeningToAnimatedNodeValueOp,
|
|
StopListeningToAnimatedNodeValueOp,
|
|
ConnectAnimatedNodesOp,
|
|
DisconnectAnimatedNodesOp,
|
|
StartAnimatingNodeOp,
|
|
StopAnimationOp,
|
|
SetAnimatedNodeOffsetOp,
|
|
SetAnimatedNodeValueOp,
|
|
ConnectAnimatedNodeToViewOp,
|
|
DisconnectAnimatedNodeFromViewOp,
|
|
RestoreDefaultValuesOp,
|
|
FlattenAnimatedNodeOffsetOp,
|
|
ExtractAnimatedNodeOffsetOp,
|
|
DropAnimatedNodeOp,
|
|
AddAnimatedEventToViewOp,
|
|
RemoveAnimatedEventFromViewOp>;
|
|
|
|
public:
|
|
AnimatedModule(
|
|
std::shared_ptr<CallInvoker> jsInvoker,
|
|
std::shared_ptr<NativeAnimatedNodesManagerProvider> nodesManagerProvider);
|
|
void startOperationBatch(jsi::Runtime& rt);
|
|
void finishOperationBatch(jsi::Runtime& rt);
|
|
void createAnimatedNode(jsi::Runtime& rt, Tag tag, jsi::Object config);
|
|
void updateAnimatedNodeConfig(jsi::Runtime& rt, Tag tag, jsi::Object config);
|
|
void
|
|
getValue(jsi::Runtime& rt, Tag tag, AsyncCallback<double> saveValueCallback);
|
|
void startListeningToAnimatedNodeValue(jsi::Runtime& rt, Tag tag);
|
|
void stopListeningToAnimatedNodeValue(jsi::Runtime& rt, Tag tag);
|
|
void connectAnimatedNodes(jsi::Runtime& rt, Tag parentTag, Tag childTag);
|
|
void disconnectAnimatedNodes(jsi::Runtime& rt, Tag parentTag, Tag childTag);
|
|
void startAnimatingNode(
|
|
jsi::Runtime& rt,
|
|
int animationId,
|
|
Tag nodeTag,
|
|
jsi::Object config,
|
|
AnimationEndCallback endCallback);
|
|
void stopAnimation(jsi::Runtime& rt, int animationId);
|
|
void setAnimatedNodeValue(jsi::Runtime& rt, Tag nodeTag, double value);
|
|
void setAnimatedNodeOffset(jsi::Runtime& rt, Tag nodeTag, double offset);
|
|
void flattenAnimatedNodeOffset(jsi::Runtime& rt, Tag nodeTag);
|
|
void extractAnimatedNodeOffset(jsi::Runtime& rt, Tag nodeTag);
|
|
void connectAnimatedNodeToView(jsi::Runtime& rt, Tag nodeTag, Tag viewTag);
|
|
void
|
|
disconnectAnimatedNodeFromView(jsi::Runtime& rt, Tag nodeTag, Tag viewTag);
|
|
void restoreDefaultValues(jsi::Runtime& rt, Tag nodeTag);
|
|
void dropAnimatedNode(jsi::Runtime& rt, Tag tag);
|
|
void addAnimatedEventToView(
|
|
jsi::Runtime& rt,
|
|
Tag viewTag,
|
|
std::string eventName,
|
|
jsi::Object eventMapping);
|
|
void removeAnimatedEventFromView(
|
|
jsi::Runtime& rt,
|
|
Tag viewTag,
|
|
std::string eventName,
|
|
Tag animatedNodeTag);
|
|
void addListener(jsi::Runtime& rt, const std::string& eventName);
|
|
void removeListeners(jsi::Runtime& rt, int count);
|
|
void queueAndExecuteBatchedOperations(
|
|
jsi::Runtime& rt,
|
|
jsi::Array operationsAndArgs);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/AnimatedMountingOverrideDelegate.h}:
|
|
namespace facebook::react {
|
|
class AnimatedMountingOverrideDelegate : public MountingOverrideDelegate {
|
|
public:
|
|
AnimatedMountingOverrideDelegate(
|
|
std::function<folly::dynamic(Tag)> getAnimatedManagedProps,
|
|
const Scheduler& scheduler);
|
|
bool shouldOverridePullTransaction() const override;
|
|
std::optional<MountingTransaction> pullTransaction(
|
|
SurfaceId surfaceId,
|
|
MountingTransaction::Number transactionNumber,
|
|
const TransactionTelemetry& telemetry,
|
|
ShadowViewMutationList mutations) const override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/EventEmitterListener.h}:
|
|
namespace facebook::react {
|
|
template <typename... TArgs>
|
|
using EventListenerT = std::function<bool(TArgs...)>;
|
|
template <typename... TArgs>
|
|
class EventListenerContainerT {
|
|
public:
|
|
bool willDispatchEvent(TArgs... args) {
|
|
std::shared_lock lock(mutex_);
|
|
bool handled = false;
|
|
for (const auto& listener : eventListeners_) {
|
|
handled = (*listener)(args...);
|
|
if (handled) {
|
|
break;
|
|
}
|
|
}
|
|
return handled;
|
|
}
|
|
void addListener(std::shared_ptr<const EventListenerT<TArgs...>> listener) {
|
|
std::unique_lock lock(mutex_);
|
|
eventListeners_.push_back(std::move(listener));
|
|
}
|
|
void removeListener(
|
|
const std::shared_ptr<const EventListenerT<TArgs...>>& listener) {
|
|
std::unique_lock lock(mutex_);
|
|
auto it =
|
|
std::find(eventListeners_.begin(), eventListeners_.end(), listener);
|
|
if (it != eventListeners_.end()) {
|
|
eventListeners_.erase(it);
|
|
}
|
|
}
|
|
};
|
|
using EventEmitterListener =
|
|
EventListenerT<Tag, const std::string&, const EventPayload&>;
|
|
using EventEmitterListenerContainer =
|
|
EventListenerContainerT<Tag, const std::string&, const EventPayload&>;
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedAllowlist.h}:
|
|
namespace facebook::react {
|
|
inline static std::unordered_set<std::string> getDirectManipulationAllowlist() {
|
|
static std::unordered_set<std::string> DIRECT_MANIPULATION_STYLES{
|
|
"backgroundColor",
|
|
"borderBottomColor",
|
|
"borderColor",
|
|
"borderEndColor",
|
|
"borderLeftColor",
|
|
"borderRightColor",
|
|
"borderStartColor",
|
|
"borderTopColor",
|
|
"color",
|
|
"tintColor",
|
|
"borderBottomEndRadius",
|
|
"borderBottomLeftRadius",
|
|
"borderBottomRightRadius",
|
|
"borderBottomStartRadius",
|
|
"borderEndEndRadius",
|
|
"borderEndStartRadius",
|
|
"borderRadius",
|
|
"borderTopEndRadius",
|
|
"borderTopLeftRadius",
|
|
"borderTopRightRadius",
|
|
"borderTopStartRadius",
|
|
"borderStartEndRadius",
|
|
"borderStartStartRadius",
|
|
"elevation",
|
|
"opacity",
|
|
"transform",
|
|
"zIndex",
|
|
"shadowOpacity",
|
|
"shadowRadius",
|
|
"scaleX",
|
|
"scaleY",
|
|
"translateX",
|
|
"translateY",
|
|
};
|
|
return DIRECT_MANIPULATION_STYLES;
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManager.h}:
|
|
namespace facebook::react {
|
|
using TimePointFunction = std::chrono::steady_clock::time_point (*)();
|
|
void g_setNativeAnimatedNowTimestampFunction(TimePointFunction nowFunction);
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
using UiTask = std::function<void()>;
|
|
using EndResult = NativeAnimatedTurboModuleEndResult<
|
|
bool,
|
|
std::optional<double>,
|
|
std::optional<double>>;
|
|
using AnimationEndCallback = AsyncCallback<EndResult>;
|
|
template <>
|
|
struct Bridging<EndResult>
|
|
: NativeAnimatedTurboModuleEndResultBridging<EndResult> {};
|
|
class NativeAnimatedNodesManager {
|
|
public:
|
|
using DirectManipulationCallback =
|
|
std::function<void(Tag, const folly::dynamic&)>;
|
|
using FabricCommitCallback =
|
|
std::function<void(std::unordered_map<Tag, folly::dynamic>&)>;
|
|
using StartOnRenderCallback = std::function<void(std::function<void()>&&)>;
|
|
using StopOnRenderCallback = std::function<void()>;
|
|
explicit NativeAnimatedNodesManager(
|
|
DirectManipulationCallback&& directManipulationCallback,
|
|
FabricCommitCallback&& fabricCommitCallback,
|
|
StartOnRenderCallback&& startOnRenderCallback = nullptr,
|
|
StopOnRenderCallback&& stopOnRenderCallback = nullptr) noexcept;
|
|
~NativeAnimatedNodesManager() noexcept;
|
|
template <
|
|
typename T,
|
|
typename = std::enable_if_t<std::is_base_of_v<AnimatedNode, T>>>
|
|
T* getAnimatedNode(Tag tag) const
|
|
requires(std::is_base_of_v<AnimatedNode, T>)
|
|
{
|
|
if (auto it = animatedNodes_.find(tag); it != animatedNodes_.end()) {
|
|
return static_cast<T*>(it->second.get());
|
|
}
|
|
return nullptr;
|
|
}
|
|
std::optional<double> getValue(Tag tag) noexcept;
|
|
void createAnimatedNode(Tag tag, const folly::dynamic& config) noexcept;
|
|
void connectAnimatedNodes(Tag parentTag, Tag childTag) noexcept;
|
|
void connectAnimatedNodeToView(Tag propsNodeTag, Tag viewTag) noexcept;
|
|
void disconnectAnimatedNodes(Tag parentTag, Tag childTag) noexcept;
|
|
void disconnectAnimatedNodeFromView(Tag propsNodeTag, Tag viewTag) noexcept;
|
|
void restoreDefaultValues(Tag tag) noexcept;
|
|
void dropAnimatedNode(Tag tag) noexcept;
|
|
void setAnimatedNodeValue(Tag tag, double value);
|
|
void flattenAnimatedNodeOffset(Tag tag);
|
|
void extractAnimatedNodeOffsetOp(Tag tag);
|
|
void setAnimatedNodeOffset(Tag tag, double offset);
|
|
void startAnimatingNode(
|
|
int animationId,
|
|
Tag animatedNodeTag,
|
|
folly::dynamic config,
|
|
std::optional<AnimationEndCallback> endCallback) noexcept;
|
|
void stopAnimation(
|
|
int animationId,
|
|
bool isTrackingAnimation = false) noexcept;
|
|
void addAnimatedEventToView(
|
|
Tag viewTag,
|
|
const std::string& eventName,
|
|
const folly::dynamic& eventMapping) noexcept;
|
|
void removeAnimatedEventFromView(
|
|
Tag viewTag,
|
|
const std::string& eventName,
|
|
Tag animatedValueTag) noexcept;
|
|
std::shared_ptr<EventEmitterListener> getEventEmitterListener() noexcept {
|
|
return ensureEventEmitterListener();
|
|
}
|
|
void startListeningToAnimatedNodeValue(
|
|
Tag tag,
|
|
ValueListenerCallback&& callback) noexcept;
|
|
void stopListeningToAnimatedNodeValue(Tag tag) noexcept;
|
|
void schedulePropsCommit(
|
|
Tag viewTag,
|
|
const folly::dynamic& props,
|
|
bool layoutStyleUpdated,
|
|
bool forceFabricCommit) noexcept;
|
|
bool commitProps();
|
|
void scheduleOnUI(UiTask&& task) {
|
|
{
|
|
std::lock_guard<std::mutex> lock(uiTasksMutex_);
|
|
operations_.push_back(std::move(task));
|
|
}
|
|
startRenderCallbackIfNeeded();
|
|
}
|
|
void onRender();
|
|
void startRenderCallbackIfNeeded();
|
|
void updateNodes(
|
|
const std::set<int>& finishedAnimationValueNodes = {}) noexcept;
|
|
folly::dynamic managedProps(Tag tag) noexcept;
|
|
bool isOnRenderThread() const noexcept;
|
|
};
|
|
DirectManipulationCallback directManipulationCallback_;
|
|
FabricCommitCallback fabricCommitCallback_;
|
|
std::atomic_bool isRenderCallbackStarted_{false};
|
|
StartOnRenderCallback startOnRenderCallback_;
|
|
StopOnRenderCallback stopOnRenderCallback_;
|
|
std::shared_ptr<EventEmitterListener> eventEmitterListener_{nullptr};
|
|
std::unordered_map<Tag, folly::dynamic> updateViewProps_{};
|
|
std::unordered_map<Tag, folly::dynamic> updateViewPropsDirect_{};
|
|
int animatedGraphBFSColor_ = 0;
|
|
friend
|
|
friend
|
|
friend
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManagerProvider.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/NativeAnimatedNodesManager.h}
|
|
|
|
namespace facebook::react {
|
|
class UIManagerNativeAnimatedDelegateImpl
|
|
: public UIManagerNativeAnimatedDelegate {
|
|
public:
|
|
explicit UIManagerNativeAnimatedDelegateImpl(
|
|
std::weak_ptr<NativeAnimatedNodesManager> nativeAnimatedNodesManager);
|
|
void runAnimationFrame() override;
|
|
};
|
|
class NativeAnimatedNodesManagerProvider {
|
|
public:
|
|
NativeAnimatedNodesManagerProvider(
|
|
NativeAnimatedNodesManager::StartOnRenderCallback startOnRenderCallback =
|
|
nullptr,
|
|
NativeAnimatedNodesManager::StopOnRenderCallback stopOnRenderCallback =
|
|
nullptr);
|
|
std::shared_ptr<NativeAnimatedNodesManager> getOrCreate(
|
|
jsi::Runtime& runtime);
|
|
void addEventEmitterListener(
|
|
const std::shared_ptr<EventEmitterListener>& listener);
|
|
std::shared_ptr<EventEmitterListener> getEventEmitterListener();
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/AnimationDriver.h}:
|
|
namespace facebook::react {
|
|
enum class AnimationDriverType {
|
|
Frames,
|
|
Spring,
|
|
Decay,
|
|
};
|
|
class AnimationDriver {
|
|
public:
|
|
AnimationDriver(
|
|
int id,
|
|
Tag animatedValueTag,
|
|
std::optional<AnimationEndCallback> endCallback,
|
|
folly::dynamic config,
|
|
NativeAnimatedNodesManager* manager);
|
|
virtual ~AnimationDriver() = default;
|
|
void startAnimation();
|
|
void stopAnimation(bool ignoreCompletedHandlers = false);
|
|
inline int getId() const noexcept {
|
|
return id_;
|
|
}
|
|
inline Tag getAnimatedValueTag() const noexcept {
|
|
return animatedValueTag_;
|
|
}
|
|
bool getIsComplete() const noexcept {
|
|
return isComplete_;
|
|
}
|
|
void runAnimationStep(double renderingTime);
|
|
virtual void updateConfig(folly::dynamic config);
|
|
static std::optional<AnimationDriverType> getDriverTypeByName(
|
|
const std::string& driverTypeName);
|
|
|
|
protected:
|
|
virtual bool update(double, bool) {
|
|
return true;
|
|
}
|
|
void markNodeUpdated(Tag tag) {
|
|
manager_->updatedNodeTags_.insert(tag);
|
|
}
|
|
std::optional<AnimationEndCallback> endCallback_;
|
|
int id_{0};
|
|
Tag animatedValueTag_{};
|
|
int iterations_{0};
|
|
NativeAnimatedNodesManager* manager_;
|
|
bool isComplete_{false};
|
|
int currentIteration_{0};
|
|
double startFrameTimeMs_{-1};
|
|
bool isStarted_{false};
|
|
bool ignoreCompletedHandlers_{false};
|
|
folly::dynamic config_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/AnimationDriverUtils.h}:
|
|
namespace facebook::react {
|
|
static constexpr std::string_view ExtrapolateTypeIdentity = "identity";
|
|
static constexpr std::string_view ExtrapolateTypeClamp = "clamp";
|
|
static constexpr std::string_view ExtrapolateTypeExtend = "extend";
|
|
static constexpr double SingleFrameIntervalMs = 1000.0 / 60.0;
|
|
static constexpr double TicksPerMs = 10000.0;
|
|
inline double interpolate(
|
|
double inputValue,
|
|
double inputMin,
|
|
double inputMax,
|
|
double outputMin,
|
|
double outputMax,
|
|
std::string_view extrapolateLeft,
|
|
std::string_view extrapolateRight) {
|
|
auto result = inputValue;
|
|
if (result < inputMin) {
|
|
if (extrapolateLeft == ExtrapolateTypeIdentity) {
|
|
return result;
|
|
} else if (extrapolateLeft == ExtrapolateTypeClamp) {
|
|
result = inputMin;
|
|
}
|
|
}
|
|
if (result > inputMax) {
|
|
if (extrapolateRight == ExtrapolateTypeIdentity) {
|
|
return result;
|
|
} else if (extrapolateRight == ExtrapolateTypeClamp) {
|
|
result = inputMax;
|
|
}
|
|
}
|
|
if (inputMin == inputMax) {
|
|
if (inputValue <= inputMin) {
|
|
return outputMin;
|
|
}
|
|
return outputMax;
|
|
}
|
|
return outputMin +
|
|
(outputMax - outputMin) * (result - inputMin) / (inputMax - inputMin);
|
|
}
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/DecayAnimationDriver.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/AnimationDriver.h}
|
|
|
|
namespace facebook::react {
|
|
class DecayAnimationDriver : public AnimationDriver {
|
|
public:
|
|
DecayAnimationDriver(
|
|
int id,
|
|
Tag animatedValueTag,
|
|
std::optional<AnimationEndCallback> endCallback,
|
|
folly::dynamic config,
|
|
NativeAnimatedNodesManager* manager);
|
|
|
|
protected:
|
|
bool update(double timeDeltaMs, bool restarting) override;
|
|
};
|
|
double deceleration_{0};
|
|
std::optional<double> fromValue_{std::nullopt};
|
|
std::optional<double> lastValue_{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/FrameAnimationDriver.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/AnimationDriver.h}
|
|
|
|
namespace facebook::react {
|
|
class FrameAnimationDriver : public AnimationDriver {
|
|
public:
|
|
FrameAnimationDriver(
|
|
int id,
|
|
Tag animatedValueTag,
|
|
std::optional<AnimationEndCallback> endCallback,
|
|
folly::dynamic config,
|
|
NativeAnimatedNodesManager* manager);
|
|
|
|
protected:
|
|
bool update(double timeDeltaMs, bool restarting) override;
|
|
void updateConfig(folly::dynamic config) override;
|
|
};
|
|
double toValue_{0};
|
|
std::optional<double> startValue_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/SpringAnimationDriver.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/drivers/AnimationDriver.h}
|
|
|
|
namespace facebook::react {
|
|
class SpringAnimationDriver : public AnimationDriver {
|
|
public:
|
|
SpringAnimationDriver(
|
|
int id,
|
|
Tag animatedValueTag,
|
|
std::optional<AnimationEndCallback> endCallback,
|
|
folly::dynamic config,
|
|
NativeAnimatedNodesManager* manager);
|
|
|
|
protected:
|
|
bool update(double timeDeltaMs, bool restarting) override;
|
|
};
|
|
double springDamping_{0};
|
|
double springMass_{0};
|
|
double initialVelocity_{0};
|
|
std::optional<double> fromValue_{std::nullopt};
|
|
double endValue_{0};
|
|
double restSpeedThreshold_{0};
|
|
double displacementFromRestThreshold_{0};
|
|
bool overshootClampingEnabled_{false};
|
|
double lastTime_{0};
|
|
double timeAccumulator_{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/event_drivers/EventAnimationDriver.h}:
|
|
namespace facebook::react {
|
|
class EventAnimationDriver {
|
|
public:
|
|
EventAnimationDriver(
|
|
const std::vector<std::string>& eventPath,
|
|
Tag animatedValueTag);
|
|
~EventAnimationDriver() = default;
|
|
std::optional<double> getValueFromPayload(const EventPayload& eventPayload);
|
|
Tag getAnimatedNodeTag() const {
|
|
return animatedValueTag_;
|
|
}
|
|
|
|
protected:
|
|
std::vector<std::string> eventPath_;
|
|
Tag animatedValueTag_;
|
|
};
|
|
struct EventAnimationDriverKey {
|
|
Tag viewTag;
|
|
std::string eventName;
|
|
bool operator==(
|
|
const facebook::react::EventAnimationDriverKey& rhs) const noexcept {
|
|
return viewTag == rhs.viewTag && eventName == rhs.eventName;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
namespace std {
|
|
template <>
|
|
struct hash<facebook::react::EventAnimationDriverKey> {
|
|
size_t operator()(const facebook::react::EventAnimationDriverKey& key) const {
|
|
return std::hash<facebook::react::Tag>()(key.viewTag) ^
|
|
std::hash<std::string>()(key.eventName);
|
|
}
|
|
};
|
|
} // namespace std
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AdditionAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class AdditionAnimatedNode final : public OperatorAnimatedNode {
|
|
public:
|
|
AdditionAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager)
|
|
: OperatorAnimatedNode(tag, config, manager) {}
|
|
void update() override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}:
|
|
namespace facebook::react {
|
|
enum class AnimatedNodeType {
|
|
Style,
|
|
Value,
|
|
Props,
|
|
Interpolation,
|
|
Addition,
|
|
Subtraction,
|
|
Division,
|
|
Multiplication,
|
|
Modulus,
|
|
Diffclamp,
|
|
Transform,
|
|
Tracking,
|
|
Color,
|
|
Round,
|
|
};
|
|
class AnimatedNode {
|
|
public:
|
|
AnimatedNode(
|
|
Tag tag,
|
|
folly::dynamic config,
|
|
NativeAnimatedNodesManager& manager,
|
|
AnimatedNodeType type);
|
|
virtual ~AnimatedNode() = default;
|
|
AnimatedNode(AnimatedNode&&) noexcept = default;
|
|
AnimatedNode& operator=(AnimatedNode&&) noexcept = default;
|
|
AnimatedNode(const AnimatedNode&) = default;
|
|
AnimatedNode& operator=(const AnimatedNode&) = default;
|
|
Tag tag() const noexcept {
|
|
return tag_;
|
|
}
|
|
void addChild(Tag tag);
|
|
void removeChild(Tag tag);
|
|
const std::unordered_set<Tag>& getChildren() const noexcept {
|
|
return children_;
|
|
}
|
|
AnimatedNodeType type() const noexcept {
|
|
return type_;
|
|
}
|
|
const folly::dynamic& getConfig() const noexcept {
|
|
return config_;
|
|
}
|
|
virtual void update() {}
|
|
virtual void onDetachedFromNode(Tag) {}
|
|
virtual void onAttachToNode(Tag) {}
|
|
static std::optional<AnimatedNodeType> getNodeTypeByName(
|
|
const std::string& nodeTypeName);
|
|
int activeIncomingNodes = 0;
|
|
int bfsColor = 0;
|
|
static constexpr int INITIAL_BFS_COLOR = 0;
|
|
|
|
protected:
|
|
AnimatedNode* getChildNode(Tag tag);
|
|
Tag tag_{0};
|
|
NativeAnimatedNodesManager* manager_;
|
|
AnimatedNodeType type_;
|
|
std::unordered_set<Tag> children_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/ColorAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
class ColorAnimatedNode final : public AnimatedNode {
|
|
public:
|
|
ColorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void update() override;
|
|
Color getColor();
|
|
};
|
|
Tag gNodeTag_{};
|
|
Tag bNodeTag_{};
|
|
Tag aNodeTag_{};
|
|
Color color_{0};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/DiffClampAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class DiffClampAnimatedNode final : public ValueAnimatedNode {
|
|
public:
|
|
DiffClampAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void update() override;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/DivisionAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class DivisionAnimatedNode final : public OperatorAnimatedNode {
|
|
public:
|
|
DivisionAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager)
|
|
: OperatorAnimatedNode(tag, config, manager) {}
|
|
void update() override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/InterpolationAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class InterpolationAnimatedNode final : public ValueAnimatedNode {
|
|
public:
|
|
InterpolationAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void update() override;
|
|
void onDetachedFromNode(Tag animatedNodeTag) override;
|
|
void onAttachToNode(Tag animatedNodeTag) override;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/ModulusAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class ModulusAnimatedNode final : public ValueAnimatedNode {
|
|
public:
|
|
ModulusAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void update() override;
|
|
};
|
|
double modulus_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/MultiplicationAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class MultiplicationAnimatedNode final : public OperatorAnimatedNode {
|
|
public:
|
|
MultiplicationAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager)
|
|
: OperatorAnimatedNode(tag, config, manager) {}
|
|
void update() override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/PropsAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
class PropsAnimatedNode final : public AnimatedNode {
|
|
public:
|
|
PropsAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void connectToView(Tag viewTag);
|
|
void disconnectFromView(Tag viewTag);
|
|
void restoreDefaultValues();
|
|
Tag connectedViewTag() const {
|
|
return connectedViewTag_;
|
|
}
|
|
folly::dynamic props() {
|
|
std::lock_guard<std::mutex> lock(propsMutex_);
|
|
return props_;
|
|
}
|
|
void update() override;
|
|
void update(bool forceFabricCommit);
|
|
};
|
|
Tag connectedViewTag_{animated::undefinedAnimatedNodeIdentifier};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/RoundAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
namespace facebook::react {
|
|
class RoundAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
RoundAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void update() override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/StyleAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
class StyleAnimatedNode final : public AnimatedNode {
|
|
public:
|
|
StyleAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void collectViewUpdates(folly::dynamic& props);
|
|
bool isLayoutStyleUpdated() const noexcept {
|
|
return layoutStyleUpdated_;
|
|
}
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/SubtractionAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
namespace facebook::react {
|
|
class SubtractionAnimatedNode final : public OperatorAnimatedNode {
|
|
public:
|
|
SubtractionAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager)
|
|
: OperatorAnimatedNode(tag, config, manager) {}
|
|
void update() override;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/TrackingAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
|
|
namespace facebook::react {
|
|
class TrackingAnimatedNode final : public AnimatedNode {
|
|
public:
|
|
TrackingAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void update() override;
|
|
};
|
|
Tag toValueNodeId_{};
|
|
Tag valueNodeId_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/TransformAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
|
|
namespace facebook::react {
|
|
struct TransformConfig {
|
|
public:
|
|
std::string property;
|
|
Tag nodeTag;
|
|
double value;
|
|
};
|
|
class TransformAnimatedNode final : public AnimatedNode {
|
|
public:
|
|
TransformAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
void collectViewUpdates(folly::dynamic& props);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/ValueAnimatedNode.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/renderer/animated/nodes/AnimatedNode.h}
|
|
namespace facebook::react {
|
|
using ValueListenerCallback = std::function<void(double)>;
|
|
class ValueAnimatedNode : public AnimatedNode {
|
|
public:
|
|
ValueAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
double getValue() const noexcept;
|
|
double getRawValue() const noexcept;
|
|
bool setRawValue(double value) noexcept;
|
|
double getOffset() const noexcept;
|
|
bool setOffset(double offset) noexcept;
|
|
void flattenOffset() noexcept;
|
|
void extractOffset() noexcept;
|
|
void setValueListener(ValueListenerCallback&& callback) noexcept;
|
|
bool getIsColorValue() const noexcept {
|
|
return isColorValue_;
|
|
}
|
|
|
|
protected:
|
|
bool isColorValue_{false};
|
|
};
|
|
double offset_{0.0};
|
|
ValueListenerCallback valueListener_{};
|
|
};
|
|
class OperatorAnimatedNode : public ValueAnimatedNode {
|
|
public:
|
|
OperatorAnimatedNode(
|
|
Tag tag,
|
|
const folly::dynamic& config,
|
|
NativeAnimatedNodesManager& manager);
|
|
|
|
protected:
|
|
std::vector<Tag> inputNodes_{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/primitives.h}:
|
|
namespace facebook::react::animated {
|
|
constexpr static Tag undefinedAnimatedNodeIdentifier = 0;
|
|
}
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/animated/tests/AnimationTestsBase.h}:
|
|
namespace facebook::react {
|
|
class AnimationTestsBase : public testing::Test {
|
|
public:
|
|
AnimationTestsBase() = default;
|
|
|
|
protected:
|
|
void initNodesManager() noexcept {
|
|
nodesManager_.reset();
|
|
nodesManager_ = std::make_shared<NativeAnimatedNodesManager>(
|
|
[this](Tag reactTag, const folly::dynamic& changedProps) {
|
|
lastUpdatedNodeTag = reactTag;
|
|
lastCommittedProps = changedProps;
|
|
},
|
|
[this](const std::unordered_map<Tag, folly::dynamic>& nodesProps) {
|
|
if (!nodesProps.empty()) {
|
|
lastUpdatedNodeTag = nodesProps.begin()->first;
|
|
lastCommittedProps = nodesProps.begin()->second;
|
|
}
|
|
});
|
|
}
|
|
bool nodeNeedsUpdate(Tag nodeTag) const {
|
|
return nodesManager_->updatedNodeTags_.contains(nodeTag);
|
|
}
|
|
void runAnimationFrame(double timestamp) {
|
|
nodesManager_->onAnimationFrame(timestamp);
|
|
}
|
|
std::shared_ptr<NativeAnimatedNodesManager> nodesManager_;
|
|
folly::dynamic lastCommittedProps{folly::dynamic::object()};
|
|
Tag lastUpdatedNodeTag{};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SchedulerDelegateImpl.h}:
|
|
namespace facebook::react {
|
|
class SchedulerDelegateImpl : public SchedulerDelegate {
|
|
public:
|
|
SchedulerDelegateImpl(
|
|
std::shared_ptr<IMountingManager> mountingManager) noexcept;
|
|
~SchedulerDelegateImpl() noexcept override = default;
|
|
SchedulerDelegateImpl(SchedulerDelegateImpl&&) noexcept = default;
|
|
SchedulerDelegateImpl& operator=(SchedulerDelegateImpl&&) noexcept = default;
|
|
SchedulerDelegateImpl(const SchedulerDelegateImpl&) = delete;
|
|
SchedulerDelegateImpl& operator=(const SchedulerDelegateImpl&) = delete;
|
|
};
|
|
}; // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/scheduler/SurfaceDelegate.h}:
|
|
namespace facebook::react {
|
|
class SurfaceDelegate {
|
|
public:
|
|
virtual ~SurfaceDelegate() = default;
|
|
virtual void createContentView(std::string appKey) = 0;
|
|
virtual bool isContentViewReady() = 0;
|
|
virtual void destroyContentView() = 0;
|
|
virtual void show() = 0;
|
|
virtual void hide() = 0;
|
|
virtual bool isShowing() = 0;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/renderer/uimanager/IMountingManager.h}:
|
|
namespace facebook::react {
|
|
using SchedulerTask = std::function<void(Scheduler& scheduler)>;
|
|
using SchedulerTaskExecutor = std::function<void(SchedulerTask&& task)>;
|
|
using EventEmitterListener = std::function<bool(
|
|
Tag eventTarget,
|
|
const std::string& eventType,
|
|
const EventPayload& eventPayload)>;
|
|
class IMountingManager {
|
|
public:
|
|
IMountingManager() noexcept = default;
|
|
virtual ~IMountingManager() noexcept = default;
|
|
IMountingManager(IMountingManager&&) noexcept = default;
|
|
IMountingManager& operator=(IMountingManager&&) noexcept = default;
|
|
IMountingManager(const IMountingManager&) = delete;
|
|
IMountingManager& operator=(const IMountingManager&) = delete;
|
|
virtual void executeMount(
|
|
SurfaceId surfaceId,
|
|
MountingTransaction&& mountingTransaction) = 0;
|
|
virtual void dispatchCommand(
|
|
const ShadowView& shadowView,
|
|
const std::string& commandName,
|
|
const folly::dynamic& args) = 0;
|
|
virtual void setIsJSResponder(
|
|
const ShadowView& shadowView,
|
|
bool isJSResponder,
|
|
bool blockNativeResponder) {};
|
|
virtual void synchronouslyUpdateViewOnUIThread(
|
|
Tag reactTag,
|
|
const folly::dynamic& changedProps) {};
|
|
virtual void onUpdateShadowTree(
|
|
const std::unordered_map<Tag, folly::dynamic>& tagToProps) {};
|
|
virtual void initializeAccessibilityManager() {};
|
|
virtual void setAccessibilityFocusedView(Tag viewTag) {};
|
|
virtual void setFocusedView(Tag viewTag) {};
|
|
virtual void clearAccessibilityFocusedView(Tag viewTag) {};
|
|
virtual void accessibleClickAction(Tag viewTag) {};
|
|
virtual void accessibleScrollInDirection(Tag viewTag, int direction) {};
|
|
virtual void accessibleSetText(Tag viewTag, const std::string& text) {};
|
|
virtual void clearFocusedView(Tag viewTag) {};
|
|
virtual void setAfterMountCallback(
|
|
std::function<void(SurfaceId)>&& onAfterMount) {};
|
|
virtual ComponentRegistryFactory getComponentRegistryFactory() {
|
|
return nullptr;
|
|
}
|
|
virtual bool hasComponent(const std::string&) {
|
|
return false;
|
|
}
|
|
virtual void setSchedulerTaskExecutor(
|
|
SchedulerTaskExecutor&& schedulerTaskExecutor) noexcept {};
|
|
virtual void setEventEmitterListener(
|
|
std::shared_ptr<EventEmitterListener> listener) noexcept {};
|
|
virtual void setUIManager(std::weak_ptr<UIManager> uiManager) noexcept {};
|
|
virtual std::shared_ptr<IImageLoader> getImageLoader() noexcept {
|
|
return nullptr;
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/runtime/ReactHost.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/runtime/ReactInstanceConfig.h}
|
|
namespace facebook::react {
|
|
class ReactHost {
|
|
public:
|
|
ReactHost(
|
|
ReactInstanceConfig reactInstanceConfig,
|
|
std::shared_ptr<IMountingManager> mountingManager,
|
|
std::shared_ptr<RunLoopObserverManager> runLoopObserverManager,
|
|
std::shared_ptr<const ContextContainer> contextContainer,
|
|
JsErrorHandler::OnJsError onJsError,
|
|
Logger logger,
|
|
std::shared_ptr<IDevUIDelegate> devUIDelegate = nullptr,
|
|
TurboModuleManagerDelegates turboModuleManagerDelegates = {},
|
|
std::shared_ptr<SurfaceDelegate> logBoxSurfaceDelegate = nullptr,
|
|
std::shared_ptr<NativeAnimatedNodesManagerProvider>
|
|
animatedNodesManagerProvider = nullptr,
|
|
ReactInstance::BindingsInstallFunc bindingsInstallFunc = nullptr);
|
|
ReactHost(const ReactHost&) = delete;
|
|
ReactHost& operator=(const ReactHost&) = delete;
|
|
ReactHost(ReactHost&&) noexcept = delete;
|
|
ReactHost& operator=(ReactHost&&) noexcept = delete;
|
|
~ReactHost() noexcept;
|
|
bool loadScript(
|
|
const std::string& bundlePath,
|
|
const std::string& sourcePath) noexcept;
|
|
void startSurface(
|
|
SurfaceId surfaceId,
|
|
const std::string& moduleName,
|
|
const folly::dynamic& initialProps,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext = {}) noexcept;
|
|
void setSurfaceConstraints(
|
|
SurfaceId surfaceId,
|
|
const LayoutConstraints& layoutConstraints,
|
|
const LayoutContext& layoutContext) noexcept;
|
|
void stopSurface(SurfaceId surfaceId) noexcept;
|
|
void stopAllSurfaces() noexcept;
|
|
bool isSurfaceRunning(SurfaceId surfaceId) const noexcept;
|
|
std::unordered_set<SurfaceId> getRunningSurfaces() const noexcept;
|
|
void runOnScheduler(std::function<void(Scheduler& scheduler)>&& task) const;
|
|
void runOnRuntimeScheduler(
|
|
std::function<void(jsi::Runtime& runtime)>&& task,
|
|
SchedulerPriority priority =
|
|
SchedulerPriority::NormalPriority) const noexcept;
|
|
void emitDeviceEvent(folly::dynamic&& args);
|
|
};
|
|
std::unique_ptr<SchedulerDelegate> schedulerDelegate_;
|
|
std::unique_ptr<Scheduler> scheduler_;
|
|
std::unique_ptr<SurfaceManager> surfaceManager_;
|
|
std::shared_ptr<DevServerHelper> devServerHelper_;
|
|
std::shared_ptr<Inspector> inspector_;
|
|
std::unique_ptr<PackagerConnection> packagerConnection_;
|
|
std::shared_ptr<AnimatedMountingOverrideDelegate>
|
|
animatedMountingOverrideDelegate_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/runtime/ReactInstanceConfig.h}:
|
|
namespace facebook::react {
|
|
struct ReactInstanceConfig {
|
|
bool enableDebugging{false};
|
|
std::string appId;
|
|
std::string deviceName;
|
|
std::string devServerHost{"localhost"};
|
|
uint32_t devServerPort{8081};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/runtime/platform/cxx/react/runtime/PlatformTimerRegistryImpl.h}:
|
|
namespace facebook::react {
|
|
class PlatformTimerRegistryImpl : public PlatformTimerRegistry {
|
|
public:
|
|
PlatformTimerRegistryImpl() noexcept = default;
|
|
PlatformTimerRegistryImpl(const PlatformTimerRegistryImpl&) = delete;
|
|
PlatformTimerRegistryImpl& operator=(const PlatformTimerRegistryImpl&) =
|
|
delete;
|
|
PlatformTimerRegistryImpl(PlatformTimerRegistryImpl&&) noexcept = delete;
|
|
PlatformTimerRegistryImpl& operator=(PlatformTimerRegistryImpl&&) noexcept =
|
|
delete;
|
|
~PlatformTimerRegistryImpl() noexcept override;
|
|
void createTimer(uint32_t timerId, double delayMs) override;
|
|
void deleteTimer(uint32_t timerId) override;
|
|
void createRecurringTimer(uint32_t timerID, double delayMs) override;
|
|
void setTimerManager(std::weak_ptr<TimerManager> timerManager);
|
|
};
|
|
double durationMs{0.0};
|
|
bool isRecurring{false};
|
|
};
|
|
TaskDispatchThread taskDispatchThread_{"PlatformTimerRegistry"};
|
|
std::weak_ptr<TimerManager> timerManager_;
|
|
std::unordered_map<uint32_t, Timer> timers_;
|
|
std::mutex timersMutex_;
|
|
void createTimerInternal(
|
|
uint32_t timerID,
|
|
double delayMs,
|
|
bool isRecurring = false);
|
|
void startTimer(uint32_t timerId, double delayMs);
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/threading/MessageQueueThreadImpl.h}:
|
|
namespace facebook::react {
|
|
using MessageQueueThreadFactory =
|
|
std::function<std::shared_ptr<MessageQueueThread>()>;
|
|
constexpr char MessageQueueThreadFactoryKey[] = "MessageQueueThreadFactoryKey";
|
|
class MessageQueueThreadImpl : public MessageQueueThread {
|
|
public:
|
|
MessageQueueThreadImpl() noexcept = default;
|
|
explicit MessageQueueThreadImpl(int priorityOffset) noexcept
|
|
: taskDispatchThread_("MessageQueue", priorityOffset) {}
|
|
~MessageQueueThreadImpl() noexcept override = default;
|
|
void runOnQueue(std::function<void()>&& runnable) override;
|
|
void runOnQueueSync(std::function<void()>&& runnable) override;
|
|
void quitSynchronous() override;
|
|
};
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/threading/TaskDispatchThread.h}:
|
|
namespace facebook::react {
|
|
class TaskDispatchThread {
|
|
public:
|
|
using TaskFn = std::function<void()>;
|
|
using TimePoint = std::chrono::time_point<std::chrono::system_clock>;
|
|
TaskDispatchThread(
|
|
std::string threadName = "",
|
|
int priorityOffset = 0) noexcept;
|
|
~TaskDispatchThread() noexcept;
|
|
bool isOnThread() noexcept;
|
|
bool isRunning() noexcept;
|
|
void runAsync(
|
|
TaskFn&& task,
|
|
std::chrono::milliseconds delayMs =
|
|
std::chrono::milliseconds::zero()) noexcept;
|
|
void runSync(TaskFn&& task) noexcept;
|
|
void quit() noexcept;
|
|
|
|
protected:
|
|
struct Task {
|
|
TimePoint dispatchTime;
|
|
TaskFn fn;
|
|
Task(TimePoint dispatchTime, TaskFn&& fn)
|
|
: dispatchTime(dispatchTime), fn(std::move(fn)) {}
|
|
bool operator<(const Task& other) const {
|
|
return dispatchTime > other.dispatchTime;
|
|
}
|
|
};
|
|
void loop() noexcept;
|
|
std::mutex queueLock_;
|
|
std::condition_variable loopCv_;
|
|
std::priority_queue<Task> queue_;
|
|
std::atomic<bool> running_{true};
|
|
std::string threadName_;
|
|
std::thread thread_;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/utils/PlatformRunLoopObserver.h}:
|
|
namespace facebook::react {
|
|
class PlatformRunLoopObserver : public RunLoopObserver {
|
|
public:
|
|
PlatformRunLoopObserver(
|
|
RunLoopObserver::Activity activities,
|
|
const RunLoopObserver::WeakOwner& owner)
|
|
: RunLoopObserver(activities, owner) {}
|
|
~PlatformRunLoopObserver() override = default;
|
|
PlatformRunLoopObserver(PlatformRunLoopObserver& other) = delete;
|
|
PlatformRunLoopObserver& operator=(PlatformRunLoopObserver& other) = delete;
|
|
PlatformRunLoopObserver(PlatformRunLoopObserver&& other) = delete;
|
|
PlatformRunLoopObserver& operator=(PlatformRunLoopObserver&& other) = delete;
|
|
bool isOnRunLoopThread() const noexcept override {
|
|
return false;
|
|
}
|
|
void onRender() const noexcept {
|
|
if (auto owner = owner_.lock()) {
|
|
activityDidChange(activities_);
|
|
}
|
|
}
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/ReactCxxPlatform/react/utils/RunLoopObserverManager.h}:
|
|
/// @dep {packages/react-native/ReactCxxPlatform/react/utils/PlatformRunLoopObserver.h}
|
|
namespace facebook::react {
|
|
class RunLoopObserverManager
|
|
: std::enable_shared_from_this<RunLoopObserverManager> {
|
|
public:
|
|
std::unique_ptr<EventBeat> createEventBeat(
|
|
std::shared_ptr<EventBeat::OwnerBox> ownerBox,
|
|
RuntimeScheduler& runtimeScheduler);
|
|
void onRender() const noexcept;
|
|
void induce() const noexcept;
|
|
};
|
|
} // namespace facebook::react
|
|
|
|
/// @src {packages/react-native/scripts/ios-prebuild/React-umbrella.h}:
|
|
extern "C" double ReactVersionNumber;
|
|
extern "C" const unsigned char ReactVersionString[];
|
|
|
|
/// @src {packages/react-native/scripts/ios-prebuild/React_RCTAppDelegate-umbrella.h}:
|
|
extern "C" double React_RCTAppDelegateVersionNumber;
|
|
extern "C" const unsigned char React_RCTAppDelegateVersionString[];
|