From da9bc1692b829ece3ff9cd3af270ab3710908757 Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Mon, 8 Jan 2024 16:18:09 -0800 Subject: [PATCH 01/16] integrate c464b215e --- .../react-native-win32-tester/overrides.json | 2 +- .../react-native-win32-tester/package.json | 4 +- .../react-native-win32/overrides.json | 10 +- .../react-native-win32/package.json | 18 +- .../Components/TextInput/TextInput.win32.js | 20 +- .../src/Libraries/Image/Image.win32.js | 9 +- .../Libraries/Inspector/Inspector.win32.js | 7 +- .../react-native-win32/src/index.win32.js | 13 +- .../automation-channel/package.json | 2 +- .../tester/overrides.json | 4 +- .../@react-native-windows/tester/package.json | 4 +- .../TextInput/TextInputExample.windows.js | 16 +- .../@react-native/monorepo/overrides.json | 2 +- .../tester/js/RNTesterAppShared.js | 62 +- .../TextInput/TextInputExample.android.js | 16 +- .../NativeCxxModuleExampleExample.js | 30 +- .../js/utils/RNTesterNavigationReducer.js | 9 + .../tester/js/utils/testerStateUtils.js | 11 +- packages/@react-native/tester/overrides.json | 10 +- packages/e2e-test-app-fabric/package.json | 2 +- packages/e2e-test-app/package.json | 2 +- packages/integration-test-app/package.json | 2 +- packages/playground/package.json | 2 +- packages/sample-apps/package.json | 2 +- .../Fabric/AbiViewComponentDescriptor.cpp | 22 +- .../Fabric/AbiViewComponentDescriptor.h | 5 +- .../CompositionViewComponentView.cpp | 2 +- .../WindowsTextInputComponentDescriptor.h | 224 +++-- .../TextInput/WindowsTextInputState.cpp | 40 - .../TextInput/WindowsTextInputState.h | 2 + .../view/YogaLayoutableShadowNode.cpp | 167 ++-- .../components/view/YogaStylableProps.cpp | 401 ++++---- .../renderer/components/view/conversions.h | 894 ------------------ .../react/renderer/graphics/Color.h | 67 -- .../renderer/uimanager/UIManagerBinding.cpp | 49 +- .../yoga/yoga/enums/YogaEnums.h | 51 +- .../yoga/yoga/node/Node.cpp | 689 -------------- .../yoga/yoga/node/Node.h | 15 +- vnext/ReactCommon/Yoga.cpp | 46 +- .../codegen/NativeImageLoaderAndroidSpec.g.h | 33 +- .../components/rnwcore/ComponentDescriptors.h | 2 +- .../components/rnwcore/EventEmitters.cpp | 2 +- .../react/components/rnwcore/EventEmitters.h | 14 +- .../react/components/rnwcore/Props.cpp | 14 +- .../codegen/react/components/rnwcore/Props.h | 20 +- .../react/components/rnwcore/ShadowNodes.cpp | 2 +- .../react/components/rnwcore/ShadowNodes.h | 22 +- .../codegen/react/components/rnwcore/States.h | 30 +- vnext/codegen/rnwcoreJSI.h | 47 +- vnext/overrides.json | 90 +- vnext/package.json | 18 +- .../Components/TextInput/TextInput.windows.js | 20 +- vnext/src/Libraries/Image/Image.windows.js | 9 +- vnext/src/index.windows.js | 13 +- yarn.lock | 130 +-- 55 files changed, 1002 insertions(+), 2397 deletions(-) delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/conversions.h delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/graphics/Color.h delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.cpp diff --git a/packages/@office-iss/react-native-win32-tester/overrides.json b/packages/@office-iss/react-native-win32-tester/overrides.json index 2c097d7ffb1..33ded5a9ade 100644 --- a/packages/@office-iss/react-native-win32-tester/overrides.json +++ b/packages/@office-iss/react-native-win32-tester/overrides.json @@ -5,7 +5,7 @@ "excludePatterns": [ "src/js/examples-win32/**" ], - "baseVersion": "0.74.0-nightly-20231116-fa89dd68b", + "baseVersion": "0.74.0-nightly-20231124-c464b215e", "overrides": [ { "type": "patch", diff --git a/packages/@office-iss/react-native-win32-tester/package.json b/packages/@office-iss/react-native-win32-tester/package.json index 9626a7af002..4dfb9b44238 100644 --- a/packages/@office-iss/react-native-win32-tester/package.json +++ b/packages/@office-iss/react-native-win32-tester/package.json @@ -19,7 +19,7 @@ "peerDependencies": { "@office-iss/react-native-win32": "^0.0.0-canary.225", "react": "18.0.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b" + "react-native": "0.74.0-nightly-20231124-c464b215e" }, "devDependencies": { "@office-iss/react-native-win32": "^0.0.0-canary.225", @@ -30,7 +30,7 @@ "@types/node": "^18.0.0", "eslint": "^8.19.0", "just-scripts": "^1.3.3", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-platform-override": "^1.9.17", "typescript": "^4.9.5" }, diff --git a/packages/@office-iss/react-native-win32/overrides.json b/packages/@office-iss/react-native-win32/overrides.json index 600f1718546..c69d132b08b 100644 --- a/packages/@office-iss/react-native-win32/overrides.json +++ b/packages/@office-iss/react-native-win32/overrides.json @@ -7,7 +7,7 @@ "**/__snapshots__/**", "src/rntypes/**" ], - "baseVersion": "0.74.0-nightly-20231116-fa89dd68b", + "baseVersion": "0.74.0-nightly-20231124-c464b215e", "overrides": [ { "type": "derived", @@ -19,7 +19,7 @@ "type": "derived", "file": "src/index.win32.js", "baseFile": "packages/react-native/index.js", - "baseHash": "b658f287732c27fdd28722a8765c3b1b0c1316fa" + "baseHash": "6c91f268c2189f9db74bead7fef1ed262c77586e" }, { "type": "platform", @@ -130,7 +130,7 @@ "type": "derived", "file": "src/Libraries/Components/TextInput/TextInput.win32.js", "baseFile": "packages/react-native/Libraries/Components/TextInput/TextInput.js", - "baseHash": "d12fe54e9da3be0b1003a5bc18fa3c6d09728564" + "baseHash": "fa10fcf147f79ede6f3a49fac45faefed48e1693" }, { "type": "patch", @@ -252,7 +252,7 @@ "type": "derived", "file": "src/Libraries/Image/Image.win32.js", "baseFile": "packages/react-native/Libraries/Image/Image.ios.js", - "baseHash": "bccd20ad47baa18b187bd8eb92b7627135be29fd", + "baseHash": "ba2c259fd454ed0c0f73b82f6390fef8045320ab", "issue": 4320 }, { @@ -306,7 +306,7 @@ "type": "patch", "file": "src/Libraries/Inspector/Inspector.win32.js", "baseFile": "packages/react-native/Libraries/Inspector/Inspector.js", - "baseHash": "03565787cbe09078824ee3fcfc12401085995454" + "baseHash": "db79965ed999c40d6bebaf1860a0921749d54b4f" }, { "type": "patch", diff --git a/packages/@office-iss/react-native-win32/package.json b/packages/@office-iss/react-native-win32/package.json index a9b956bc53d..665a848aec5 100644 --- a/packages/@office-iss/react-native-win32/package.json +++ b/packages/@office-iss/react-native-win32/package.json @@ -30,14 +30,14 @@ "@react-native-community/cli-platform-android": "12.0.0", "@react-native-community/cli-platform-ios": "12.0.0", "@react-native/assets": "1.0.0", - "@react-native/assets-registry": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/codegen": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/community-cli-plugin": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/gradle-plugin": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/js-polyfills": "0.74.0-nightly-20231116-fa89dd68b", + "@react-native/assets-registry": "0.74.0-nightly-20231124-c464b215e", + "@react-native/codegen": "0.74.0-nightly-20231124-c464b215e", + "@react-native/community-cli-plugin": "0.74.0-nightly-20231124-c464b215e", + "@react-native/gradle-plugin": "0.74.0-nightly-20231124-c464b215e", + "@react-native/js-polyfills": "0.74.0-nightly-20231124-c464b215e", "@react-native/metro-config": "^0.73.0", - "@react-native/normalize-colors": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/virtualized-lists": "0.74.0-nightly-20231116-fa89dd68b", + "@react-native/normalize-colors": "0.74.0-nightly-20231124-c464b215e", + "@react-native/virtualized-lists": "0.74.0-nightly-20231124-c464b215e", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", @@ -85,13 +85,13 @@ "just-scripts": "^1.3.3", "prettier": "^2.4.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-platform-override": "^1.9.17", "typescript": "^4.9.5" }, "peerDependencies": { "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b" + "react-native": "0.74.0-nightly-20231124-c464b215e" }, "beachball": { "defaultNpmTag": "canary", diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js b/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js index 856055b304a..09ddfa2f2e9 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js @@ -960,6 +960,12 @@ export type Props = $ReadOnly<{| */ selectionColor?: ?ColorValue, + /** + * The text selection handle color. + * @platform android + */ + selectionHandleColor?: ?ColorValue, + /** * If `true`, all text will automatically be selected on focus. */ @@ -1156,6 +1162,9 @@ function InternalTextInput(props: Props): React.Node { id, tabIndex, selection: propsSelection, + selectionColor, + selectionHandleColor, + cursorColor, ...otherProps } = props; @@ -1620,7 +1629,15 @@ function InternalTextInput(props: Props): React.Node { if (childCount > 1) { children = {children}; } - + // For consistency with iOS set cursor/selectionHandle color as selectionColor + const colorProps = { + selectionColor, + selectionHandleColor: + selectionHandleColor === undefined + ? selectionColor + : selectionHandleColor, + cursorColor: cursorColor === undefined ? selectionColor : cursorColor, + }; textInput = ( /* $FlowFixMe[prop-missing] the types for AndroidTextInput don't match up * exactly with the props for TextInput. This will need to get fixed */ @@ -1634,6 +1651,7 @@ function InternalTextInput(props: Props): React.Node { // $FlowFixMe[incompatible-type] - Figure out imperative + forward refs. ref={ref} {...otherProps} + {...colorProps} {...eventHandlers} accessibilityErrorMessage={accessibilityErrorMessage} accessibilityState={_accessibilityState} diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Image/Image.win32.js b/packages/@office-iss/react-native-win32/src/Libraries/Image/Image.win32.js index 41a84bfd1a0..1831dfc1fe3 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Image/Image.win32.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Image/Image.win32.js @@ -22,7 +22,10 @@ import {createRootTag} from '../ReactNative/RootTag'; import flattenStyle from '../StyleSheet/flattenStyle'; import StyleSheet from '../StyleSheet/StyleSheet'; import ImageAnalyticsTagContext from './ImageAnalyticsTagContext'; -import {unstable_getImageComponentDecorator} from './ImageInjection'; +import { + unstable_getImageComponentDecorator, + useWrapRefWithImageAttachedCallbacks, +} from './ImageInjection'; import {getImageSourcesFromImageProps} from './ImageSourceUtils'; import {convertObjectFitToResizeMode} from './ImageUtils'; import ImageViewNativeComponent from './ImageViewNativeComponent'; @@ -190,6 +193,8 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { }; const accessibilityLabel = props['aria-label'] ?? props.accessibilityLabel; + const actualRef = useWrapRefWithImageAttachedCallbacks(forwardedRef); + return ( // [Win32 @@ -209,7 +214,7 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { {...restProps} accessible={props.alt !== undefined ? true : props.accessible} accessibilityLabel={accessibilityLabel ?? props.alt} - ref={forwardedRef} + ref={actualRef} style={style} resizeMode={resizeMode} tintColor={tintColor} diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js b/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js index c8f87164da9..1bba357ed25 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js @@ -16,7 +16,6 @@ import type { } from '../Renderer/shims/ReactNativeTypes'; import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; import type {ReactDevToolsAgent} from '../Types/ReactDevToolsTypes'; -import type {HostRef} from './getInspectorDataForViewAtPoint'; const PressabilityDebug = require('../Pressability/PressabilityDebug'); const ReactNative = require('../Renderer/shims/ReactNative'); @@ -47,7 +46,7 @@ export type InspectedElement = $ReadOnly<{ export type ElementsHierarchy = InspectorData['hierarchy']; type Props = { - inspectedView: ?HostRef, + inspectedViewRef: React.RefObject | null>, onRequestRerenderApp: () => void, reactDevToolsAgent?: ReactDevToolsAgent, }; @@ -55,7 +54,7 @@ type Props = { const UIManager = require('../ReactNative/UIManager'); // [Win32] function Inspector({ - inspectedView, + inspectedViewRef, onRequestRerenderApp, reactDevToolsAgent, }: Props): React.Node { @@ -132,7 +131,7 @@ function Inspector({ // ]Win32 getInspectorDataForViewAtPoint( - inspectedView, + inspectedViewRef.current, locationX, locationY, viewData => { diff --git a/packages/@office-iss/react-native-win32/src/index.win32.js b/packages/@office-iss/react-native-win32/src/index.win32.js index 9ccafc1dc39..f4c6b17eb1d 100644 --- a/packages/@office-iss/react-native-win32/src/index.win32.js +++ b/packages/@office-iss/react-native-win32/src/index.win32.js @@ -294,7 +294,7 @@ module.exports = { 'pushNotificationIOS-moved', 'PushNotificationIOS has been extracted from react-native core and will be removed in a future release. ' + "It can now be installed and imported from '@react-native-community/push-notification-ios' instead of 'react-native'. " + - 'See https://github.com/react-native-push-notification-ios/push-notification-ios', + 'See https://github.com/react-native-push-notification/ios', ); return require('./Libraries/PushNotificationIOS/PushNotificationIOS'); }, @@ -467,7 +467,8 @@ if (__DEV__) { invariant( false, 'ART has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/art' instead of 'react-native'. " + + "Please upgrade to use either 'react-native-svg' or a similar package. " + + "If you cannot upgrade to a different library, please install the deprecated '@react-native-community/art' package. " + 'See https://github.com/react-native-art/art', ); }, @@ -547,7 +548,7 @@ if (__DEV__) { invariant( false, 'CameraRoll has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/cameraroll' instead of 'react-native'. " + + "It can now be installed and imported from '@react-native-camera-roll/camera-roll' instead of 'react-native'. " + 'See https://github.com/react-native-cameraroll/react-native-cameraroll', ); }, @@ -660,7 +661,7 @@ if (__DEV__) { invariant( false, 'SegmentedControlIOS has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/segmented-checkbox' instead of 'react-native'." + + "It can now be installed and imported from '@react-native-segmented-control/segmented-control' instead of 'react-native'." + 'See https://github.com/react-native-segmented-control/segmented-control', ); }, @@ -738,7 +739,7 @@ if (__DEV__) { invariant( false, 'MaskedViewIOS has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/react-native-masked-view' instead of 'react-native'. " + + "It can now be installed and imported from '@react-native-masked-view/masked-view' instead of 'react-native'. " + 'See https://github.com/react-native-masked-view/masked-view', ); }, @@ -768,7 +769,7 @@ if (__DEV__) { invariant( false, 'ImagePickerIOS has been removed from React Native. ' + - "Please upgrade to use either '@react-native-community/react-native-image-picker' or 'expo-image-picker'. " + + "Please upgrade to use either 'react-native-image-picker' or 'expo-image-picker'. " + "If you cannot upgrade to a different library, please install the deprecated '@react-native-community/image-picker-ios' package. " + 'See https://github.com/rnc-archive/react-native-image-picker-ios', ); diff --git a/packages/@react-native-windows/automation-channel/package.json b/packages/@react-native-windows/automation-channel/package.json index 9673487c03e..fa2175b3ef2 100644 --- a/packages/@react-native-windows/automation-channel/package.json +++ b/packages/@react-native-windows/automation-channel/package.json @@ -31,7 +31,7 @@ "just-scripts": "^1.3.2", "prettier": "^2.4.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749", "typescript": "^4.9.5" }, diff --git a/packages/@react-native-windows/tester/overrides.json b/packages/@react-native-windows/tester/overrides.json index 87925d42df1..0c0a7fcbcac 100644 --- a/packages/@react-native-windows/tester/overrides.json +++ b/packages/@react-native-windows/tester/overrides.json @@ -5,7 +5,7 @@ "excludePatterns": [ "src/js/examples-win/**" ], - "baseVersion": "0.74.0-nightly-20231116-fa89dd68b", + "baseVersion": "0.74.0-nightly-20231124-c464b215e", "overrides": [ { "type": "derived", @@ -38,7 +38,7 @@ "type": "patch", "file": "src/js/examples/TextInput/TextInputExample.windows.js", "baseFile": "packages/rn-tester/js/examples/TextInput/TextInputExample.android.js", - "baseHash": "528b850e74260e8059797a7fbf771ce8a07f27dd", + "baseHash": "0feb796c56462855789816350f23943b5a212b2e", "issue": 5688 }, { diff --git a/packages/@react-native-windows/tester/package.json b/packages/@react-native-windows/tester/package.json index 27e89b2da2b..d8dd812649a 100644 --- a/packages/@react-native-windows/tester/package.json +++ b/packages/@react-native-windows/tester/package.json @@ -18,7 +18,7 @@ "peerDependencies": { "@react-native-picker/picker": "2.4.10", "react": "18.0.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749", "react-native-xaml": "^0.0.50" }, @@ -31,7 +31,7 @@ "@types/node": "^18.0.0", "eslint": "^8.19.0", "just-scripts": "^1.3.3", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-platform-override": "^1.9.17", "react-native-windows": "^0.0.0-canary.749", "typescript": "^4.9.5" diff --git a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js index efe66204324..4d5430918e6 100644 --- a/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js +++ b/packages/@react-native-windows/tester/src/js/examples/TextInput/TextInputExample.windows.js @@ -306,11 +306,21 @@ const examples: Array = [ + + ); }, @@ -602,7 +612,7 @@ const examples: Array = [ 'next', ]; const returnKeyLabels = ['Compile', 'React Native']; - const examples = returnKeyTypes.map(type => { + const returnKeyExamples = returnKeyTypes.map(type => { return ( = [ }); return ( - {examples} + {returnKeyExamples} {types} ); diff --git a/packages/@react-native/monorepo/overrides.json b/packages/@react-native/monorepo/overrides.json index 18a9cf25246..8303ac5ed6d 100644 --- a/packages/@react-native/monorepo/overrides.json +++ b/packages/@react-native/monorepo/overrides.json @@ -1,5 +1,5 @@ { - "baseVersion": "0.74.0-nightly-20231116-fa89dd68b", + "baseVersion": "0.74.0-nightly-20231124-c464b215e", "overrides": [ { "type": "patch", diff --git a/packages/@react-native/tester/js/RNTesterAppShared.js b/packages/@react-native/tester/js/RNTesterAppShared.js index 04c17f58f32..27260cc901a 100644 --- a/packages/@react-native/tester/js/RNTesterAppShared.js +++ b/packages/@react-native/tester/js/RNTesterAppShared.js @@ -8,6 +8,8 @@ * @flow */ +import type {RNTesterModuleInfo} from './types/RNTesterTypes'; + import RNTesterModuleContainer from './components/RNTesterModuleContainer'; import RNTesterModuleList from './components/RNTesterModuleList'; import RNTesterNavBar, {navBarHeight} from './components/RNTesterNavbar'; @@ -24,11 +26,24 @@ import { initialNavigationState, } from './utils/testerStateUtils'; import * as React from 'react'; -import {BackHandler, StyleSheet, View, useColorScheme} from 'react-native'; +import { + BackHandler, + Linking, + StyleSheet, + View, + useColorScheme, +} from 'react-native'; // RNTester App currently uses in memory storage for storing navigation state -const RNTesterApp = (): React.Node => { +const RNTesterApp = ({ + testList, +}: { + testList?: { + components?: Array, + apis?: Array, + }, +}): React.Node => { const [state, dispatch] = React.useReducer( RNTesterNavigationReducer, initialNavigationState, @@ -44,8 +59,8 @@ const RNTesterApp = (): React.Node => { } = state; const examplesList = React.useMemo( - () => getExamplesListWithRecentlyUsed({recentlyUsed}), - [recentlyUsed], + () => getExamplesListWithRecentlyUsed({recentlyUsed, testList}), + [recentlyUsed, testList], ); const handleBackPress = React.useCallback(() => { @@ -104,6 +119,45 @@ const RNTesterApp = (): React.Node => { [dispatch], ); + // Setup Linking event subscription + const handleOpenUrlRequest = React.useCallback( + ({url}: {url: string, ...}) => { + // Supported URL pattern(s): + // * rntester://example/ + const match = /^rntester:\/\/example\/(.+)$/.exec(url); + if (!match) { + console.warn( + `handleOpenUrlRequest: Received unsupported URL: '${url}'`, + ); + return; + } + + const key = match[1]; + const exampleModule = RNTesterList.Modules[key]; + if (exampleModule == null) { + console.warn( + `handleOpenUrlRequest: Unable to find requested module with key: '${key}'`, + ); + return; + } + + console.log(`handleOpenUrlRequest: Opening example '${key}'`); + + dispatch({ + type: RNTesterNavigationActionsType.EXAMPLE_OPEN_URL_REQUEST, + data: { + key, + title: exampleModule.title || key, + }, + }); + }, + [dispatch], + ); + React.useEffect(() => { + const subscription = Linking.addEventListener('url', handleOpenUrlRequest); + return () => subscription.remove(); + }, [handleOpenUrlRequest]); + const theme = colorScheme === 'dark' ? themes.dark : themes.light; if (examplesList === null) { diff --git a/packages/@react-native/tester/js/examples/TextInput/TextInputExample.android.js b/packages/@react-native/tester/js/examples/TextInput/TextInputExample.android.js index d0ad8661558..35347b720ce 100644 --- a/packages/@react-native/tester/js/examples/TextInput/TextInputExample.android.js +++ b/packages/@react-native/tester/js/examples/TextInput/TextInputExample.android.js @@ -196,10 +196,20 @@ const examples: Array = [ + + ); }, @@ -470,7 +480,7 @@ const examples: Array = [ 'next', ]; const returnKeyLabels = ['Compile', 'React Native']; - const examples = returnKeyTypes.map(type => { + const returnKeyExamples = returnKeyTypes.map(type => { return ( = [ }); return ( - {examples} + {returnKeyExamples} {types} ); diff --git a/packages/@react-native/tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js b/packages/@react-native/tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js index f4135cc5b5f..189c3a5fd21 100644 --- a/packages/@react-native/tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js +++ b/packages/@react-native/tester/js/examples/TurboModule/NativeCxxModuleExampleExample.js @@ -55,7 +55,9 @@ type Examples = | 'rejectPromise' | 'voidFunc' | 'optionalArgs' - | 'emitDeviceEvent' + | 'emitDeviceEvent'; + +type ErrorExamples = | 'voidFuncThrows' | 'getObjectThrows' | 'promiseThrows' @@ -131,6 +133,10 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> { }); NativeCxxModuleExample?.emitCustomDeviceEvent(CUSTOM_EVENT_TYPE); }, + }; + + // $FlowFixMe[missing-local-annot] + _errorTests = { voidFuncThrows: () => { try { NativeCxxModuleExample?.voidFuncThrows(); @@ -202,7 +208,7 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> { })); } - _renderResult(name: Examples): React.Node { + _renderResult(name: Examples | ErrorExamples): React.Node { const result = this.state.testResults[name] || {}; return ( @@ -231,7 +237,7 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> { this._setResult(item, this._tests[item]()), ) }> - Run all tests + Run function call tests this.setState({testResults: {}})} @@ -254,6 +260,24 @@ class NativeCxxModuleExampleExample extends React.Component<{||}, State> { )} /> + + Report errors tests + + item} + renderItem={({item}: {item: ErrorExamples, ...}) => ( + + this._setResult(item, this._errorTests[item]())}> + {item} + + {this._renderResult(item)} + + )} + /> ); } diff --git a/packages/@react-native/tester/js/utils/RNTesterNavigationReducer.js b/packages/@react-native/tester/js/utils/RNTesterNavigationReducer.js index 9c2097d668c..db59ba5a7a7 100644 --- a/packages/@react-native/tester/js/utils/RNTesterNavigationReducer.js +++ b/packages/@react-native/tester/js/utils/RNTesterNavigationReducer.js @@ -18,6 +18,7 @@ export const RNTesterNavigationActionsType = { BACK_BUTTON_PRESS: 'BACK_BUTTON_PRESS', MODULE_CARD_PRESS: 'MODULE_CARD_PRESS', EXAMPLE_CARD_PRESS: 'EXAMPLE_CARD_PRESS', + EXAMPLE_OPEN_URL_REQUEST: 'EXAMPLE_OPEN_URL_REQUEST', }; const getUpdatedRecentlyUsed = ({ @@ -100,6 +101,14 @@ export const RNTesterNavigationReducer = ( state.activeModuleExampleKey != null ? state.activeModuleTitle : null, }; + case RNTesterNavigationActionsType.EXAMPLE_OPEN_URL_REQUEST: + return { + ...state, + activeModuleKey: key, + activeModuleTitle: title, + activeModuleExampleKey: null, + }; + default: throw new Error(`Invalid action type ${action.type}`); } diff --git a/packages/@react-native/tester/js/utils/testerStateUtils.js b/packages/@react-native/tester/js/utils/testerStateUtils.js index c3239adeab9..805cfe83349 100644 --- a/packages/@react-native/tester/js/utils/testerStateUtils.js +++ b/packages/@react-native/tester/js/utils/testerStateUtils.js @@ -48,15 +48,21 @@ const filterEmptySections = (examplesList: ExamplesList): any => { export const getExamplesListWithRecentlyUsed = ({ recentlyUsed, + testList, }: { recentlyUsed: ComponentList, + testList?: { + components?: Array, + apis?: Array, + }, }): ExamplesList | null => { // Return early if state has not been initialized from storage if (!recentlyUsed) { return null; } - const components = RNTesterList.Components.map( + const componentList = testList?.components ?? RNTesterList.Components; + const components = componentList.map( (componentExample): RNTesterModuleInfo => ({ ...componentExample, exampleType: Screens.COMPONENTS, @@ -69,7 +75,8 @@ export const getExamplesListWithRecentlyUsed = ({ ) .filter(Boolean); - const apis = RNTesterList.APIs.map((apiExample): RNTesterModuleInfo => ({ + const apisList = testList?.apis ?? RNTesterList.APIs; + const apis = apisList.map((apiExample): RNTesterModuleInfo => ({ ...apiExample, exampleType: Screens.APIS, })); diff --git a/packages/@react-native/tester/overrides.json b/packages/@react-native/tester/overrides.json index 9a9d7a288b5..6fc2abd04eb 100644 --- a/packages/@react-native/tester/overrides.json +++ b/packages/@react-native/tester/overrides.json @@ -1,5 +1,5 @@ { - "baseVersion": "0.74.0-nightly-20231116-fa89dd68b", + "baseVersion": "0.74.0-nightly-20231124-c464b215e", "overrides": [ { "type": "copy", @@ -383,7 +383,7 @@ "type": "copy", "directory": "js/examples/TextInput", "baseDirectory": "packages/rn-tester/js/examples/TextInput", - "baseHash": "76225825a3f4a981e5b804c14edc68081257967f", + "baseHash": "945fcdd1e5cb8a229d62b43a367a0a49ca754670", "issue": 4054 }, { @@ -425,7 +425,7 @@ "type": "copy", "directory": "js/examples/TurboModule", "baseDirectory": "packages/rn-tester/js/examples/TurboModule", - "baseHash": "b5578c95183bfbf584844d1c77d7c198ada306e1", + "baseHash": "2f833999772c0489207afe4d58ae7e001d6da4fe", "issue": 4054 }, { @@ -474,7 +474,7 @@ "type": "copy", "file": "js/RNTesterAppShared.js", "baseFile": "packages/rn-tester/js/RNTesterAppShared.js", - "baseHash": "47dbdd4392c77270221b14051bb898ccb0ef610c", + "baseHash": "0323b0f1a26dba9a0f053e098024604c582052db", "issue": 4054 }, { @@ -488,7 +488,7 @@ "type": "copy", "directory": "js/utils", "baseDirectory": "packages/rn-tester/js/utils", - "baseHash": "97abb83b21178ac0ca73d2b90f2d5572cd2a25ff", + "baseHash": "fda3b531c884cf078815fac9c040a3e9cd55df97", "issue": 4054 }, { diff --git a/packages/e2e-test-app-fabric/package.json b/packages/e2e-test-app-fabric/package.json index 427aec75f97..4ef29bb42fa 100644 --- a/packages/e2e-test-app-fabric/package.json +++ b/packages/e2e-test-app-fabric/package.json @@ -19,7 +19,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/packages/e2e-test-app/package.json b/packages/e2e-test-app/package.json index 3e989a90124..28cf65adc13 100644 --- a/packages/e2e-test-app/package.json +++ b/packages/e2e-test-app/package.json @@ -19,7 +19,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749", "react-native-xaml": "^0.0.76" }, diff --git a/packages/integration-test-app/package.json b/packages/integration-test-app/package.json index 69df582b6c7..6af22ead138 100644 --- a/packages/integration-test-app/package.json +++ b/packages/integration-test-app/package.json @@ -16,7 +16,7 @@ "@typescript-eslint/parser": "^5.21.0", "chai": "^4.2.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/packages/playground/package.json b/packages/playground/package.json index f4ae0f13ad2..4931e94638e 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -15,7 +15,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/packages/sample-apps/package.json b/packages/sample-apps/package.json index 077c0c50e53..438a29f9c96 100644 --- a/packages/sample-apps/package.json +++ b/packages/sample-apps/package.json @@ -15,7 +15,7 @@ "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.57.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp b/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp index 73a2d202f75..0b2a04d63e9 100644 --- a/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.cpp @@ -78,7 +78,7 @@ void AbiViewComponentDescriptor::appendChild( facebook::react::Props::Shared AbiViewComponentDescriptor::cloneProps( const facebook::react::PropsParserContext &context, const facebook::react::Props::Shared &props, - const facebook::react::RawProps &rawProps) const { + facebook::react::RawProps rawProps) const { // Optimization: // Quite often nodes are constructed with default/empty props: the base // `props` object is `null` (there no base because it's not cloning) and the @@ -88,7 +88,13 @@ facebook::react::Props::Shared AbiViewComponentDescriptor::cloneProps( return ShadowNodeT::defaultSharedProps(); } - rawProps.parse(rawPropsParser_, context); + if (facebook::react::CoreFeatures::excludeYogaFromRawProps) { + if (ShadowNodeT::IdentifierTrait() == facebook::react::ShadowNodeTraits::Trait::YogaLayoutableKind) { + rawProps.filterYogaStylePropsInDynamicConversion(); + } + } + + rawProps.parse(rawPropsParser_); // Call old-style constructor // auto shadowNodeProps = std::make_shared(context, rawProps, props); @@ -150,16 +156,10 @@ facebook::react::State::Shared AbiViewComponentDescriptor::createState( facebook::react::ShadowNodeFamily::Shared AbiViewComponentDescriptor::createFamily( facebook::react::ShadowNodeFamilyFragment const &fragment) const { + auto eventEmitter = std::make_shared( + std::make_shared(fragment.instanceHandle), eventDispatcher_); return std::make_shared( - facebook::react::ShadowNodeFamilyFragment{fragment.tag, fragment.surfaceId, fragment.instanceHandle}, - eventDispatcher_, - *this); -} - -facebook::react::SharedEventEmitter AbiViewComponentDescriptor::createEventEmitter( - facebook::react::InstanceHandle::Shared const &instanceHandle) const { - return std::make_shared( - std::make_shared(instanceHandle), eventDispatcher_); + fragment, std::move(eventEmitter), eventDispatcher_, *this); } /* diff --git a/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h b/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h index 899360fcbb9..32ff0581c12 100644 --- a/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h +++ b/vnext/Microsoft.ReactNative/Fabric/AbiViewComponentDescriptor.h @@ -42,7 +42,7 @@ class AbiViewComponentDescriptor : public facebook::react::ComponentDescriptor { virtual facebook::react::Props::Shared cloneProps( const facebook::react::PropsParserContext &context, const facebook::react::Props::Shared &props, - const facebook::react::RawProps &rawProps) const override; + facebook::react::RawProps rawProps) const override; virtual facebook::react::State::Shared createInitialState( facebook::react::Props::Shared const &props, facebook::react::ShadowNodeFamily::Shared const &family) const override; @@ -53,9 +53,6 @@ class AbiViewComponentDescriptor : public facebook::react::ComponentDescriptor { facebook::react::ShadowNodeFamily::Shared createFamily( facebook::react::ShadowNodeFamilyFragment const &fragment) const override; - facebook::react::SharedEventEmitter createEventEmitter( - facebook::react::InstanceHandle::Shared const &instanceHandle) const override; - protected: /* * Called immediately after `ShadowNode` is created or cloned. diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index 99a333b3b69..f77e34b99ed 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -1190,7 +1190,7 @@ void CompositionBaseComponentView::updateBorderProps( const facebook::react::ViewProps &oldViewProps, const facebook::react::ViewProps &newViewProps) noexcept { if (oldViewProps.borderColors != newViewProps.borderColors || oldViewProps.borderRadii != newViewProps.borderRadii || - !(oldViewProps.yogaStyle.border() == newViewProps.yogaStyle.border()) || + !(oldViewProps.yogaStyle.border(YGEdgeAll) == newViewProps.yogaStyle.border(YGEdgeAll)) || oldViewProps.borderStyles != newViewProps.borderStyles) { m_needsBorderUpdate = true; } diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h index ab7935cb59c..76626efdce4 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h @@ -28,52 +28,42 @@ class WindowsTextInputComponentDescriptor final : public ConcreteComponentDescri } /* - virtual State::Shared createInitialState( - facebook::react::Props::Shared const &props, - ShadowNodeFamily::Shared const &family) const override { - int surfaceId = family->getSurfaceId(); - - YGStyle::Edges theme; - // TODO: figure out RTL/start/end/left/right stuff here - if (surfaceIdToThemePaddingMap_.find(surfaceId) != - surfaceIdToThemePaddingMap_.end()) { - theme = surfaceIdToThemePaddingMap_[surfaceId]; - } else { - const jni::global_ref &fabricUIManager = - contextContainer_->at>("FabricUIManager"); - - auto env = jni::Environment::current(); - auto defaultTextInputPaddingArray = env->NewFloatArray(4); - static auto getThemeData = - jni::findClassStatic(UIManagerJavaDescriptor) - ->getMethod("getThemeData"); - - if (getThemeData( - fabricUIManager, surfaceId, defaultTextInputPaddingArray)) { - jfloat *defaultTextInputPadding = - env->GetFloatArrayElements(defaultTextInputPaddingArray, 0); - theme[YGEdgeStart] = (YGValue){defaultTextInputPadding[0], YGUnitPoint}; - theme[YGEdgeEnd] = (YGValue){defaultTextInputPadding[1], YGUnitPoint}; - theme[YGEdgeTop] = (YGValue){defaultTextInputPadding[2], YGUnitPoint}; - theme[YGEdgeBottom] = - (YGValue){defaultTextInputPadding[3], YGUnitPoint}; - surfaceIdToThemePaddingMap_.emplace(std::make_pair(surfaceId, theme)); - env->ReleaseFloatArrayElements( - defaultTextInputPaddingArray, defaultTextInputPadding, JNI_ABORT); - } - env->DeleteLocalRef(defaultTextInputPaddingArray); +virtual State::Shared createInitialState( + const Props::Shared& props, + const ShadowNodeFamily::Shared& family) const override { + int surfaceId = family->getSurfaceId(); + + ThemePadding theme; + // TODO: figure out RTL/start/end/left/right stuff here + if (surfaceIdToThemePaddingMap_.find(surfaceId) != + surfaceIdToThemePaddingMap_.end()) { + theme = surfaceIdToThemePaddingMap_[surfaceId]; + } else { + const jni::global_ref& fabricUIManager = + contextContainer_->at>("FabricUIManager"); + + auto env = jni::Environment::current(); + auto defaultTextInputPaddingArray = env->NewFloatArray(4); + static auto getThemeData = + jni::findClassStatic(UIManagerJavaDescriptor) + ->getMethod("getThemeData"); + + if (getThemeData( + fabricUIManager, surfaceId, defaultTextInputPaddingArray)) { + jfloat* defaultTextInputPadding = + env->GetFloatArrayElements(defaultTextInputPaddingArray, 0); + 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); } return std::make_shared( std::make_shared(AndroidTextInputState( - 0, - {}, - {}, - {}, - ((YGValue)theme[YGEdgeStart]).value, - ((YGValue)theme[YGEdgeEnd]).value, - ((YGValue)theme[YGEdgeTop]).value, - ((YGValue)theme[YGEdgeBottom]).value)), + 0, {}, {}, {}, theme.start, theme.end, theme.top, theme.bottom)), family); } */ @@ -89,78 +79,73 @@ class WindowsTextInputComponentDescriptor final : public ConcreteComponentDescri textInputShadowNode.setContextContainer(const_cast(getContextContainer().get())); /* - int surfaceId = textInputShadowNode->getSurfaceId(); - if (surfaceIdToThemePaddingMap_.find(surfaceId) != - surfaceIdToThemePaddingMap_.end()) { - yoga::Style::Edges theme = surfaceIdToThemePaddingMap_[surfaceId]; - - // Override padding - // Node is still unsealed during adoption, before layout is complete - // TODO: T62959168 account for RTL and paddingLeft when setting default - // paddingStart, and vice-versa with paddingRight/paddingEnd. - // For now this assumes no RTL. - yoga::Style::Edges result = - textInputShadowNode->getConcreteProps().yogaStyle.padding(); - bool changedPadding = false; - if (!textInputShadowNode->getConcreteProps().hasPadding && - !textInputShadowNode->getConcreteProps().hasPaddingStart && - !textInputShadowNode->getConcreteProps().hasPaddingLeft && - !textInputShadowNode->getConcreteProps().hasPaddingHorizontal) { - changedPadding = true; - result[YGEdgeStart] = theme[YGEdgeStart]; - } - if (!textInputShadowNode->getConcreteProps().hasPadding && - !textInputShadowNode->getConcreteProps().hasPaddingEnd && - !textInputShadowNode->getConcreteProps().hasPaddingRight && - !textInputShadowNode->getConcreteProps().hasPaddingHorizontal) { - changedPadding = true; - result[YGEdgeEnd] = theme[YGEdgeEnd]; - } - if (!textInputShadowNode->getConcreteProps().hasPadding && - !textInputShadowNode->getConcreteProps().hasPaddingTop && - !textInputShadowNode->getConcreteProps().hasPaddingVertical) { - changedPadding = true; - result[YGEdgeTop] = theme[YGEdgeTop]; - } - if (!textInputShadowNode->getConcreteProps().hasPadding && - !textInputShadowNode->getConcreteProps().hasPaddingBottom && - !textInputShadowNode->getConcreteProps().hasPaddingVertical) { - changedPadding = true; - result[YGEdgeBottom] = theme[YGEdgeBottom]; - } - - // If the TextInput initially does not have paddingLeft or paddingStart, a - // paddingStart may be set from the theme. If that happens, when there's a - // paddingLeft update, we must explicitly unset paddingStart... (same with - // paddingEnd) - // TODO: support RTL - if ((textInputShadowNode->getConcreteProps().hasPadding || - textInputShadowNode->getConcreteProps().hasPaddingLeft || - textInputShadowNode->getConcreteProps().hasPaddingHorizontal) && - !textInputShadowNode->getConcreteProps().hasPaddingStart) { - result[YGEdgeStart] = YGValueUndefined; - } - if ((textInputShadowNode->getConcreteProps().hasPadding || - textInputShadowNode->getConcreteProps().hasPaddingRight || - textInputShadowNode->getConcreteProps().hasPaddingHorizontal) && - !textInputShadowNode->getConcreteProps().hasPaddingEnd) { - result[YGEdgeEnd] = YGValueUndefined; - } - - // Note that this is expensive: on every adopt, we need to set the Yoga - // props again, which normally only happens during prop parsing. Every - // commit, state update, etc, will incur this cost. - if (changedPadding) { - // Set new props on node - const_cast( - textInputShadowNode->getConcreteProps()) - .yogaStyle.padding() = result; - // Communicate new props to Yoga part of the node - textInputShadowNode->updateYogaProps(); - } - } - - textInputShadowNode->dirtyLayout(); + int surfaceId = textInputShadowNode.getSurfaceId(); + if (surfaceIdToThemePaddingMap_.find(surfaceId) != + surfaceIdToThemePaddingMap_.end()) { + const auto& theme = surfaceIdToThemePaddingMap_[surfaceId]; + + auto& textInputProps = textInputShadowNode.getConcreteProps(); + + // Override padding + // Node is still unsealed during adoption, before layout is complete + // TODO: T62959168 account for RTL and paddingLeft when setting default + // paddingStart, and vice-versa with paddingRight/paddingEnd. + // For now this assumes no RTL. + auto& style = const_cast(textInputProps.yogaStyle); + bool changedPadding = false; + if (!textInputProps.hasPadding && !textInputProps.hasPaddingStart && + !textInputProps.hasPaddingLeft && + !textInputProps.hasPaddingHorizontal) { + changedPadding = true; + style.setPadding( + YGEdgeStart, yoga::CompactValue::of(theme.start)); + } + if (!textInputProps.hasPadding && !textInputProps.hasPaddingEnd && + !textInputProps.hasPaddingRight && + !textInputProps.hasPaddingHorizontal) { + changedPadding = true; + style.setPadding( + YGEdgeEnd, yoga::CompactValue::of(theme.end)); + } + if (!textInputProps.hasPadding && !textInputProps.hasPaddingTop && + !textInputProps.hasPaddingVertical) { + changedPadding = true; + style.setPadding( + YGEdgeTop, yoga::CompactValue::of(theme.top)); + } + if (!textInputProps.hasPadding && !textInputProps.hasPaddingBottom && + !textInputProps.hasPaddingVertical) { + changedPadding = true; + style.setPadding( + YGEdgeBottom, yoga::CompactValue::of(theme.bottom)); + } + + // If the TextInput initially does not have paddingLeft or paddingStart, a + // paddingStart may be set from the theme. If that happens, when there's a + // paddingLeft update, we must explicitly unset paddingStart... (same with + // paddingEnd) + // TODO: support RTL + if ((textInputProps.hasPadding || textInputProps.hasPaddingLeft || + textInputProps.hasPaddingHorizontal) && + !textInputProps.hasPaddingStart) { + style.setPadding(YGEdgeStart, yoga::CompactValue::ofUndefined()); + } + if ((textInputProps.hasPadding || textInputProps.hasPaddingRight || + textInputProps.hasPaddingHorizontal) && + !textInputProps.hasPaddingEnd) { + style.setPadding(YGEdgeEnd, yoga::CompactValue::ofUndefined()); + } + + // Note that this is expensive: on every adopt, we need to set the Yoga + // props again, which normally only happens during prop parsing. Every + // commit, state update, etc, will incur this cost. + if (changedPadding) { + // Communicate new props to Yoga part of the node + textInputShadowNode.updateYogaProps(); + } + } + + textInputShadowNode.dirtyLayout(); */ textInputShadowNode.enableMeasurement(); @@ -169,7 +154,18 @@ class WindowsTextInputComponentDescriptor final : public ConcreteComponentDescri } private: + struct ThemePadding { + float start{}; + float end{}; + float top{}; + float bottom{}; + }; + + // TODO T68526882: Unify with Binding::UIManagerJavaDescriptor + constexpr static auto UIManagerJavaDescriptor = "com/facebook/react/fabric/FabricUIManager"; + SharedTextLayoutManager m_textLayoutManager; + mutable std::unordered_map surfaceIdToThemePaddingMap_; }; } // namespace facebook::react diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp index b47051109d8..3ac8a64c53d 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp @@ -6,11 +6,8 @@ #include #include - -#ifdef ANDROID #include #include -#endif #include @@ -47,41 +44,4 @@ WindowsTextInputState::WindowsTextInputState(const WindowsTextInputState &previo defaultThemePaddingBottom( data.getDefault("themePaddingBottom", previousState.defaultThemePaddingBottom).getDouble()){}; -#ifdef ANDROID -folly::dynamic AndroidTextInputState::getDynamic() const { - // Java doesn't need all fields, so we don't pass them all along. - folly::dynamic newState = folly::dynamic::object(); - - // If we have a `cachedAttributedStringId` we know that we're (1) not trying - // to set a new string, so we don't need to pass it along; (2) setState was - // called from Java to trigger a relayout with a `cachedAttributedStringId`, - // so Java has all up-to-date information and we should pass an empty map - // through. - if (cachedAttributedStringId == 0) { - newState["mostRecentEventCount"] = mostRecentEventCount; - newState["attributedString"] = toDynamic(attributedString); - newState["hash"] = newState["attributedString"]["hash"]; - newState["paragraphAttributes"] = toDynamic(paragraphAttributes); // TODO: can we memoize this in Java? - } - return newState; -} - -MapBuffer AndroidTextInputState::getMapBuffer() const { - auto builder = MapBufferBuilder(); - // See comment in getDynamic block. - if (cachedAttributedStringId == 0) { - builder.putInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT, mostRecentEventCount); - - auto attStringMapBuffer = toMapBuffer(attributedString); - builder.putMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING, attStringMapBuffer); - auto paMapBuffer = toMapBuffer(paragraphAttributes); - builder.putMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES, paMapBuffer); - - builder.putInt(TX_STATE_KEY_HASH, attStringMapBuffer.getInt(AS_KEY_HASH)); - } - return builder.build(); -} - -#endif - } // namespace facebook::react diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h index 4f1b57fc55d..ae137bef264 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h @@ -3,9 +3,11 @@ #pragma once +#include #include #include #include +#include #include namespace facebook::react { diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp index 1aa2de1d98e..a3d5f60fcca 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp @@ -106,14 +106,20 @@ YogaLayoutableShadowNode::YogaLayoutableShadowNode( yogaConfig_(FabricDefaultYogaLog), yogaNode_(static_cast(sourceShadowNode) .yogaNode_) { - // Note, cloned `yoga::Node` instance (copied using copy-constructor) inherits - // dirty flag, measure function, and other properties being set originally in - // the `YogaLayoutableShadowNode` constructor above. - +// Note, cloned `yoga::Node` instance (copied using copy-constructor) inherits +// dirty flag, measure function, and other properties being set originally in +// the `YogaLayoutableShadowNode` constructor above. + +// There is a known race condition when background executor is enabled, where +// a tree may be laid out on the Fabric background thread concurrently with +// the ShadowTree being created on the JS thread. This assert can be +// re-enabled after disabling background executor everywhere. +#if 0 react_native_assert( static_cast(sourceShadowNode) .yogaNode_.isDirty() == yogaNode_.isDirty() && "Yoga node must inherit dirty flag."); +#endif if (!getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) { for (auto& child : getChildren()) { @@ -385,64 +391,55 @@ void YogaLayoutableShadowNode::updateYogaProps() { yoga::Style result{baseStyle}; // Aliases with precedence - if (!props.inset.isUndefined()) { - result.position()[YGEdgeAll] = props.inset; - } - if (!props.insetBlock.isUndefined()) { - result.position()[YGEdgeVertical] = props.insetBlock; - } - if (!props.insetInline.isUndefined()) { - result.position()[YGEdgeHorizontal] = props.insetInline; + if (props.insetInlineEnd.isDefined()) { + result.setPosition(YGEdgeEnd, props.insetInlineEnd); } - if (!props.insetInlineEnd.isUndefined()) { - result.position()[YGEdgeEnd] = props.insetInlineEnd; + if (props.insetInlineStart.isDefined()) { + result.setPosition(YGEdgeStart, props.insetInlineStart); } - if (!props.insetInlineStart.isUndefined()) { - result.position()[YGEdgeStart] = props.insetInlineStart; + if (props.marginInline.isDefined()) { + result.setMargin(YGEdgeHorizontal, props.marginInline); } - if (!props.marginInline.isUndefined()) { - result.margin()[YGEdgeHorizontal] = props.marginInline; + if (props.marginInlineStart.isDefined()) { + result.setMargin(YGEdgeStart, props.marginInlineStart); } - if (!props.marginInlineStart.isUndefined()) { - result.margin()[YGEdgeStart] = props.marginInlineStart; + if (props.marginInlineEnd.isDefined()) { + result.setMargin(YGEdgeEnd, props.marginInlineEnd); } - if (!props.marginInlineEnd.isUndefined()) { - result.margin()[YGEdgeEnd] = props.marginInlineEnd; + if (props.marginBlock.isDefined()) { + result.setMargin(YGEdgeVertical, props.marginBlock); } - if (!props.marginBlock.isUndefined()) { - result.margin()[YGEdgeVertical] = props.marginBlock; + if (props.paddingInline.isDefined()) { + result.setPadding(YGEdgeHorizontal, props.paddingInline); } - if (!props.paddingInline.isUndefined()) { - result.padding()[YGEdgeHorizontal] = props.paddingInline; + if (props.paddingInlineStart.isDefined()) { + result.setPadding(YGEdgeStart, props.paddingInlineStart); } - if (!props.paddingInlineStart.isUndefined()) { - result.padding()[YGEdgeStart] = props.paddingInlineStart; + if (props.paddingInlineEnd.isDefined()) { + result.setPadding(YGEdgeEnd, props.paddingInlineEnd); } - if (!props.paddingInlineEnd.isUndefined()) { - result.padding()[YGEdgeEnd] = props.paddingInlineEnd; - } - if (!props.paddingBlock.isUndefined()) { - result.padding()[YGEdgeVertical] = props.paddingBlock; + if (props.paddingBlock.isDefined()) { + result.setPadding(YGEdgeVertical, props.paddingBlock); } // Aliases without precedence - if (CompactValue(result.position()[YGEdgeBottom]).isUndefined()) { - result.position()[YGEdgeBottom] = props.insetBlockEnd; + if (result.position(YGEdgeBottom).isUndefined()) { + result.setPosition(YGEdgeBottom, props.insetBlockEnd); } - if (CompactValue(result.position()[YGEdgeTop]).isUndefined()) { - result.position()[YGEdgeTop] = props.insetBlockStart; + if (result.position(YGEdgeTop).isUndefined()) { + result.setPosition(YGEdgeTop, props.insetBlockStart); } - if (CompactValue(result.margin()[YGEdgeTop]).isUndefined()) { - result.margin()[YGEdgeTop] = props.marginBlockStart; + if (result.margin(YGEdgeTop).isUndefined()) { + result.setMargin(YGEdgeTop, props.marginBlockStart); } - if (CompactValue(result.margin()[YGEdgeBottom]).isUndefined()) { - result.margin()[YGEdgeBottom] = props.marginBlockEnd; + if (result.margin(YGEdgeBottom).isUndefined()) { + result.setMargin(YGEdgeBottom, props.marginBlockEnd); } - if (CompactValue(result.padding()[YGEdgeTop]).isUndefined()) { - result.padding()[YGEdgeTop] = props.paddingBlockStart; + if (result.padding(YGEdgeTop).isUndefined()) { + result.setPadding(YGEdgeTop, props.paddingBlockStart); } - if (CompactValue(result.padding()[YGEdgeBottom]).isUndefined()) { - result.padding()[YGEdgeBottom] = props.paddingBlockEnd; + if (result.padding(YGEdgeBottom).isUndefined()) { + result.setPadding(YGEdgeBottom, props.paddingBlockEnd); } return result; @@ -552,18 +549,18 @@ void YogaLayoutableShadowNode::setPadding(RectangleEdges padding) const { auto rightPadding = yoga::CompactValue::ofMaybe(padding.right); auto bottomPadding = yoga::CompactValue::ofMaybe(padding.bottom); - if (leftPadding != style.padding()[YGEdgeLeft] || - topPadding != style.padding()[YGEdgeTop] || - rightPadding != style.padding()[YGEdgeRight] || - bottomPadding != style.padding()[YGEdgeBottom]) { - style.padding()[YGEdgeTop] = - yoga::CompactValue::ofMaybe(padding.top); - style.padding()[YGEdgeLeft] = - yoga::CompactValue::ofMaybe(padding.left); - style.padding()[YGEdgeRight] = - yoga::CompactValue::ofMaybe(padding.right); - style.padding()[YGEdgeBottom] = - yoga::CompactValue::ofMaybe(padding.bottom); + if (leftPadding != style.padding(YGEdgeLeft) || + topPadding != style.padding(YGEdgeTop) || + rightPadding != style.padding(YGEdgeRight) || + bottomPadding != style.padding(YGEdgeBottom)) { + style.setPadding( + YGEdgeTop, yoga::CompactValue::ofMaybe(padding.top)); + style.setPadding( + YGEdgeLeft, yoga::CompactValue::ofMaybe(padding.left)); + style.setPadding( + YGEdgeRight, yoga::CompactValue::ofMaybe(padding.right)); + style.setPadding( + YGEdgeBottom, yoga::CompactValue::ofMaybe(padding.bottom)); yogaNode_.setStyle(style); yogaNode_.setDirty(true); } @@ -886,40 +883,36 @@ void YogaLayoutableShadowNode::swapLeftAndRightInYogaStyleProps( const YogaLayoutableShadowNode& shadowNode) { auto yogaStyle = shadowNode.yogaNode_.getStyle(); - const yoga::Style::Edges& position = yogaStyle.position(); - const yoga::Style::Edges& padding = yogaStyle.padding(); - const yoga::Style::Edges& margin = yogaStyle.margin(); - // Swap Yoga node values, position, padding and margin. - if (yogaStyle.position()[YGEdgeLeft] != YGValueUndefined) { - yogaStyle.position()[YGEdgeStart] = position[YGEdgeLeft]; - yogaStyle.position()[YGEdgeLeft] = YGValueUndefined; + if (yogaStyle.position(YGEdgeLeft).isDefined()) { + yogaStyle.setPosition(YGEdgeStart, yogaStyle.position(YGEdgeLeft)); + yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::ofUndefined()); } - if (yogaStyle.position()[YGEdgeRight] != YGValueUndefined) { - yogaStyle.position()[YGEdgeEnd] = position[YGEdgeRight]; - yogaStyle.position()[YGEdgeRight] = YGValueUndefined; + if (yogaStyle.position(YGEdgeRight).isDefined()) { + yogaStyle.setPosition(YGEdgeEnd, yogaStyle.position(YGEdgeRight)); + yogaStyle.setPosition(YGEdgeRight, yoga::CompactValue::ofUndefined()); } - if (yogaStyle.padding()[YGEdgeLeft] != YGValueUndefined) { - yogaStyle.padding()[YGEdgeStart] = padding[YGEdgeLeft]; - yogaStyle.padding()[YGEdgeLeft] = YGValueUndefined; + if (yogaStyle.padding(YGEdgeLeft).isDefined()) { + yogaStyle.setPadding(YGEdgeStart, yogaStyle.padding(YGEdgeLeft)); + yogaStyle.setPadding(YGEdgeLeft, yoga::CompactValue::ofUndefined()); } - if (yogaStyle.padding()[YGEdgeRight] != YGValueUndefined) { - yogaStyle.padding()[YGEdgeEnd] = padding[YGEdgeRight]; - yogaStyle.padding()[YGEdgeRight] = YGValueUndefined; + if (yogaStyle.padding(YGEdgeRight).isDefined()) { + yogaStyle.setPadding(YGEdgeEnd, yogaStyle.padding(YGEdgeRight)); + yogaStyle.setPadding(YGEdgeRight, yoga::CompactValue::ofUndefined()); } - if (yogaStyle.margin()[YGEdgeLeft] != YGValueUndefined) { - yogaStyle.margin()[YGEdgeStart] = margin[YGEdgeLeft]; - yogaStyle.margin()[YGEdgeLeft] = YGValueUndefined; + if (yogaStyle.margin(YGEdgeLeft).isDefined()) { + yogaStyle.setMargin(YGEdgeStart, yogaStyle.margin(YGEdgeLeft)); + yogaStyle.setMargin(YGEdgeLeft, yoga::CompactValue::ofUndefined()); } - if (yogaStyle.margin()[YGEdgeRight] != YGValueUndefined) { - yogaStyle.margin()[YGEdgeEnd] = margin[YGEdgeRight]; - yogaStyle.margin()[YGEdgeRight] = YGValueUndefined; + if (yogaStyle.margin(YGEdgeRight).isDefined()) { + yogaStyle.setMargin(YGEdgeEnd, yogaStyle.margin(YGEdgeRight)); + yogaStyle.setMargin(YGEdgeRight, yoga::CompactValue::ofUndefined()); } shadowNode.yogaNode_.setStyle(yogaStyle); @@ -972,16 +965,14 @@ void YogaLayoutableShadowNode::swapLeftAndRightInViewProps( props.borderStyles.right.reset(); } - const yoga::Style::Edges& border = props.yogaStyle.border(); - - if (props.yogaStyle.border()[YGEdgeLeft] != YGValueUndefined) { - props.yogaStyle.border()[YGEdgeStart] = border[YGEdgeLeft]; - props.yogaStyle.border()[YGEdgeLeft] = YGValueUndefined; + if (props.yogaStyle.border(YGEdgeLeft).isDefined()) { + props.yogaStyle.setBorder(YGEdgeStart, props.yogaStyle.border(YGEdgeLeft)); + props.yogaStyle.setBorder(YGEdgeLeft, yoga::CompactValue::ofUndefined()); } - if (props.yogaStyle.border()[YGEdgeRight] != YGValueUndefined) { - props.yogaStyle.border()[YGEdgeEnd] = border[YGEdgeRight]; - props.yogaStyle.border()[YGEdgeRight] = YGValueUndefined; + if (props.yogaStyle.border(YGEdgeRight).isDefined()) { + props.yogaStyle.setBorder(YGEdgeEnd, props.yogaStyle.border(YGEdgeRight)); + props.yogaStyle.setBorder(YGEdgeRight, yoga::CompactValue::ofUndefined()); } } @@ -1037,4 +1028,4 @@ void YogaLayoutableShadowNode::ensureYogaChildrenAlignment() const { #endif } -} // namespace facebook::react +} // namespace facebook::react \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp index 639ca95cb7b..52915bb62cc 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp @@ -19,134 +19,19 @@ namespace facebook::react { -namespace { -inline RawProps filterYogaProps(const RawProps& rawProps) { - const static std::unordered_set yogaStylePropNames = { - {"direction", - "flexDirection", - "justifyContent", - "alignContent", - "alignItems", - "alignSelf", - "position", - "flexWrap", - "display", - "flex", - "flexGrow", - "flexShrink", - "flexBasis", - "margin", - "padding", - "rowGap", - "columnGap", - "gap", - // TODO: T163711275 also filter out width/height when SVG no longer read - // them from RawProps - "minWidth", - "maxWidth", - "minHeight", - "maxHeight", - "aspectRatio", - - // edges - "left", - "right", - "top", - "bottom", - "start", - "end", - - // variants of inset - "inset", - "insetStart", - "insetEnd", - "insetInline", - "insetInlineStart", - "insetInlineEnd", - "insetBlock", - "insetBlockEnd", - "insetBlockStart", - "insetVertical", - "insetHorizontal", - "insetTop", - "insetBottom", - "insetLeft", - "insetRight", - - // variants of margin - "marginStart", - "marginEnd", - "marginInline", - "marginInlineStart", - "marginInlineEnd", - "marginBlock", - "marginBlockStart", - "marginBlockEnd", - "marginVertical", - "marginHorizontal", - "marginTop", - "marginBottom", - "marginLeft", - "marginRight", - - // variants of padding - "paddingStart", - "paddingEnd", - "paddingInline", - "paddingInlineStart", - "paddingInlineEnd", - "paddingBlock", - "paddingBlockStart", - "paddingBlockEnd", - "paddingVertical", - "paddingHorizontal", - "paddingTop", - "paddingBottom", - "paddingLeft", - "paddingRight"}}; - - auto filteredRawProps = (folly::dynamic)rawProps; - - auto it = filteredRawProps.items().begin(); - while (it != filteredRawProps.items().end()) { - auto key = it->first.asString(); - if (yogaStylePropNames.find(key) != yogaStylePropNames.end()) { - it = filteredRawProps.erase(it); - } else { - ++it; - } - } - - return RawProps(std::move(filteredRawProps)); -} -} // namespace - YogaStylableProps::YogaStylableProps( const PropsParserContext& context, const YogaStylableProps& sourceProps, const RawProps& rawProps) : Props() { - if (CoreFeatures::excludeYogaFromRawProps) { - const auto filteredRawProps = filterYogaProps(rawProps); - initialize(context, sourceProps, filteredRawProps); - - yogaStyle = CoreFeatures::enablePropIteratorSetter - ? sourceProps.yogaStyle - : convertRawProp(context, filteredRawProps, sourceProps.yogaStyle); - - if (!CoreFeatures::enablePropIteratorSetter) { - convertRawPropAliases(context, sourceProps, filteredRawProps); - } - } else { - initialize(context, sourceProps, rawProps); + initialize(context, sourceProps, rawProps); - yogaStyle = CoreFeatures::enablePropIteratorSetter - ? sourceProps.yogaStyle - : convertRawProp(context, rawProps, sourceProps.yogaStyle); + yogaStyle = CoreFeatures::enablePropIteratorSetter + ? sourceProps.yogaStyle + : convertRawProp(context, rawProps, sourceProps.yogaStyle); - if (!CoreFeatures::enablePropIteratorSetter) { - convertRawPropAliases(context, sourceProps, rawProps); - } + if (!CoreFeatures::enablePropIteratorSetter) { + convertRawPropAliases(context, sourceProps, rawProps); } }; @@ -174,56 +59,67 @@ static inline T const getFieldValue( #define REBUILD_FIELD_SWITCH_CASE_YSP(field) \ REBUILD_FIELD_SWITCH_CASE2(field, #field) -#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, index, fieldName) \ - case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ - yogaStyle.field()[index] = \ - getFieldValue(context, value, ygDefaults.field()[index]); \ - return; \ - } - -#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \ - field, setter, index, fieldName) \ - case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ - yogaStyle.setter( \ - index, getFieldValue(context, value, ygDefaults.field(index))); \ - return; \ +#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, setter, index, fieldName) \ + case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ + yogaStyle.setter( \ + index, getFieldValue(context, value, ygDefaults.field(index))); \ + return; \ } #define REBUILD_FIELD_YG_DIMENSION(field, setter, widthStr, heightStr) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \ - field, setter, yoga::Dimension::Width, widthStr); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER( \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Dimension::Width, widthStr); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ field, setter, yoga::Dimension::Height, heightStr); -#define REBUILD_FIELD_YG_GUTTER(field, setter, rowGapStr, columnGapStr, gapStr) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER(field, setter, yoga::Gutter::Row, rowGapStr); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER(field, setter, yoga::Gutter::Column, columnGapStr); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED_SETTER(field, setter, yoga::Gutter::All, gapStr); - -#define REBUILD_FIELD_YG_EDGES(field, prefix, suffix) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, YGEdgeLeft, prefix "Left" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, YGEdgeTop, prefix "Top" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, YGEdgeRight, prefix "Right" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, YGEdgeBottom, prefix "Bottom" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, YGEdgeStart, prefix "Start" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, YGEdgeEnd, prefix "End" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, YGEdgeHorizontal, prefix "Horizontal" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, YGEdgeVertical, prefix "Vertical" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, YGEdgeAll, prefix "" suffix); - -#define REBUILD_FIELD_YG_EDGES_POSITION() \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeLeft, "left"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeTop, "top"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeRight, "right"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeBottom, "bottom"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeStart, "start"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(position, YGEdgeEnd, "end"); +#define REBUILD_FIELD_YG_GUTTER( \ + field, setter, rowGapStr, columnGapStr, gapStr) \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Gutter::Row, rowGapStr); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Gutter::Column, columnGapStr); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Gutter::All, gapStr); + +#define REBUILD_FIELD_YG_EDGES(field, setter, prefix, suffix) \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeLeft, prefix "Left" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeTop, prefix "Top" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeRight, prefix "Right" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeBottom, prefix "Bottom" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeStart, prefix "Start" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeEnd, prefix "End" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeHorizontal, prefix "Horizontal" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeVertical, prefix "Vertical" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, YGEdgeAll, prefix "" suffix); + +#define REBUILD_FIELD_YG_EDGES_POSITION() \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeLeft, "left"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeTop, "top"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeRight, "right"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeBottom, "bottom"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeStart, "start"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeEnd, "end"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeHorizontal, "insetInline"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeVertical, "insetBlock"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, YGEdgeAll, "inset"); void YogaStylableProps::setProp( const PropsParserContext& context, @@ -258,16 +154,13 @@ void YogaStylableProps::setProp( REBUILD_FIELD_YG_DIMENSION( maxDimension, setMaxDimension, "maxWidth", "maxHeight"); REBUILD_FIELD_YG_EDGES_POSITION(); - REBUILD_FIELD_YG_EDGES(margin, "margin", ""); - REBUILD_FIELD_YG_EDGES(padding, "padding", ""); - REBUILD_FIELD_YG_EDGES(border, "border", "Width"); + REBUILD_FIELD_YG_EDGES(margin, setMargin, "margin", ""); + REBUILD_FIELD_YG_EDGES(padding, setPadding, "padding", ""); + REBUILD_FIELD_YG_EDGES(border, setBorder, "border", "Width"); // Aliases - RAW_SET_PROP_SWITCH_CASE(inset, "inset"); - RAW_SET_PROP_SWITCH_CASE(insetBlock, "insetBlock"); RAW_SET_PROP_SWITCH_CASE(insetBlockEnd, "insetBlockEnd"); RAW_SET_PROP_SWITCH_CASE(insetBlockStart, "insetBlockStart"); - RAW_SET_PROP_SWITCH_CASE(insetInline, "insetInline"); RAW_SET_PROP_SWITCH_CASE(insetInlineEnd, "insetInlineEnd"); RAW_SET_PROP_SWITCH_CASE(insetInlineStart, "insetInlineStart"); RAW_SET_PROP_SWITCH_CASE(marginInline, "marginInline"); @@ -340,13 +233,149 @@ SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const { debugStringConvertibleItem( "flexBasis", yogaStyle.flexBasis(), defaultYogaStyle.flexBasis()), debugStringConvertibleItem( - "margin", yogaStyle.margin(), defaultYogaStyle.margin()), + "marginLeft", + yogaStyle.margin(YGEdgeLeft), + defaultYogaStyle.margin(YGEdgeLeft)), + debugStringConvertibleItem( + "marginTop", + yogaStyle.margin(YGEdgeTop), + defaultYogaStyle.margin(YGEdgeTop)), + debugStringConvertibleItem( + "marginRight", + yogaStyle.margin(YGEdgeRight), + defaultYogaStyle.margin(YGEdgeRight)), + debugStringConvertibleItem( + "marginBottom", + yogaStyle.margin(YGEdgeBottom), + defaultYogaStyle.margin(YGEdgeBottom)), + debugStringConvertibleItem( + "marginStart", + yogaStyle.margin(YGEdgeStart), + defaultYogaStyle.margin(YGEdgeStart)), + debugStringConvertibleItem( + "marginEnd", + yogaStyle.margin(YGEdgeEnd), + defaultYogaStyle.margin(YGEdgeEnd)), + debugStringConvertibleItem( + "marginHorizontal", + yogaStyle.margin(YGEdgeHorizontal), + defaultYogaStyle.margin(YGEdgeHorizontal)), + debugStringConvertibleItem( + "marginVertical", + yogaStyle.margin(YGEdgeVertical), + defaultYogaStyle.margin(YGEdgeVertical)), + debugStringConvertibleItem( + "margin", + yogaStyle.margin(YGEdgeAll), + defaultYogaStyle.margin(YGEdgeAll)), + debugStringConvertibleItem( + "left", + yogaStyle.position(YGEdgeLeft), + defaultYogaStyle.position(YGEdgeLeft)), + debugStringConvertibleItem( + "top", + yogaStyle.position(YGEdgeTop), + defaultYogaStyle.position(YGEdgeTop)), + debugStringConvertibleItem( + "right", + yogaStyle.position(YGEdgeRight), + defaultYogaStyle.position(YGEdgeRight)), + debugStringConvertibleItem( + "bottom", + yogaStyle.position(YGEdgeBottom), + defaultYogaStyle.position(YGEdgeBottom)), + debugStringConvertibleItem( + "start", + yogaStyle.position(YGEdgeStart), + defaultYogaStyle.position(YGEdgeStart)), debugStringConvertibleItem( - "position", yogaStyle.position(), defaultYogaStyle.position()), + "end", + yogaStyle.position(YGEdgeEnd), + defaultYogaStyle.position(YGEdgeEnd)), debugStringConvertibleItem( - "padding", yogaStyle.padding(), defaultYogaStyle.padding()), + "inseInline", + yogaStyle.position(YGEdgeHorizontal), + defaultYogaStyle.position(YGEdgeHorizontal)), debugStringConvertibleItem( - "border", yogaStyle.border(), defaultYogaStyle.border()), + "insetBlock", + yogaStyle.position(YGEdgeVertical), + defaultYogaStyle.position(YGEdgeVertical)), + debugStringConvertibleItem( + "inset", + yogaStyle.position(YGEdgeAll), + defaultYogaStyle.position(YGEdgeAll)), + debugStringConvertibleItem( + "paddingLeft", + yogaStyle.padding(YGEdgeLeft), + defaultYogaStyle.padding(YGEdgeLeft)), + debugStringConvertibleItem( + "paddingTop", + yogaStyle.padding(YGEdgeTop), + defaultYogaStyle.padding(YGEdgeTop)), + debugStringConvertibleItem( + "paddingRight", + yogaStyle.padding(YGEdgeRight), + defaultYogaStyle.padding(YGEdgeRight)), + debugStringConvertibleItem( + "paddingBottom", + yogaStyle.padding(YGEdgeBottom), + defaultYogaStyle.padding(YGEdgeBottom)), + debugStringConvertibleItem( + "paddingStart", + yogaStyle.padding(YGEdgeStart), + defaultYogaStyle.padding(YGEdgeStart)), + debugStringConvertibleItem( + "paddingEnd", + yogaStyle.padding(YGEdgeEnd), + defaultYogaStyle.padding(YGEdgeEnd)), + debugStringConvertibleItem( + "paddingHorizontal", + yogaStyle.padding(YGEdgeHorizontal), + defaultYogaStyle.padding(YGEdgeHorizontal)), + debugStringConvertibleItem( + "paddingVertical", + yogaStyle.padding(YGEdgeVertical), + defaultYogaStyle.padding(YGEdgeVertical)), + debugStringConvertibleItem( + "padding", + yogaStyle.padding(YGEdgeAll), + defaultYogaStyle.padding(YGEdgeAll)), + debugStringConvertibleItem( + "borderLeftWidth", + yogaStyle.border(YGEdgeLeft), + defaultYogaStyle.border(YGEdgeLeft)), + debugStringConvertibleItem( + "borderTopWidth", + yogaStyle.border(YGEdgeTop), + defaultYogaStyle.border(YGEdgeTop)), + debugStringConvertibleItem( + "borderRightWidth", + yogaStyle.border(YGEdgeRight), + defaultYogaStyle.border(YGEdgeRight)), + debugStringConvertibleItem( + "borderBottomWidth", + yogaStyle.border(YGEdgeBottom), + defaultYogaStyle.border(YGEdgeBottom)), + debugStringConvertibleItem( + "borderStartWidth", + yogaStyle.border(YGEdgeStart), + defaultYogaStyle.border(YGEdgeStart)), + debugStringConvertibleItem( + "borderEndWidth", + yogaStyle.border(YGEdgeEnd), + defaultYogaStyle.border(YGEdgeEnd)), + debugStringConvertibleItem( + "borderHorizontalWidth", + yogaStyle.border(YGEdgeHorizontal), + defaultYogaStyle.border(YGEdgeHorizontal)), + debugStringConvertibleItem( + "borderVerticalWidth", + yogaStyle.border(YGEdgeVertical), + defaultYogaStyle.border(YGEdgeVertical)), + debugStringConvertibleItem( + "bordeWidth", + yogaStyle.border(YGEdgeAll), + defaultYogaStyle.border(YGEdgeAll)), debugStringConvertibleItem( "width", yogaStyle.dimension(yoga::Dimension::Width), @@ -383,18 +412,6 @@ void YogaStylableProps::convertRawPropAliases( const PropsParserContext& context, const YogaStylableProps& sourceProps, const RawProps& rawProps) { - inset = convertRawProp( - context, - rawProps, - "inset", - sourceProps.inset, - CompactValue::ofUndefined()); - insetBlock = convertRawProp( - context, - rawProps, - "insetBlock", - sourceProps.insetBlock, - CompactValue::ofUndefined()); insetBlockEnd = convertRawProp( context, rawProps, @@ -407,12 +424,6 @@ void YogaStylableProps::convertRawPropAliases( "insetBlockStart", sourceProps.insetBlockStart, CompactValue::ofUndefined()); - insetInline = convertRawProp( - context, - rawProps, - "insetInline", - sourceProps.insetInline, - CompactValue::ofUndefined()); insetInlineEnd = convertRawProp( context, rawProps, @@ -500,4 +511,4 @@ void YogaStylableProps::convertRawPropAliases( CompactValue::ofUndefined()); } -} // namespace facebook::react +} // namespace facebook::react \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/conversions.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/conversions.h deleted file mode 100644 index b2e8febb602..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/conversions.h +++ /dev/null @@ -1,894 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace facebook::react { - -/* - * Yoga's `float` <-> React Native's `Float` (can be `double` or `float`) - * - * Regular Yoga `float` values represent some onscreen-position-related values. - * They can be real numbers or special value `YGUndefined` (which actually is - * `NaN`). Conceptually, layout computation process inside Yoga should never - * produce `NaN` values from non-`NaN` values. At the same time, ` YGUndefined` - * values have special "no limit" meaning in Yoga, therefore ` YGUndefined` - * usually corresponds to `Infinity` value. - */ -inline Float floatFromYogaFloat(float value) { - static_assert( - YGUndefined != YGUndefined, - "The code of this function assumes that YGUndefined is NaN."); - if (std::isnan(value) /* means: `value == YGUndefined` */) { - return std::numeric_limits::infinity(); - } - - return (Float)value; -} - -inline float yogaFloatFromFloat(Float value) { - if (!std::isfinite(value)) { - return YGUndefined; - } - - return (float)value; -} - -/* - * `yoga::FloatOptional` <-> React Native's `Float` - * - * `yoga::FloatOptional` represents optional dimensionless float values in Yoga - * Style object (e.g. `flex`). The most suitable analogy to empty - * `yoga::FloatOptional` is `NaN` value. - * `yoga::FloatOptional` values are usually parsed from some outside data source - * which usually has some special corresponding representation for an empty - * value. - */ -inline Float floatFromYogaOptionalFloat(yoga::FloatOptional value) { - if (value.isUndefined()) { - return std::numeric_limits::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 optionalFloatFromYogaValue( - const YGValue value, - std::optional base = {}) { - switch (value.unit) { - case YGUnitUndefined: - return {}; - case YGUnitPoint: - return floatFromYogaFloat(value.value); - case YGUnitPercent: - return base.has_value() - ? std::optional(base.value() * floatFromYogaFloat(value.value)) - : std::optional(); - case YGUnitAuto: - return {}; - } -} - -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 = - yogaNode.getStyle().display() == yoga::Display::None ? DisplayType::None - : DisplayType::Flex; - - 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()); - if (!value.hasType()) { - 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 Direction:" << stringValue; - react_native_expect(false); -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::FlexDirection& result) { - result = yoga::FlexDirection::Column; - react_native_expect(value.hasType()); - if (!value.hasType()) { - 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; - react_native_expect(false); -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::Justify& result) { - result = yoga::Justify::FlexStart; - react_native_expect(value.hasType()); - if (!value.hasType()) { - 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; - react_native_expect(false); -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::Align& result) { - result = yoga::Align::Stretch; - react_native_expect(value.hasType()); - if (!value.hasType()) { - 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; - } - 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()); - if (!value.hasType()) { - 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; - react_native_expect(false); -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::Wrap& result) { - result = yoga::Wrap::NoWrap; - react_native_expect(value.hasType()); - if (!value.hasType()) { - 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; - react_native_expect(false); -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::Overflow& result) { - result = yoga::Overflow::Visible; - react_native_expect(value.hasType()); - if (!value.hasType()) { - 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()); - if (!value.hasType()) { - return; - } - auto stringValue = (std::string)value; - if (stringValue == "flex") { - result = yoga::Display::Flex; - return; - } - if (stringValue == "none") { - result = yoga::Display::None; - return; - } - LOG(ERROR) << "Could not parse yoga::Display:" << stringValue; - react_native_expect(false); -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::Style::ValueRepr& result) { - if (value.hasType()) { - result = yoga::CompactValue::ofMaybe((float)value); - return; - } else if (value.hasType()) { - const auto stringValue = (std::string)value; - if (stringValue == "auto") { - result = YGValueAuto; - return; - } else { - if (stringValue.back() == '%') { - auto tryValue = folly::tryTo( - std::string_view(stringValue).substr(0, stringValue.length() - 1)); - if (tryValue.hasValue()) { - result = YGValue{tryValue.value(), YGUnitPercent}; - return; - } - } else { - auto tryValue = folly::tryTo(stringValue); - if (tryValue.hasValue()) { - result = YGValue{tryValue.value(), YGUnitPoint}; - return; - } - } - } - } - result = YGValueUndefined; -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - YGValue& result) { - yoga::Style::ValueRepr ygValue{}; - fromRawValue(context, value, ygValue); - result = ygValue; -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - yoga::FloatOptional& result) { - result = value.hasType() ? yoga::FloatOptional((float)value) - : yoga::FloatOptional(); -} - -inline Float toRadians( - const RawValue& value, - std::optional defaultValue) { - if (value.hasType()) { - return (Float)value; - } - react_native_expect(value.hasType()); - if (!value.hasType() && defaultValue.has_value()) { - return *defaultValue; - } - auto stringValue = (std::string)value; - char* suffixStart; - double num = strtod( - stringValue.c_str(), &suffixStart); // can't use std::stod, probably - // because of old Android NDKs - if (0 == strncmp(suffixStart, "deg", 3)) { - return static_cast(num * M_PI / 180.0f); - } - return static_cast(num); // assume suffix is "rad" -} - -inline void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - Transform& result) { - auto transformMatrix = Transform{}; - react_native_expect(value.hasType>()); - if (!value.hasType>()) { - result = transformMatrix; - return; - } - - auto configurations = static_cast>(value); - for (const auto& configuration : configurations) { - if (!configuration.hasType>()) { - // TODO: The following checks have to be removed after codegen is shipped. - // See T45151459. - continue; - } - - auto configurationPair = - static_cast>(configuration); - auto pair = configurationPair.begin(); - auto operation = pair->first; - auto& parameters = pair->second; - - if (operation == "matrix") { - react_native_expect(parameters.hasType>()); - auto numbers = (std::vector)parameters; - react_native_expect(numbers.size() == transformMatrix.matrix.size()); - auto i = 0; - for (auto number : numbers) { - transformMatrix.matrix[i++] = number; - } - transformMatrix.operations.push_back( - TransformOperation{TransformOperationType::Arbitrary, 0, 0, 0}); - } else if (operation == "perspective") { - transformMatrix = - transformMatrix * Transform::Perspective((Float)parameters); - } else if (operation == "rotateX") { - transformMatrix = transformMatrix * - Transform::Rotate(toRadians(parameters, 0.0f), 0, 0); - } else if (operation == "rotateY") { - transformMatrix = transformMatrix * - Transform::Rotate(0, toRadians(parameters, 0.0f), 0); - } else if (operation == "rotateZ" || operation == "rotate") { - transformMatrix = transformMatrix * - Transform::Rotate(0, 0, toRadians(parameters, 0.0f)); - } else if (operation == "scale") { - auto number = (Float)parameters; - transformMatrix = - transformMatrix * Transform::Scale(number, number, number); - } else if (operation == "scaleX") { - transformMatrix = - transformMatrix * Transform::Scale((Float)parameters, 1, 1); - } else if (operation == "scaleY") { - transformMatrix = - transformMatrix * Transform::Scale(1, (Float)parameters, 1); - } else if (operation == "scaleZ") { - transformMatrix = - transformMatrix * Transform::Scale(1, 1, (Float)parameters); - } else if (operation == "translate") { - auto numbers = (std::vector)parameters; - transformMatrix = transformMatrix * - Transform::Translate(numbers.at(0), numbers.at(1), 0); - } else if (operation == "translateX") { - transformMatrix = - transformMatrix * Transform::Translate((Float)parameters, 0, 0); - } else if (operation == "translateY") { - transformMatrix = - transformMatrix * Transform::Translate(0, (Float)parameters, 0); - } else if (operation == "skewX") { - transformMatrix = - transformMatrix * Transform::Skew(toRadians(parameters, 0.0f), 0); - } else if (operation == "skewY") { - transformMatrix = - transformMatrix * Transform::Skew(0, toRadians(parameters, 0.0f)); - } - } - - result = transformMatrix; -} - -inline void fromRawValue( - const PropsParserContext& /*context*/, - const RawValue& value, - TransformOrigin& result) { - react_native_expect(value.hasType>()); - auto origins = (std::vector)value; - - TransformOrigin transformOrigin; - - const size_t maxIndex = 2; - - for (size_t i = 0; i < std::min(origins.size(), maxIndex); i++) { - const auto& origin = origins[i]; - if (origin.hasType()) { - auto originFloat = (float)origin; - if (std::isfinite(originFloat)) { - transformOrigin.xy[i] = ValueUnit(originFloat, UnitType::Point); - } else { - transformOrigin.xy[i] = ValueUnit(0.0f, UnitType::Undefined); - } - } else if (origin.hasType()) { - const auto stringValue = (std::string)origin; - - if (stringValue.back() == '%') { - auto tryValue = folly::tryTo( - std::string_view(stringValue).substr(0, stringValue.length() - 1)); - if (tryValue.hasValue()) { - transformOrigin.xy[i] = - ValueUnit(tryValue.value(), UnitType::Percent); - } - } - } - } - - if (origins.size() >= 3 && origins[2].hasType()) { - 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()); - if (!value.hasType()) { - 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 void fromRawValue( - const PropsParserContext& context, - const RawValue& value, - BackfaceVisibility& result) { - result = BackfaceVisibility::Auto; - react_native_expect(value.hasType()); - if (!value.hasType()) { - 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()); - if (!value.hasType()) { - 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()); - if (!value.hasType()) { - 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, - LayoutConformance& result) { - result = LayoutConformance::Classic; - react_native_expect(value.hasType()); - if (!value.hasType()) { - return; - } - auto stringValue = (std::string)value; - if (stringValue == "classic") { - result = LayoutConformance::Classic; - return; - } - if (stringValue == "strict") { - result = LayoutConformance::Strict; - return; - } - LOG(ERROR) << "Could not parse LayoutConformance:" << stringValue; - react_native_expect(false); -} - -template -inline std::string toString(const std::array 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) { - switch (value) { - case yoga::Direction::Inherit: - return "inherit"; - case yoga::Direction::LTR: - return "ltr"; - case yoga::Direction::RTL: - return "rtl"; - } -} - -inline std::string toString(const yoga::FlexDirection& value) { - switch (value) { - case yoga::FlexDirection::Column: - return "column"; - case yoga::FlexDirection::ColumnReverse: - return "column-reverse"; - case yoga::FlexDirection::Row: - return "row"; - case yoga::FlexDirection::RowReverse: - return "row-reverse"; - } -} - -inline std::string toString(const yoga::Justify& value) { - switch (value) { - case yoga::Justify::FlexStart: - return "flex-start"; - case yoga::Justify::Center: - return "center"; - case yoga::Justify::FlexEnd: - return "flex-end"; - case yoga::Justify::SpaceBetween: - return "space-between"; - case yoga::Justify::SpaceAround: - return "space-around"; - case yoga::Justify::SpaceEvenly: - return "space-evenly"; - } -} - -inline std::string toString(const yoga::Align& value) { - switch (value) { - case yoga::Align::Auto: - return "auto"; - case yoga::Align::FlexStart: - return "flex-start"; - case yoga::Align::Center: - return "center"; - case yoga::Align::FlexEnd: - return "flex-end"; - case yoga::Align::Stretch: - return "stretch"; - case yoga::Align::Baseline: - return "baseline"; - case yoga::Align::SpaceBetween: - return "space-between"; - case yoga::Align::SpaceAround: - return "space-around"; - } -} - -inline std::string toString(const yoga::PositionType& value) { - switch (value) { - case yoga::PositionType::Static: - return "static"; - case yoga::PositionType::Relative: - return "relative"; - case yoga::PositionType::Absolute: - return "absolute"; - } -} - -inline std::string toString(const yoga::Wrap& value) { - switch (value) { - case yoga::Wrap::NoWrap: - return "no-wrap"; - case yoga::Wrap::Wrap: - return "wrap"; - case yoga::Wrap::WrapReverse: - return "wrap-reverse"; - } -} - -inline std::string toString(const yoga::Overflow& value) { - switch (value) { - case yoga::Overflow::Visible: - return "visible"; - case yoga::Overflow::Scroll: - return "scroll"; - case yoga::Overflow::Hidden: - return "hidden"; - } -} - -inline std::string toString(const yoga::Display& value) { - switch (value) { - case yoga::Display::Flex: - return "flex"; - case yoga::Display::None: - return "none"; - } -} - -inline std::string toString(const YGValue& value) { - switch (value.unit) { - case YGUnitUndefined: - return "undefined"; - case YGUnitPoint: - return folly::to(value.value); - case YGUnitPercent: - return folly::to(value.value) + "%"; - case YGUnitAuto: - return "auto"; - } -} - -inline std::string toString(const yoga::FloatOptional& value) { - if (value.isUndefined()) { - return "undefined"; - } - - return folly::to(floatFromYogaFloat(value.unwrap())); -} - -inline std::string toString(const yoga::Style::Dimensions& value) { - return "{" + toString(value[0]) + ", " + toString(value[1]) + "}"; -} - -inline std::string toString(const yoga::Style::Edges& value) { - static std::array names = { - {"left", - "top", - "right", - "bottom", - "start", - "end", - "horizontal", - "vertical", - "all"}}; - - auto result = std::string{}; - auto separator = std::string{", "}; - - for (size_t i = 0; i < names.size(); i++) { - YGValue v = value[i]; - if (v.unit == YGUnitUndefined) { - continue; - } - result += names[i] + ": " + toString(v) + separator; - } - - if (!result.empty()) { - result.erase(result.length() - separator.length()); - } - - return "{" + result + "}"; -} - -inline std::string toString(const LayoutConformance& value) { - switch (value) { - case LayoutConformance::Undefined: - return "undefined"; - case LayoutConformance::Classic: - return "classic"; - case LayoutConformance::Strict: - return "strict"; - } -} - -} // namespace facebook::react diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/graphics/Color.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/graphics/Color.h deleted file mode 100644 index c3ae69eaa28..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/graphics/Color.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include - -#include -#include - -namespace facebook::react { - -/* - * On Android, a color can be represented as 32 bits integer, so there is no - * need to instantiate complex color objects and then pass them as shared - * pointers. Hense instead of using shared_ptr, we use a simple wrapper class - * which provides a pointer-like interface. On other platforms, colors may be - * represented by more complex objects that cannot be represented as 32-bits - * integers, so we hide the implementation detail in HostPlatformColor.h. - */ -class SharedColor { - public: - SharedColor() : color_(HostPlatformColor::UndefinedColor) {} - - SharedColor(Color color) : color_(color) {} - - 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; - } - - private: - Color color_; -}; - -bool isColorMeaningful(const SharedColor& color) noexcept; -SharedColor colorFromComponents(ColorComponents components); -ColorComponents colorComponentsFromColor(SharedColor color); - -SharedColor clearColor(); -SharedColor blackColor(); -SharedColor whiteColor(); - -} // namespace facebook::react - -template <> -struct std::hash { - size_t operator()(facebook::react::SharedColor color) const { - return std::hash{}(*color); - } -}; diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManagerBinding.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManagerBinding.cpp index 381c25a2f0a..2e0d4d7333f 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManagerBinding.cpp +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManagerBinding.cpp @@ -230,23 +230,27 @@ jsi::Value UIManagerBinding::get( const jsi::Value& /*thisValue*/, const jsi::Value* arguments, size_t count) -> jsi::Value { - validateArgumentCount(runtime, methodName, paramCount, count); - - auto instanceHandle = - instanceHandleFromValue(runtime, arguments[4], arguments[0]); - if (!instanceHandle) { - react_native_assert(false); - return jsi::Value::undefined(); + try { + validateArgumentCount(runtime, methodName, paramCount, count); + + auto instanceHandle = + instanceHandleFromValue(runtime, arguments[4], arguments[0]); + if (!instanceHandle) { + react_native_assert(false); + return jsi::Value::undefined(); + } + + return valueFromShadowNode( + runtime, + uiManager->createNode( + tagFromValue(arguments[0]), + stringFromValue(runtime, arguments[1]), + surfaceIdFromValue(runtime, arguments[2]), + RawProps(runtime, arguments[3]), + std::move(instanceHandle))); + } catch (const std::logic_error& ex) { + LOG(FATAL) << "logic_error in createNode: " << ex.what(); } - - return valueFromShadowNode( - runtime, - uiManager->createNode( - tagFromValue(arguments[0]), - stringFromValue(runtime, arguments[1]), - surfaceIdFromValue(runtime, arguments[2]), - RawProps(runtime, arguments[3]), - std::move(instanceHandle))); }); } @@ -267,7 +271,9 @@ jsi::Value UIManagerBinding::get( return valueFromShadowNode( runtime, uiManager->cloneNode( - *shadowNodeFromValue(runtime, arguments[0]))); + *shadowNodeFromValue(runtime, arguments[0]), + nullptr, + RawProps())); }); } @@ -347,7 +353,8 @@ jsi::Value UIManagerBinding::get( uiManager->cloneNode( *shadowNodeFromValue(runtime, arguments[0]), count > 1 ? shadowNodeListFromValue(runtime, arguments[1]) - : ShadowNode::emptySharedShadowNodeSharedList())); + : ShadowNode::emptySharedShadowNodeSharedList(), + RawProps())); }); } @@ -365,13 +372,12 @@ jsi::Value UIManagerBinding::get( size_t count) -> jsi::Value { validateArgumentCount(runtime, methodName, paramCount, count); - RawProps rawProps(runtime, arguments[1]); return valueFromShadowNode( runtime, uiManager->cloneNode( *shadowNodeFromValue(runtime, arguments[0]), nullptr, - &rawProps)); + RawProps(runtime, arguments[1]))); }); } @@ -392,7 +398,6 @@ jsi::Value UIManagerBinding::get( // validateArgumentCount(runtime, methodName, paramCount, count); bool hasChildrenArg = count == 3; - RawProps rawProps(runtime, arguments[hasChildrenArg ? 2 : 1]); return valueFromShadowNode( runtime, uiManager->cloneNode( @@ -400,7 +405,7 @@ jsi::Value UIManagerBinding::get( hasChildrenArg ? shadowNodeListFromValue(runtime, arguments[1]) : ShadowNode::emptySharedShadowNodeSharedList(), - &rawProps)); + RawProps(runtime, arguments[hasChildrenArg ? 2 : 1]))); }); } diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/enums/YogaEnums.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/enums/YogaEnums.h index 17a503622b5..afc1b5f5e05 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/enums/YogaEnums.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/enums/YogaEnums.h @@ -7,6 +7,7 @@ #pragma once +#include #include namespace facebook::yoga { @@ -14,14 +15,60 @@ namespace facebook::yoga { template constexpr inline int32_t ordinalCount(); +/** + * Count of bits needed to represent every ordinal + */ template constexpr inline int32_t bitCount(); -// Polyfill of C++ 23 to_underlying() -// https://en.cppreference.com/w/cpp/utility/to_underlying +/** + * Polyfill of C++ 23 to_underlying() + * https://en.cppreference.com/w/cpp/utility/to_underlying + */ template constexpr auto to_underlying(T e) noexcept { return static_cast>(e); } +/** + * Convenience function to iterate through every value in a Yoga enum as part of + * a range-based for loop. + */ +template +auto ordinals() { + struct Iterator { + EnumT e{}; + + EnumT operator*() const { + return e; + } + + Iterator& operator++() { + e = static_cast(to_underlying(e) + 1); + return *this; + } + + // [Windows C++20 fix ##12195 + bool operator==(const Iterator& other) const { + return e == other.e; + } + + bool operator!=(const Iterator& other) const { + return e != other.e; + } + // Windows] + }; + + struct Range { + Iterator begin() const { + return Iterator{}; + } + Iterator end() const { + return Iterator{static_cast(ordinalCount())}; + } + }; + + return Range{}; +} + } // namespace facebook::yoga diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.cpp deleted file mode 100644 index e69c96f5aed..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.cpp +++ /dev/null @@ -1,689 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include -#include -#include - -#include -#include -#include -#include -#include - -namespace facebook::yoga { - -Node::Node() : Node{&Config::getDefault()} {} - -Node::Node(const yoga::Config* config) : config_{config} { - yoga::assertFatal( - config != nullptr, "Attempting to construct Node with null config"); - - if (config->useWebDefaults()) { - useWebDefaults(); - } -} - -Node::Node(Node&& node) { - hasNewLayout_ = node.hasNewLayout_; - isReferenceBaseline_ = node.isReferenceBaseline_; - isDirty_ = node.isDirty_; - nodeType_ = node.nodeType_; - context_ = node.context_; - measureFunc_ = node.measureFunc_; - baselineFunc_ = node.baselineFunc_; - printFunc_ = node.printFunc_; - dirtiedFunc_ = node.dirtiedFunc_; - style_ = node.style_; - layout_ = node.layout_; - lineIndex_ = node.lineIndex_; - owner_ = node.owner_; - children_ = std::move(node.children_); - config_ = node.config_; - resolvedDimensions_ = node.resolvedDimensions_; - for (auto c : children_) { - c->setOwner(this); - } -} - -void Node::print() { - if (printFunc_ != nullptr) { - printFunc_(this); - } -} - -CompactValue Node::computeEdgeValueForRow( - const Style::Edges& edges, - YGEdge rowEdge, - YGEdge edge) { - if (edges[rowEdge].isDefined()) { - return edges[rowEdge]; - } else if (edges[edge].isDefined()) { - return edges[edge]; - } else if (edges[YGEdgeHorizontal].isDefined()) { - return edges[YGEdgeHorizontal]; - } else { - return edges[YGEdgeAll]; - } -} - -CompactValue Node::computeEdgeValueForColumn( - const Style::Edges& edges, - YGEdge edge) { - if (edges[edge].isDefined()) { - return edges[edge]; - } else if (edges[YGEdgeVertical].isDefined()) { - return edges[YGEdgeVertical]; - } else { - return edges[YGEdgeAll]; - } -} - -YGEdge Node::getInlineStartEdgeUsingErrata( - FlexDirection flexDirection, - Direction direction) const { - return hasErrata(Errata::StartingEndingEdgeFromFlexDirection) - ? flexStartEdge(flexDirection) - : inlineStartEdge(flexDirection, direction); -} - -YGEdge Node::getInlineEndEdgeUsingErrata( - FlexDirection flexDirection, - Direction direction) const { - return hasErrata(Errata::StartingEndingEdgeFromFlexDirection) - ? flexEndEdge(flexDirection) - : inlineEndEdge(flexDirection, direction); -} - -bool Node::isFlexStartPositionDefined(FlexDirection axis) const { - const YGEdge startEdge = flexStartEdge(axis); - auto leadingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.position(), startEdge); - - return leadingPosition.isDefined(); -} - -bool Node::isInlineStartPositionDefined(FlexDirection axis, Direction direction) - const { - const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.position(), startEdge); - - return leadingPosition.isDefined(); -} - -bool Node::isFlexEndPositionDefined(FlexDirection axis) const { - const YGEdge endEdge = flexEndEdge(axis); - auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.position(), endEdge); - - return !trailingPosition.isUndefined(); -} - -bool Node::isInlineEndPositionDefined(FlexDirection axis, Direction direction) - const { - const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.position(), endEdge); - - return trailingPosition.isDefined(); -} - -float Node::getFlexStartPosition(FlexDirection axis, float axisSize) const { - const YGEdge startEdge = flexStartEdge(axis); - auto leadingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.position(), startEdge); - - return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineStartPosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.position(), startEdge); - - return resolveValue(leadingPosition, axisSize).unwrapOrDefault(0.0f); -} - -float Node::getFlexEndPosition(FlexDirection axis, float axisSize) const { - const YGEdge endEdge = flexEndEdge(axis); - auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.position(), endEdge); - - return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineEndPosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingPosition = isRow(axis) - ? computeEdgeValueForRow(style_.position(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.position(), endEdge); - - return resolveValue(trailingPosition, axisSize).unwrapOrDefault(0.0f); -} - -float Node::getFlexStartMargin(FlexDirection axis, float widthSize) const { - const YGEdge startEdge = flexStartEdge(axis); - auto leadingMargin = isRow(axis) - ? computeEdgeValueForRow(style_.margin(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.margin(), startEdge); - - return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineStartMargin( - FlexDirection axis, - Direction direction, - float widthSize) const { - const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingMargin = isRow(axis) - ? computeEdgeValueForRow(style_.margin(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.margin(), startEdge); - - return resolveValue(leadingMargin, widthSize).unwrapOrDefault(0.0f); -} - -float Node::getFlexEndMargin(FlexDirection axis, float widthSize) const { - const YGEdge endEdge = flexEndEdge(axis); - auto trailingMargin = isRow(axis) - ? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.margin(), endEdge); - - return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineEndMargin( - FlexDirection axis, - Direction direction, - float widthSize) const { - const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingMargin = isRow(axis) - ? computeEdgeValueForRow(style_.margin(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.margin(), endEdge); - - return resolveValue(trailingMargin, widthSize).unwrapOrDefault(0.0f); -} - -float Node::getInlineStartBorder(FlexDirection axis, Direction direction) - const { - const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - YGValue leadingBorder = isRow(axis) - ? computeEdgeValueForRow(style_.border(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.border(), startEdge); - - return maxOrDefined(leadingBorder.value, 0.0f); -} - -float Node::getFlexStartBorder(FlexDirection axis, Direction direction) const { - const YGEdge leadRelativeFlexItemEdge = - flexStartRelativeEdge(axis, direction); - YGValue leadingBorder = isRow(axis) - ? computeEdgeValueForRow( - style_.border(), leadRelativeFlexItemEdge, flexStartEdge(axis)) - : computeEdgeValueForColumn(style_.border(), flexStartEdge(axis)); - - return maxOrDefined(leadingBorder.value, 0.0f); -} - -float Node::getInlineEndBorder(FlexDirection axis, Direction direction) const { - const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - YGValue trailingBorder = isRow(axis) - ? computeEdgeValueForRow(style_.border(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.border(), endEdge); - - return maxOrDefined(trailingBorder.value, 0.0f); -} - -float Node::getFlexEndBorder(FlexDirection axis, Direction direction) const { - const YGEdge trailRelativeFlexItemEdge = flexEndRelativeEdge(axis, direction); - YGValue trailingBorder = isRow(axis) - ? computeEdgeValueForRow( - style_.border(), trailRelativeFlexItemEdge, flexEndEdge(axis)) - : computeEdgeValueForColumn(style_.border(), flexEndEdge(axis)); - - return maxOrDefined(trailingBorder.value, 0.0f); -} - -float Node::getInlineStartPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - const YGEdge startEdge = getInlineStartEdgeUsingErrata(axis, direction); - auto leadingPadding = isRow(axis) - ? computeEdgeValueForRow(style_.padding(), YGEdgeStart, startEdge) - : computeEdgeValueForColumn(style_.padding(), startEdge); - - return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f); -} - -float Node::getFlexStartPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - const YGEdge leadRelativeFlexItemEdge = - flexStartRelativeEdge(axis, direction); - auto leadingPadding = isRow(axis) - ? computeEdgeValueForRow( - style_.padding(), leadRelativeFlexItemEdge, flexStartEdge(axis)) - : computeEdgeValueForColumn(style_.padding(), flexStartEdge(axis)); - - return maxOrDefined(resolveValue(leadingPadding, widthSize).unwrap(), 0.0f); -} - -float Node::getInlineEndPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - const YGEdge endEdge = getInlineEndEdgeUsingErrata(axis, direction); - auto trailingPadding = isRow(axis) - ? computeEdgeValueForRow(style_.padding(), YGEdgeEnd, endEdge) - : computeEdgeValueForColumn(style_.padding(), endEdge); - - return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f); -} - -float Node::getFlexEndPadding( - FlexDirection axis, - Direction direction, - float widthSize) const { - const YGEdge trailRelativeFlexItemEdge = flexEndRelativeEdge(axis, direction); - auto trailingPadding = isRow(axis) - ? computeEdgeValueForRow( - style_.padding(), trailRelativeFlexItemEdge, flexEndEdge(axis)) - : computeEdgeValueForColumn(style_.padding(), flexEndEdge(axis)); - - return maxOrDefined(resolveValue(trailingPadding, widthSize).unwrap(), 0.0f); -} - -float Node::getInlineStartPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getInlineStartPadding(axis, direction, widthSize) + - getInlineStartBorder(axis, direction); -} - -float Node::getFlexStartPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getFlexStartPadding(axis, direction, widthSize) + - getFlexStartBorder(axis, direction); -} - -float Node::getInlineEndPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getInlineEndPadding(axis, direction, widthSize) + - getInlineEndBorder(axis, direction); -} - -float Node::getFlexEndPaddingAndBorder( - FlexDirection axis, - Direction direction, - float widthSize) const { - return getFlexEndPadding(axis, direction, widthSize) + - getFlexEndBorder(axis, direction); -} - -float Node::getMarginForAxis(FlexDirection axis, float widthSize) const { - // The total margin for a given axis does not depend on the direction - // so hardcoding LTR here to avoid piping direction to this function - return getInlineStartMargin(axis, Direction::LTR, widthSize) + - getInlineEndMargin(axis, Direction::LTR, widthSize); -} - -float Node::getGapForAxis(FlexDirection axis) const { - auto gap = isRow(axis) ? style_.resolveColumnGap() : style_.resolveRowGap(); - // TODO: Validate percentage gap, and expose ability to set percentage to - // public API - return maxOrDefined(resolveValue(gap, 0.0f /*ownerSize*/).unwrap(), 0.0f); -} - -YGSize Node::measure( - float width, - MeasureMode widthMode, - float height, - MeasureMode heightMode) { - return measureFunc_( - this, width, unscopedEnum(widthMode), height, unscopedEnum(heightMode)); -} - -float Node::baseline(float width, float height) const { - return baselineFunc_(this, width, height); -} - -// Setters - -void Node::setMeasureFunc(YGMeasureFunc measureFunc) { - if (measureFunc == nullptr) { - // TODO: t18095186 Move nodeType to opt-in function and mark appropriate - // places in Litho - setNodeType(NodeType::Default); - } else { - yoga::assertFatalWithNode( - this, - children_.size() == 0, - "Cannot set measure function: Nodes with measure functions cannot have " - "children."); - // TODO: t18095186 Move nodeType to opt-in function and mark appropriate - // places in Litho - setNodeType(NodeType::Text); - } - - measureFunc_ = measureFunc; -} - -void Node::replaceChild(Node* child, size_t index) { - children_[index] = child; -} - -void Node::replaceChild(Node* oldChild, Node* newChild) { - std::replace(children_.begin(), children_.end(), oldChild, newChild); -} - -void Node::insertChild(Node* child, size_t index) { - children_.insert(children_.begin() + static_cast(index), child); -} - -void Node::setConfig(yoga::Config* config) { - yoga::assertFatal( - config != nullptr, "Attempting to set a null config on a Node"); - yoga::assertFatalWithConfig( - config, - config->useWebDefaults() == config_->useWebDefaults(), - "UseWebDefaults may not be changed after constructing a Node"); - - if (yoga::configUpdateInvalidatesLayout(*config_, *config)) { - markDirtyAndPropagate(); - } - - config_ = config; -} - -void Node::setDirty(bool isDirty) { - if (isDirty == isDirty_) { - return; - } - isDirty_ = isDirty; - if (isDirty && dirtiedFunc_) { - dirtiedFunc_(this); - } -} - -bool Node::removeChild(Node* child) { - std::vector::iterator p = - std::find(children_.begin(), children_.end(), child); - if (p != children_.end()) { - children_.erase(p); - return true; - } - return false; -} - -void Node::removeChild(size_t index) { - children_.erase(children_.begin() + static_cast(index)); -} - -void Node::setLayoutDirection(Direction direction) { - layout_.setDirection(direction); -} - -void Node::setLayoutMargin(float margin, YGEdge edge) { - assertFatal( - edge < static_cast(layout_.margin.size()), - "Edge must be top/left/bottom/right"); - layout_.margin[edge] = margin; -} - -void Node::setLayoutBorder(float border, YGEdge edge) { - assertFatal( - edge < static_cast(layout_.border.size()), - "Edge must be top/left/bottom/right"); - layout_.border[edge] = border; -} - -void Node::setLayoutPadding(float padding, YGEdge edge) { - assertFatal( - edge < static_cast(layout_.padding.size()), - "Edge must be top/left/bottom/right"); - layout_.padding[edge] = padding; -} - -void Node::setLayoutLastOwnerDirection(Direction direction) { - layout_.lastOwnerDirection = direction; -} - -void Node::setLayoutComputedFlexBasis(const FloatOptional computedFlexBasis) { - layout_.computedFlexBasis = computedFlexBasis; -} - -void Node::setLayoutPosition(float position, YGEdge edge) { - assertFatal( - edge < static_cast(layout_.position.size()), - "Edge must be top/left/bottom/right"); - layout_.position[edge] = position; -} - -void Node::setLayoutComputedFlexBasisGeneration( - uint32_t computedFlexBasisGeneration) { - layout_.computedFlexBasisGeneration = computedFlexBasisGeneration; -} - -void Node::setLayoutMeasuredDimension( - float measuredDimension, - Dimension dimension) { - layout_.setMeasuredDimension(dimension, measuredDimension); -} - -void Node::setLayoutHadOverflow(bool hadOverflow) { - layout_.setHadOverflow(hadOverflow); -} - -void Node::setLayoutDimension(float dimensionValue, Dimension dimension) { - layout_.setDimension(dimension, dimensionValue); -} - -// If both left and right are defined, then use left. Otherwise return +left or -// -right depending on which is defined. -float Node::relativePosition( - FlexDirection axis, - Direction direction, - float axisSize) const { - if (isInlineStartPositionDefined(axis, direction)) { - return getInlineStartPosition(axis, direction, axisSize); - } - - return -1 * getInlineEndPosition(axis, direction, axisSize); -} - -void Node::setPosition( - const Direction direction, - const float mainSize, - const float crossSize, - const float ownerWidth) { - /* Root nodes should be always layouted as LTR, so we don't return negative - * values. */ - const Direction directionRespectingRoot = - owner_ != nullptr ? direction : Direction::LTR; - const FlexDirection mainAxis = - yoga::resolveDirection(style_.flexDirection(), directionRespectingRoot); - const FlexDirection crossAxis = - yoga::resolveCrossDirection(mainAxis, directionRespectingRoot); - - // Here we should check for `PositionType::Static` and in this case zero inset - // properties (left, right, top, bottom, begin, end). - // https://www.w3.org/TR/css-position-3/#valdef-position-static - const float relativePositionMain = - relativePosition(mainAxis, directionRespectingRoot, mainSize); - const float relativePositionCross = - relativePosition(crossAxis, directionRespectingRoot, crossSize); - - const YGEdge mainAxisLeadingEdge = - getInlineStartEdgeUsingErrata(mainAxis, direction); - const YGEdge mainAxisTrailingEdge = - getInlineEndEdgeUsingErrata(mainAxis, direction); - const YGEdge crossAxisLeadingEdge = - getInlineStartEdgeUsingErrata(crossAxis, direction); - const YGEdge crossAxisTrailingEdge = - getInlineEndEdgeUsingErrata(crossAxis, direction); - - setLayoutPosition( - (getInlineStartMargin(mainAxis, direction, ownerWidth) + - relativePositionMain), - mainAxisLeadingEdge); - setLayoutPosition( - (getInlineEndMargin(mainAxis, direction, ownerWidth) + - relativePositionMain), - mainAxisTrailingEdge); - setLayoutPosition( - (getInlineStartMargin(crossAxis, direction, ownerWidth) + - relativePositionCross), - crossAxisLeadingEdge); - setLayoutPosition( - (getInlineEndMargin(crossAxis, direction, ownerWidth) + - relativePositionCross), - crossAxisTrailingEdge); -} - -YGValue Node::getFlexStartMarginValue(FlexDirection axis) const { - if (isRow(axis) && style_.margin()[YGEdgeStart].isDefined()) { - return style_.margin()[YGEdgeStart]; - } else { - return style_.margin()[flexStartEdge(axis)]; - } -} - -YGValue Node::marginTrailingValue(FlexDirection axis) const { - if (isRow(axis) && style_.margin()[YGEdgeEnd].isDefined()) { - return style_.margin()[YGEdgeEnd]; - } else { - return style_.margin()[flexEndEdge(axis)]; - } -} - -YGValue Node::resolveFlexBasisPtr() const { - YGValue flexBasis = style_.flexBasis(); - if (flexBasis.unit != YGUnitAuto && flexBasis.unit != YGUnitUndefined) { - return flexBasis; - } - if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0f) { - return config_->useWebDefaults() ? YGValueAuto : YGValueZero; - } - return YGValueAuto; -} - -void Node::resolveDimension() { - const Style& style = getStyle(); - for (auto dim : {Dimension::Width, Dimension::Height}) { - if (style.maxDimension(dim).isDefined() && - yoga::inexactEquals(style.maxDimension(dim), style.minDimension(dim))) { - resolvedDimensions_[yoga::to_underlying(dim)] = style.maxDimension(dim); - } else { - resolvedDimensions_[yoga::to_underlying(dim)] = style.dimension(dim); - } - } -} - -Direction Node::resolveDirection(const Direction ownerDirection) { - if (style_.direction() == Direction::Inherit) { - return ownerDirection != Direction::Inherit ? ownerDirection - : Direction::LTR; - } else { - return style_.direction(); - } -} - -void Node::clearChildren() { - children_.clear(); - children_.shrink_to_fit(); -} - -// Other Methods - -void Node::cloneChildrenIfNeeded() { - size_t i = 0; - for (Node*& child : children_) { - if (child->getOwner() != this) { - child = resolveRef(config_->cloneNode(child, this, i)); - child->setOwner(this); - } - i += 1; - } -} - -void Node::markDirtyAndPropagate() { - if (!isDirty_) { - setDirty(true); - setLayoutComputedFlexBasis(FloatOptional()); - if (owner_) { - owner_->markDirtyAndPropagate(); - } - } -} - -float Node::resolveFlexGrow() const { - // Root nodes flexGrow should always be 0 - if (owner_ == nullptr) { - return 0.0; - } - if (style_.flexGrow().isDefined()) { - return style_.flexGrow().unwrap(); - } - if (style_.flex().isDefined() && style_.flex().unwrap() > 0.0f) { - return style_.flex().unwrap(); - } - return Style::DefaultFlexGrow; -} - -float Node::resolveFlexShrink() const { - if (owner_ == nullptr) { - return 0.0; - } - if (style_.flexShrink().isDefined()) { - return style_.flexShrink().unwrap(); - } - if (!config_->useWebDefaults() && style_.flex().isDefined() && - style_.flex().unwrap() < 0.0f) { - return -style_.flex().unwrap(); - } - return config_->useWebDefaults() ? Style::WebDefaultFlexShrink - : Style::DefaultFlexShrink; -} - -bool Node::isNodeFlexible() { - return ( - (style_.positionType() != PositionType::Absolute) && - (resolveFlexGrow() != 0 || resolveFlexShrink() != 0)); -} - -void Node::reset() { - yoga::assertFatalWithNode( - this, - children_.size() == 0, - "Cannot reset a node which still has children attached"); - yoga::assertFatalWithNode( - this, owner_ == nullptr, "Cannot reset a node still attached to a owner"); - - *this = Node{getConfig()}; -} - -} // namespace facebook::yoga diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h index eb031e589e3..fec0b9bd3ea 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h @@ -65,6 +65,12 @@ class YG_EXPORT Node : public ::YGNode { style_.alignContent() = Align::Stretch; } + template + CompactValue computeEdgeValueForColumn(YGEdge edge) const; + + template + CompactValue computeEdgeValueForRow(YGEdge rowEdge, YGEdge edge) const; + // DANGER DANGER DANGER! // If the node assigned to has children, we'd either have to deallocate // them (potentially incorrect) or ignore them (danger of leaks). Only ever @@ -189,15 +195,6 @@ class YG_EXPORT Node : public ::YGNode { return resolvedDimensions_[static_cast(dimension)]; } - static CompactValue computeEdgeValueForColumn( - const Style::Edges& edges, - YGEdge edge); - - static CompactValue computeEdgeValueForRow( - const Style::Edges& edges, - YGEdge rowEdge, - YGEdge edge); - // Methods related to positions, margin, padding and border bool isFlexStartPositionDefined(FlexDirection axis) const; bool isInlineStartPositionDefined(FlexDirection axis, Direction direction) diff --git a/vnext/ReactCommon/Yoga.cpp b/vnext/ReactCommon/Yoga.cpp index 7afab29425e..542f6fbbae3 100644 --- a/vnext/ReactCommon/Yoga.cpp +++ b/vnext/ReactCommon/Yoga.cpp @@ -390,19 +390,6 @@ void updateStyle(YGNodeRef node, Ref (Style::*prop)(), T value) { [prop](Style& s, T x) { (s.*prop)() = x; }); } -template -void updateIndexedStyleProp( - YGNodeRef node, - Ref (Style::*prop)(), - Idx idx, - CompactValue value) { - updateStyle( - resolveRef(node), - value, - [idx, prop](Style& s, CompactValue x) { return (s.*prop)()[idx] != x; }, - [idx, prop](Style& s, CompactValue x) { (s.*prop)()[idx] = x; }); -} - template void updateIndexedStyleProp(YGNodeRef node, IdxT idx, CompactValue value) { updateStyle( @@ -555,46 +542,45 @@ void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float points) { auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &Style::position, edge, value); + updateIndexedStyleProp<&Style::position, &Style::setPosition>( + node, edge, value); } void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) { auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &Style::position, edge, value); + updateIndexedStyleProp<&Style::position, &Style::setPosition>( + node, edge, value); } YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().position()[edge]; + return resolveRef(node)->getStyle().position(edge); } void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) { auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp(node, &Style::margin, edge, value); + updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value); } void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float percent) { auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp(node, &Style::margin, edge, value); + updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value); } void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { - updateIndexedStyleProp( - node, &Style::margin, edge, CompactValue::ofAuto()); + updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, CompactValue::ofAuto()); } YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().margin()[edge]; + return resolveRef(node)->getStyle().margin(edge); } void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) { auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp( - node, &Style::padding, edge, value); + updateIndexedStyleProp<&Style::padding, &Style::setPadding>( + node, edge, value); } void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) { auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp( - node, &Style::padding, edge, value); + updateIndexedStyleProp<&Style::padding, &Style::setPadding>( + node, edge, value); } YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().padding()[edge]; + return resolveRef(node)->getStyle().padding(edge); } void YGNodeStyleSetBorder( @@ -602,11 +588,11 @@ void YGNodeStyleSetBorder( const YGEdge edge, const float border) { auto value = CompactValue::ofMaybe(border); - updateIndexedStyleProp(node, &Style::border, edge, value); + updateIndexedStyleProp<&Style::border, &Style::setBorder>(node, edge, value); } float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) { - auto border = resolveRef(node)->getStyle().border()[edge]; + auto border = resolveRef(node)->getStyle().border(edge); if (border.isUndefined() || border.isAuto()) { return YGUndefined; } diff --git a/vnext/codegen/NativeImageLoaderAndroidSpec.g.h b/vnext/codegen/NativeImageLoaderAndroidSpec.g.h index 113f7b3545e..433bc7a116a 100644 --- a/vnext/codegen/NativeImageLoaderAndroidSpec.g.h +++ b/vnext/codegen/NativeImageLoaderAndroidSpec.g.h @@ -13,29 +13,16 @@ namespace Microsoft::ReactNativeSpecs { -struct ImageLoaderAndroidSpec_getSize_returnType { +struct ImageLoaderAndroidSpec_ImageSize { double width; double height; }; -struct ImageLoaderAndroidSpec_getSizeWithHeaders_returnType { - double width; - double height; -}; - - -inline winrt::Microsoft::ReactNative::FieldMap GetStructInfo(ImageLoaderAndroidSpec_getSize_returnType*) noexcept { - winrt::Microsoft::ReactNative::FieldMap fieldMap { - {L"width", &ImageLoaderAndroidSpec_getSize_returnType::width}, - {L"height", &ImageLoaderAndroidSpec_getSize_returnType::height}, - }; - return fieldMap; -} -inline winrt::Microsoft::ReactNative::FieldMap GetStructInfo(ImageLoaderAndroidSpec_getSizeWithHeaders_returnType*) noexcept { +inline winrt::Microsoft::ReactNative::FieldMap GetStructInfo(ImageLoaderAndroidSpec_ImageSize*) noexcept { winrt::Microsoft::ReactNative::FieldMap fieldMap { - {L"width", &ImageLoaderAndroidSpec_getSizeWithHeaders_returnType::width}, - {L"height", &ImageLoaderAndroidSpec_getSizeWithHeaders_returnType::height}, + {L"width", &ImageLoaderAndroidSpec_ImageSize::width}, + {L"height", &ImageLoaderAndroidSpec_ImageSize::height}, }; return fieldMap; } @@ -43,8 +30,8 @@ inline winrt::Microsoft::ReactNative::FieldMap GetStructInfo(ImageLoaderAndroidS struct ImageLoaderAndroidSpec : winrt::Microsoft::ReactNative::TurboModuleSpec { static constexpr auto methods = std::tuple{ Method{0, L"abortRequest"}, - Method) noexcept>{1, L"getSize"}, - Method) noexcept>{2, L"getSizeWithHeaders"}, + Method) noexcept>{1, L"getSize"}, + Method) noexcept>{2, L"getSizeWithHeaders"}, Method) noexcept>{3, L"prefetchImage"}, Method, Promise<::React::JSValue>) noexcept>{4, L"queryCache"}, }; @@ -61,13 +48,13 @@ struct ImageLoaderAndroidSpec : winrt::Microsoft::ReactNative::TurboModuleSpec { REACT_SHOW_METHOD_SPEC_ERRORS( 1, "getSize", - " REACT_METHOD(getSize) void getSize(std::string uri, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n" - " REACT_METHOD(getSize) static void getSize(std::string uri, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n"); + " REACT_METHOD(getSize) void getSize(std::string uri, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n" + " REACT_METHOD(getSize) static void getSize(std::string uri, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n"); REACT_SHOW_METHOD_SPEC_ERRORS( 2, "getSizeWithHeaders", - " REACT_METHOD(getSizeWithHeaders) void getSizeWithHeaders(std::string uri, ::React::JSValue && headers, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n" - " REACT_METHOD(getSizeWithHeaders) static void getSizeWithHeaders(std::string uri, ::React::JSValue && headers, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n"); + " REACT_METHOD(getSizeWithHeaders) void getSizeWithHeaders(std::string uri, ::React::JSValue && headers, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n" + " REACT_METHOD(getSizeWithHeaders) static void getSizeWithHeaders(std::string uri, ::React::JSValue && headers, ::React::ReactPromise &&result) noexcept { /* implementation */ }\n"); REACT_SHOW_METHOD_SPEC_ERRORS( 3, "prefetchImage", diff --git a/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h b/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h index 2861340fb65..810e7ee37cf 100644 --- a/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h +++ b/vnext/codegen/react/components/rnwcore/ComponentDescriptors.h @@ -16,13 +16,13 @@ namespace facebook { namespace react { +using DebuggingOverlayComponentDescriptor = ConcreteComponentDescriptor; using ActivityIndicatorViewComponentDescriptor = ConcreteComponentDescriptor; using AndroidDrawerLayoutComponentDescriptor = ConcreteComponentDescriptor; using AndroidSwipeRefreshLayoutComponentDescriptor = ConcreteComponentDescriptor; using PullToRefreshViewComponentDescriptor = ConcreteComponentDescriptor; using AndroidHorizontalScrollContentViewComponentDescriptor = ConcreteComponentDescriptor; using SwitchComponentDescriptor = ConcreteComponentDescriptor; -using TraceUpdateOverlayComponentDescriptor = ConcreteComponentDescriptor; using UnimplementedNativeViewComponentDescriptor = ConcreteComponentDescriptor; } // namespace react diff --git a/vnext/codegen/react/components/rnwcore/EventEmitters.cpp b/vnext/codegen/react/components/rnwcore/EventEmitters.cpp index 8062e6e8fd0..56dc6c831df 100644 --- a/vnext/codegen/react/components/rnwcore/EventEmitters.cpp +++ b/vnext/codegen/react/components/rnwcore/EventEmitters.cpp @@ -14,6 +14,7 @@ namespace facebook { namespace react { + void ModalHostViewEventEmitter::onRequestClose(OnRequestClose $event) const { dispatchEvent("requestClose", [](jsi::Runtime &runtime) { auto $payload = jsi::Object(runtime); @@ -148,6 +149,5 @@ void SwitchEventEmitter::onChange(OnChange $event) const { - } // namespace react } // namespace facebook diff --git a/vnext/codegen/react/components/rnwcore/EventEmitters.h b/vnext/codegen/react/components/rnwcore/EventEmitters.h index 98b824b21c8..b8143ac65a2 100644 --- a/vnext/codegen/react/components/rnwcore/EventEmitters.h +++ b/vnext/codegen/react/components/rnwcore/EventEmitters.h @@ -14,6 +14,13 @@ namespace facebook { namespace react { +class DebuggingOverlayEventEmitter : public ViewEventEmitter { + public: + using ViewEventEmitter::ViewEventEmitter; + + + +}; class ModalHostViewEventEmitter : public ViewEventEmitter { public: using ViewEventEmitter::ViewEventEmitter; @@ -177,13 +184,6 @@ class InputAccessoryEventEmitter : public ViewEventEmitter { -}; -class TraceUpdateOverlayEventEmitter : public ViewEventEmitter { - public: - using ViewEventEmitter::ViewEventEmitter; - - - }; class UnimplementedNativeViewEventEmitter : public ViewEventEmitter { public: diff --git a/vnext/codegen/react/components/rnwcore/Props.cpp b/vnext/codegen/react/components/rnwcore/Props.cpp index 663721d25da..bb6c2d0ac89 100644 --- a/vnext/codegen/react/components/rnwcore/Props.cpp +++ b/vnext/codegen/react/components/rnwcore/Props.cpp @@ -15,6 +15,13 @@ namespace facebook { namespace react { +DebuggingOverlayProps::DebuggingOverlayProps( + const PropsParserContext &context, + const DebuggingOverlayProps &sourceProps, + const RawProps &rawProps): ViewProps(context, sourceProps, rawProps) + + + {} ModalHostViewProps::ModalHostViewProps( const PropsParserContext &context, const ModalHostViewProps &sourceProps, @@ -177,13 +184,6 @@ InputAccessoryProps::InputAccessoryProps( const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), backgroundColor(convertRawProp(context, rawProps, "backgroundColor", sourceProps.backgroundColor, {})) - {} -TraceUpdateOverlayProps::TraceUpdateOverlayProps( - const PropsParserContext &context, - const TraceUpdateOverlayProps &sourceProps, - const RawProps &rawProps): ViewProps(context, sourceProps, rawProps) - - {} UnimplementedNativeViewProps::UnimplementedNativeViewProps( const PropsParserContext &context, diff --git a/vnext/codegen/react/components/rnwcore/Props.h b/vnext/codegen/react/components/rnwcore/Props.h index 784c2511454..bcc5840b376 100644 --- a/vnext/codegen/react/components/rnwcore/Props.h +++ b/vnext/codegen/react/components/rnwcore/Props.h @@ -18,6 +18,16 @@ namespace facebook { namespace react { +class DebuggingOverlayProps final : public ViewProps { + public: + DebuggingOverlayProps() = default; + DebuggingOverlayProps(const PropsParserContext& context, const DebuggingOverlayProps &sourceProps, const RawProps &rawProps); + +#pragma mark - Props + + +}; + enum class ModalHostViewAnimationType { None, Slide, Fade }; static inline void fromRawValue(const PropsParserContext& context, const RawValue &value, ModalHostViewAnimationType &result) { @@ -419,16 +429,6 @@ class InputAccessoryProps final : public ViewProps { SharedColor backgroundColor{}; }; -class TraceUpdateOverlayProps final : public ViewProps { - public: - TraceUpdateOverlayProps() = default; - TraceUpdateOverlayProps(const PropsParserContext& context, const TraceUpdateOverlayProps &sourceProps, const RawProps &rawProps); - -#pragma mark - Props - - -}; - class UnimplementedNativeViewProps final : public ViewProps { public: UnimplementedNativeViewProps() = default; diff --git a/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp b/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp index deab6e80ac1..51f50c3d562 100644 --- a/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp +++ b/vnext/codegen/react/components/rnwcore/ShadowNodes.cpp @@ -13,13 +13,13 @@ namespace facebook { namespace react { +extern const char DebuggingOverlayComponentName[] = "DebuggingOverlay"; extern const char ActivityIndicatorViewComponentName[] = "ActivityIndicatorView"; extern const char AndroidDrawerLayoutComponentName[] = "AndroidDrawerLayout"; extern const char AndroidSwipeRefreshLayoutComponentName[] = "AndroidSwipeRefreshLayout"; extern const char PullToRefreshViewComponentName[] = "PullToRefreshView"; extern const char AndroidHorizontalScrollContentViewComponentName[] = "AndroidHorizontalScrollContentView"; extern const char SwitchComponentName[] = "Switch"; -extern const char TraceUpdateOverlayComponentName[] = "TraceUpdateOverlay"; extern const char UnimplementedNativeViewComponentName[] = "UnimplementedNativeView"; } // namespace react diff --git a/vnext/codegen/react/components/rnwcore/ShadowNodes.h b/vnext/codegen/react/components/rnwcore/ShadowNodes.h index 9e56e55b12f..91f3dd2afb1 100644 --- a/vnext/codegen/react/components/rnwcore/ShadowNodes.h +++ b/vnext/codegen/react/components/rnwcore/ShadowNodes.h @@ -19,6 +19,17 @@ namespace facebook { namespace react { +JSI_EXPORT extern const char DebuggingOverlayComponentName[]; + +/* + * `ShadowNode` for component. + */ +using DebuggingOverlayShadowNode = ConcreteViewShadowNode< + DebuggingOverlayComponentName, + DebuggingOverlayProps, + DebuggingOverlayEventEmitter, + DebuggingOverlayState>; + JSI_EXPORT extern const char ActivityIndicatorViewComponentName[]; /* @@ -85,17 +96,6 @@ using SwitchShadowNode = ConcreteViewShadowNode< SwitchEventEmitter, SwitchState>; -JSI_EXPORT extern const char TraceUpdateOverlayComponentName[]; - -/* - * `ShadowNode` for component. - */ -using TraceUpdateOverlayShadowNode = ConcreteViewShadowNode< - TraceUpdateOverlayComponentName, - TraceUpdateOverlayProps, - TraceUpdateOverlayEventEmitter, - TraceUpdateOverlayState>; - JSI_EXPORT extern const char UnimplementedNativeViewComponentName[]; /* diff --git a/vnext/codegen/react/components/rnwcore/States.h b/vnext/codegen/react/components/rnwcore/States.h index 34aa3a910e6..48d28ab9827 100644 --- a/vnext/codegen/react/components/rnwcore/States.h +++ b/vnext/codegen/react/components/rnwcore/States.h @@ -17,6 +17,21 @@ namespace facebook { namespace react { +class DebuggingOverlayState { +public: + DebuggingOverlayState() = default; + +#ifdef ANDROID + DebuggingOverlayState(DebuggingOverlayState const &previousState, folly::dynamic data){}; + folly::dynamic getDynamic() const { + return {}; + }; + MapBuffer getMapBuffer() const { + return MapBufferBuilder::EMPTY(); + }; +#endif +}; + class ActivityIndicatorViewState { public: ActivityIndicatorViewState() = default; @@ -107,21 +122,6 @@ class SwitchState { #endif }; -class TraceUpdateOverlayState { -public: - TraceUpdateOverlayState() = default; - -#ifdef ANDROID - TraceUpdateOverlayState(TraceUpdateOverlayState const &previousState, folly::dynamic data){}; - folly::dynamic getDynamic() const { - return {}; - }; - MapBuffer getMapBuffer() const { - return MapBufferBuilder::EMPTY(); - }; -#endif -}; - class UnimplementedNativeViewState { public: UnimplementedNativeViewState() = default; diff --git a/vnext/codegen/rnwcoreJSI.h b/vnext/codegen/rnwcoreJSI.h index 3effb336336..23295a92375 100644 --- a/vnext/codegen/rnwcoreJSI.h +++ b/vnext/codegen/rnwcoreJSI.h @@ -2149,7 +2149,52 @@ class JSI_EXPORT NativeImageEditorCxxSpec : public TurboModule { }; - class JSI_EXPORT NativeImageLoaderAndroidCxxSpecJSI : public TurboModule { + +#pragma mark - ImageLoaderBaseImageSize + +template +struct ImageLoaderBaseImageSize { + P0 width; + P1 height; + bool operator==(const ImageLoaderBaseImageSize &other) const { + return width == other.width && height == other.height; + } +}; + +template +struct ImageLoaderBaseImageSizeBridging { + static ImageLoaderBaseImageSize fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + ImageLoaderBaseImageSize result{ + bridging::fromJs(rt, value.getProperty(rt, "width"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "height"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double widthToJs(jsi::Runtime &rt, P0 value) { + return bridging::toJs(rt, value); + } + + static double heightToJs(jsi::Runtime &rt, P1 value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const ImageLoaderBaseImageSize &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "width", bridging::toJs(rt, value.width, jsInvoker)); + result.setProperty(rt, "height", bridging::toJs(rt, value.height, jsInvoker)); + return result; + } +}; + +class JSI_EXPORT NativeImageLoaderAndroidCxxSpecJSI : public TurboModule { protected: NativeImageLoaderAndroidCxxSpecJSI(std::shared_ptr jsInvoker); diff --git a/vnext/overrides.json b/vnext/overrides.json index f0a6eb7e57b..0ce35454b3a 100644 --- a/vnext/overrides.json +++ b/vnext/overrides.json @@ -8,7 +8,7 @@ "**/__snapshots__/**", "src/rntypes/**" ], - "baseVersion": "0.74.0-nightly-20231116-fa89dd68b", + "baseVersion": "0.74.0-nightly-20231124-c464b215e", "overrides": [ { "type": "derived", @@ -20,7 +20,7 @@ "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h", "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputComponentDescriptor.h", - "baseHash": "476e6698abe05a235ebe82ad913c699acb23d85f" + "baseHash": "09b2d135a48cde87cd3a7da28cbf1648ce840fc4" }, { "type": "derived", @@ -38,20 +38,27 @@ "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp", "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.cpp", - "baseHash": "a9bd512e3cc9923176157d731365c08536b479a8" + "baseHash": "e5fe1ab887bc6fdd353548276ccf414b11f35c61" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h", "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.h", - "baseHash": "b83afcec6091b25baedbcf6742e06adc8a794f92" + "baseHash": "e0cb62818f80a458ef28430a08a6a685805d3a91" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/ImageRequest.cpp", - "baseFile": "packages/react-native/ReactCommon/react/renderer/imagemanager/platform/ios/react/renderer/imagemanager/ImageRequest.cpp", + "baseFile": "packages/react-native/ReactCommon/react/renderer/imagemanager/ImageRequest.cpp", "baseHash": "a72d01a2516c09f453090181cb22beeef2a4b29c" }, + { + "type": "copy", + "file": "Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/YogaLayoutableShadowNode.cpp", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp", + "baseHash": "a5821ed70a5be50febe8f69dfbef10be1147b2d5", + "issue": 7821 + }, { "type": "copy", "file": "Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Float.h", @@ -66,6 +73,55 @@ "baseHash": "224ddd5bc92672790e8875bf3078f0529aca05d0", "issue": 12210 }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/Bridging.h", + "baseFile": "packages/react-native/ReactCommon/react/bridging/Bridging.h", + "baseHash": "7298e5365811b51bcd892732dcb51110ecbed5ec", + "issue": 12195 + }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/CallbackWrapper.h", + "baseFile": "packages/react-native/ReactCommon/react/bridging/CallbackWrapper.h", + "baseHash": "fe1adea3ede6ed141bc6db212be72091722ffa02", + "issue": 12195 + }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/LongLivedObject.cpp", + "baseFile": "packages/react-native/ReactCommon/react/bridging/LongLivedObject.cpp", + "baseHash": "4998856d2ebeb3fd6985472123764bb00645bd75", + "issue": 12195 + }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/bridging/LongLivedObject.h", + "baseFile": "packages/react-native/ReactCommon/react/bridging/LongLivedObject.h", + "baseHash": "6ffd4b844e3b205de8ae85ce6d2ff691c99992e1", + "issue": 12195 + }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp", + "baseFile": "packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.cpp", + "baseHash": "a2fe17d8840fd038a4b1569d10b7667a1f9e516a", + "issue": 12195 + }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleBinding.h", + "baseFile": "packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleBinding.h", + "baseHash": "b3b916aa12828c0f77a434d086248453d6243870", + "issue": 12195 + }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/nativemodule/core/ReactCommon/TurboModuleUtils.h", + "baseFile": "packages/react-native/ReactCommon/react/nativemodule/core/ReactCommon/TurboModuleUtils.h", + "baseHash": "11de652e153bff8c42cc0e2bbf209c762ed3b314", + "issue": 12195 + }, { "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/core/RawPropsParser.cpp", @@ -73,6 +129,13 @@ "baseHash": "79fc21a9ad5ba440186d970c44021e25928b6f79", "issue": 12300 }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/mapbuffer/MapBufferBuilder.cpp", + "baseFile": "packages/react-native/ReactCommon/react/renderer/mapbuffer/MapBufferBuilder.cpp", + "baseHash": "a2fa7db6a41b3bbd170dc24f153185dfb131d121", + "issue": 7821 + }, { "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/mounting/ShadowTree.cpp", @@ -84,7 +147,7 @@ "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/uimanager/UIManagerBinding.cpp", "baseFile": "packages/react-native/ReactCommon/react/renderer/uimanager/UIManagerBinding.cpp", - "baseHash": "5f60fee5a468fb960ab0e5c12c3a54837d2c8b92", + "baseHash": "9210ab2289dbe492ead3e3506f080290cd9fa26b", "issue": 12195 }, { @@ -94,6 +157,13 @@ "baseHash": "c01a9fd4408d1df6419197990a4000a09d28bf52", "issue": 12195 }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/enums/YogaEnums.h", + "baseFile": "packages/react-native/ReactCommon/yoga/yoga/enums/YogaEnums.h", + "baseHash": "25adf2469465bb27ea1b5c41901ff8642b4b4896", + "issue": 12195 + }, { "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h", @@ -105,7 +175,7 @@ "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h", "baseFile": "packages/react-native/ReactCommon/yoga/yoga/node/Node.h", - "baseHash": "79aa34fdec0dfed4591cb059e9b72ba9f0ef0155", + "baseHash": "c40a83f59704ffd6783cba257421aee668b681ad", "issue": 12195 }, { @@ -126,7 +196,7 @@ "type": "derived", "file": "src/index.windows.js", "baseFile": "packages/react-native/index.js", - "baseHash": "b658f287732c27fdd28722a8765c3b1b0c1316fa" + "baseHash": "6c91f268c2189f9db74bead7fef1ed262c77586e" }, { "type": "platform", @@ -288,7 +358,7 @@ "type": "patch", "file": "src/Libraries/Components/TextInput/TextInput.windows.js", "baseFile": "packages/react-native/Libraries/Components/TextInput/TextInput.js", - "baseHash": "d12fe54e9da3be0b1003a5bc18fa3c6d09728564" + "baseHash": "fa10fcf147f79ede6f3a49fac45faefed48e1693" }, { "type": "patch", @@ -372,7 +442,7 @@ "type": "patch", "file": "src/Libraries/Image/Image.windows.js", "baseFile": "packages/react-native/Libraries/Image/Image.ios.js", - "baseHash": "bccd20ad47baa18b187bd8eb92b7627135be29fd", + "baseHash": "ba2c259fd454ed0c0f73b82f6390fef8045320ab", "issue": 4590 }, { diff --git a/vnext/package.json b/vnext/package.json index b1f1b6bf2d0..a9eca1ebb2e 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -28,13 +28,13 @@ "@react-native-community/cli-platform-ios": "12.0.0", "@react-native-windows/cli": "0.0.0-canary.194", "@react-native/assets": "1.0.0", - "@react-native/assets-registry": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/codegen": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/community-cli-plugin": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/gradle-plugin": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/js-polyfills": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/normalize-colors": "0.74.0-nightly-20231116-fa89dd68b", - "@react-native/virtualized-lists": "0.74.0-nightly-20231116-fa89dd68b", + "@react-native/assets-registry": "0.74.0-nightly-20231124-c464b215e", + "@react-native/codegen": "0.74.0-nightly-20231124-c464b215e", + "@react-native/community-cli-plugin": "0.74.0-nightly-20231124-c464b215e", + "@react-native/gradle-plugin": "0.74.0-nightly-20231124-c464b215e", + "@react-native/js-polyfills": "0.74.0-nightly-20231124-c464b215e", + "@react-native/normalize-colors": "0.74.0-nightly-20231124-c464b215e", + "@react-native/virtualized-lists": "0.74.0-nightly-20231124-c464b215e", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", @@ -81,14 +81,14 @@ "just-scripts": "^1.3.3", "prettier": "^2.4.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b", + "react-native": "0.74.0-nightly-20231124-c464b215e", "react-native-platform-override": "^1.9.17", "react-refresh": "^0.4.0", "typescript": "^4.9.5" }, "peerDependencies": { "react": "18.2.0", - "react-native": "0.74.0-nightly-20231116-fa89dd68b" + "react-native": "0.74.0-nightly-20231124-c464b215e" }, "beachball": { "defaultNpmTag": "canary", diff --git a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js index 456b99b49c6..bc24b1b97fe 100644 --- a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js +++ b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js @@ -994,6 +994,12 @@ export type Props = $ReadOnly<{| */ selectionColor?: ?ColorValue, + /** + * The text selection handle color. + * @platform android + */ + selectionHandleColor?: ?ColorValue, + /** * If `true`, all text will automatically be selected on focus. */ @@ -1188,6 +1194,9 @@ function InternalTextInput(props: Props): React.Node { id, tabIndex, selection: propsSelection, + selectionColor, + selectionHandleColor, + cursorColor, ...otherProps } = props; @@ -1653,7 +1662,15 @@ function InternalTextInput(props: Props): React.Node { if (childCount > 1) { children = {children}; } - + // For consistency with iOS set cursor/selectionHandle color as selectionColor + const colorProps = { + selectionColor, + selectionHandleColor: + selectionHandleColor === undefined + ? selectionColor + : selectionHandleColor, + cursorColor: cursorColor === undefined ? selectionColor : cursorColor, + }; textInput = ( /* $FlowFixMe[prop-missing] the types for AndroidTextInput don't match up * exactly with the props for TextInput. This will need to get fixed */ @@ -1667,6 +1684,7 @@ function InternalTextInput(props: Props): React.Node { // $FlowFixMe[incompatible-type] - Figure out imperative + forward refs. ref={ref} {...otherProps} + {...colorProps} {...eventHandlers} accessibilityErrorMessage={accessibilityErrorMessage} accessibilityState={_accessibilityState} diff --git a/vnext/src/Libraries/Image/Image.windows.js b/vnext/src/Libraries/Image/Image.windows.js index 5f023d148d2..17d79a35b86 100644 --- a/vnext/src/Libraries/Image/Image.windows.js +++ b/vnext/src/Libraries/Image/Image.windows.js @@ -18,7 +18,10 @@ import invariant from 'invariant'; // [Windows] import flattenStyle from '../StyleSheet/flattenStyle'; import StyleSheet from '../StyleSheet/StyleSheet'; import ImageAnalyticsTagContext from './ImageAnalyticsTagContext'; -import {unstable_getImageComponentDecorator} from './ImageInjection'; +import { + unstable_getImageComponentDecorator, + useWrapRefWithImageAttachedCallbacks, +} from './ImageInjection'; import {getImageSourcesFromImageProps} from './ImageSourceUtils'; import {convertObjectFitToResizeMode} from './ImageUtils'; import ImageViewNativeComponent from './ImageViewNativeComponent'; @@ -160,6 +163,8 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { }; const accessibilityLabel = props['aria-label'] ?? props.accessibilityLabel; + const actualRef = useWrapRefWithImageAttachedCallbacks(forwardedRef); + return ( // [Windows @@ -179,7 +184,7 @@ let BaseImage: AbstractImageIOS = React.forwardRef((props, forwardedRef) => { {...restProps} accessible={props.alt !== undefined ? true : props.accessible} accessibilityLabel={accessibilityLabel ?? props.alt} - ref={forwardedRef} + ref={actualRef} style={style} resizeMode={resizeMode} tintColor={tintColor} diff --git a/vnext/src/index.windows.js b/vnext/src/index.windows.js index 59ae5a3ebdb..c80cc408155 100644 --- a/vnext/src/index.windows.js +++ b/vnext/src/index.windows.js @@ -289,7 +289,7 @@ module.exports = { 'pushNotificationIOS-moved', 'PushNotificationIOS has been extracted from react-native core and will be removed in a future release. ' + "It can now be installed and imported from '@react-native-community/push-notification-ios' instead of 'react-native'. " + - 'See https://github.com/react-native-push-notification-ios/push-notification-ios', + 'See https://github.com/react-native-push-notification/ios', ); return require('./Libraries/PushNotificationIOS/PushNotificationIOS'); }, @@ -487,7 +487,8 @@ if (__DEV__) { invariant( false, 'ART has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/art' instead of 'react-native'. " + + "Please upgrade to use either 'react-native-svg' or a similar package. " + + "If you cannot upgrade to a different library, please install the deprecated '@react-native-community/art' package. " + 'See https://github.com/react-native-art/art', ); }, @@ -567,7 +568,7 @@ if (__DEV__) { invariant( false, 'CameraRoll has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/cameraroll' instead of 'react-native'. " + + "It can now be installed and imported from '@react-native-camera-roll/camera-roll' instead of 'react-native'. " + 'See https://github.com/react-native-cameraroll/react-native-cameraroll', ); }, @@ -680,7 +681,7 @@ if (__DEV__) { invariant( false, 'SegmentedControlIOS has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/segmented-checkbox' instead of 'react-native'." + + "It can now be installed and imported from '@react-native-segmented-control/segmented-control' instead of 'react-native'." + 'See https://github.com/react-native-segmented-control/segmented-control', ); }, @@ -758,7 +759,7 @@ if (__DEV__) { invariant( false, 'MaskedViewIOS has been removed from React Native. ' + - "It can now be installed and imported from '@react-native-community/react-native-masked-view' instead of 'react-native'. " + + "It can now be installed and imported from '@react-native-masked-view/masked-view' instead of 'react-native'. " + 'See https://github.com/react-native-masked-view/masked-view', ); }, @@ -788,7 +789,7 @@ if (__DEV__) { invariant( false, 'ImagePickerIOS has been removed from React Native. ' + - "Please upgrade to use either '@react-native-community/react-native-image-picker' or 'expo-image-picker'. " + + "Please upgrade to use either 'react-native-image-picker' or 'expo-image-picker'. " + "If you cannot upgrade to a different library, please install the deprecated '@react-native-community/image-picker-ios' package. " + 'See https://github.com/rnc-archive/react-native-image-picker-ios', ); diff --git a/yarn.lock b/yarn.lock index f75a5fa5c72..4e9fb9dbcdc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2404,10 +2404,10 @@ resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.6.1.tgz#3b20ddd1385fab0487db103dc6519570f8892e6d" integrity sha512-oJftvmLOj6Y6/bF4kPcK6L83yNBALGmqNYugf94BzP0FQGpHBwimVN2ygqkQ2Sn2ZU3pGUZMs0jV6+Gku2GyYg== -"@react-native/assets-registry@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.0-nightly-20231116-fa89dd68b.tgz#0b508a62821e2de110984e45cff784da9be0b7e0" - integrity sha512-NPqJGqAr/KaVF3pRRXKNYJANU7eLL0E5g9F0LTM+yaRT9d5R+iAdwatX6nGe3t89KLwx6QQUVYER4I99JC60Aw== +"@react-native/assets-registry@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.0-nightly-20231124-c464b215e.tgz#13e3ea91d218ab11fc7b76a05bbad5db407f0cfc" + integrity sha512-S6bBzs8fKR0SH87SAIAqGvWhh1//VukTSqQRdEOcHr1qYrspECNGZ4zA0Y9DpTzCUhZK36W6YaDjWZTPS+XZAw== "@react-native/assets@1.0.0": version "1.0.0" @@ -2421,12 +2421,12 @@ dependencies: "@react-native/codegen" "*" -"@react-native/babel-plugin-codegen@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.0-nightly-20231116-fa89dd68b.tgz#d24dca5b2e1e246b2da3073d92919cf5abbf7e24" - integrity sha512-AovzqgIjlWuCPVDS2fuEDoe6FqJHUF0/OBfB/9GinPaDyIM0+i7PMNKpOYgjfhpBUzhsI1emwCwUFd0+9vHkfA== +"@react-native/babel-plugin-codegen@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.0-nightly-20231124-c464b215e.tgz#71e0c3b58aaee75d4d18978a381deabcf1f2152e" + integrity sha512-VogsexG5kpx1SYSiGITBI9Gcd9Wcc9p7JTsKnW4peFZrxqabCvmuTeiCk47vsp2Go4DuN2ljWU23GVPTTnGQIQ== dependencies: - "@react-native/codegen" "0.74.0-nightly-20231116-fa89dd68b" + "@react-native/codegen" "0.74.0-nightly-20231124-c464b215e" "@react-native/babel-preset@*", "@react-native/babel-preset@0.73.16": version "0.73.16" @@ -2474,10 +2474,10 @@ babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.4.0" -"@react-native/babel-preset@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.0-nightly-20231116-fa89dd68b.tgz#841a9ce1b318992ac761d5e0916ae54e0d102edd" - integrity sha512-Y6eXRvO0qPrQahL5o1jNlQiYTdboE5S6QijqSmFXA6An1C3puyJVMkyGrzmTbVYRv4Wlkxkz8ZkX6VFJ8UVtvQ== +"@react-native/babel-preset@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.0-nightly-20231124-c464b215e.tgz#06d7719e774dfcb10accf246be9ef9a72a17c6f8" + integrity sha512-4j6Vp6rfT8lr8w9pyAZOGGVcsaPzc6HWK8a1Nc97TzZj+tv4JlqnhGnAvi6uDcfz6pTwWe6Wr/OK0a+a40+N+Q== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" @@ -2519,7 +2519,7 @@ "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - "@react-native/babel-plugin-codegen" "0.74.0-nightly-20231116-fa89dd68b" + "@react-native/babel-plugin-codegen" "0.74.0-nightly-20231124-c464b215e" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" @@ -2533,10 +2533,10 @@ jscodeshift "^0.14.0" nullthrows "^1.1.1" -"@react-native/codegen@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.0-nightly-20231116-fa89dd68b.tgz#d0537cb841caa5b370f84b22cd48f2637cd01d5f" - integrity sha512-6Dipb4e9anrt5KQwPN51JI77sIuTXp3C7bl+Fx5ono6exjHMzWfMLjzd9HnXINGTGBLJZl6tN0ZJVpRMjrkm/A== +"@react-native/codegen@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.0-nightly-20231124-c464b215e.tgz#ff66cbb30873c6db0ce07a48a2f07458d4f0f3b4" + integrity sha512-tIEawYmhXbL3UWpp2dw/XY/fQJvZxZh3ea6vfrsXfGhm0zkGjVIZNdAMhzXWF+60NfJuSMmydROB9+NtbrbzrA== dependencies: "@babel/parser" "^7.20.0" glob "^7.1.1" @@ -2546,15 +2546,15 @@ mkdirp "^0.5.1" nullthrows "^1.1.1" -"@react-native/community-cli-plugin@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.0-nightly-20231116-fa89dd68b.tgz#22628173ddb3630a3fe9b6d174f6c3a999fd26ae" - integrity sha512-+sBzVu2lTBS8RoKgFOZNmy+pCdbS49LJgGXLDVrOT0nWhdBLGxUbZlFY9WtwUkMaGcHOR7PlBxlb7IEZ7f67nQ== +"@react-native/community-cli-plugin@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.0-nightly-20231124-c464b215e.tgz#7ba1c95fead49ee4c36cf7902da75a4eb0ef9211" + integrity sha512-SUIZ2qizuWWZAJmy/t9VW2vTLFzVUGMccQt2ppT90yAjNL09Pg/L3mAPIk/CWtaXUVbETaVL4dGHCCPd9si1+A== dependencies: "@react-native-community/cli-server-api" "12.0.0" "@react-native-community/cli-tools" "12.0.0" - "@react-native/dev-middleware" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/metro-babel-transformer" "0.74.0-nightly-20231116-fa89dd68b" + "@react-native/dev-middleware" "0.74.0-nightly-20231124-c464b215e" + "@react-native/metro-babel-transformer" "0.74.0-nightly-20231124-c464b215e" chalk "^4.0.0" execa "^5.1.1" metro "^0.80.0" @@ -2563,18 +2563,18 @@ node-fetch "^2.2.0" readline "^1.3.0" -"@react-native/debugger-frontend@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.0-nightly-20231116-fa89dd68b.tgz#2cf5400280ca36fdf26de9382c808404be8106ad" - integrity sha512-gF/2ennW/XCgk7RVLljKNeiLoqhq7IHXHB0DV5Pz1t/pWwaWF4SOka0GvDdACkFTiaKljS8DmtXP2yQck5O5Sw== +"@react-native/debugger-frontend@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.0-nightly-20231124-c464b215e.tgz#c33ed7968903f9a6b6655cc0d8655ace4ec3fcf2" + integrity sha512-gvYXYrOP4d1tuzp7Uq0xJK4gf8FUACpldevpM17snmIE1NpOu61Z9c0lcafWoki3cH4wfi77AbuChg2a25M0sw== -"@react-native/dev-middleware@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.0-nightly-20231116-fa89dd68b.tgz#37b5b9c72c6bebc2909f6d23e8b001ede310b245" - integrity sha512-YGMv6TjG/uOKrvvqzNd2sCV1DepVc/aErsm5K+Tu2sTGtoktn7vGqZnhaIOgrBryo7eIkbi9yDRmN2ESlCZwkQ== +"@react-native/dev-middleware@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.0-nightly-20231124-c464b215e.tgz#b649eb8da4abe94304d07105179725075f6a03ff" + integrity sha512-wqIcwod4uycBSraaouar0WNPpz4ylHdPIBDNTox6g1b9Bfeb+Igo08nfDhx3H0SBbuq9VGg8rI2prWphGgrcxA== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.74.0-nightly-20231116-fa89dd68b" + "@react-native/debugger-frontend" "0.74.0-nightly-20231124-c464b215e" "@rnx-kit/chromium-edge-launcher" "^1.0.0" chrome-launcher "^0.15.2" connect "^3.6.5" @@ -2609,15 +2609,15 @@ resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.73.1.tgz#79d2c4d90c80bfad8900db335bfbaf1ca599abdc" integrity sha512-8BNMFE8CAI7JLWLOs3u33wcwcJ821LYs5g53Xyx9GhSg0h8AygTwDrwmYb/pp04FkCNCPjKPBoaYRthQZmxgwA== -"@react-native/gradle-plugin@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.0-nightly-20231116-fa89dd68b.tgz#9327359ec3e8c5d88dbd4b77f743c0a655c8137e" - integrity sha512-2XSFnXRYHsVxiRkNHTj0OkSdTbPFmLU3/kav3YNJd3DgyzSoKk9CaX0F28ciw//zRfyNsIA50jmQ7MthB2gT0A== +"@react-native/gradle-plugin@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.0-nightly-20231124-c464b215e.tgz#beabaf30eaa62f3d4f7e0c90b3cb7a1265c470ac" + integrity sha512-t7IngZokZ2dYdeFs24bxzz3rG58aaGZzB85rE6jtoFZU8zB4sABWPvj+hMdbntVdjW0TMuORAZ7cEUSdcOZQAQ== -"@react-native/js-polyfills@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.0-nightly-20231116-fa89dd68b.tgz#e0ac2b2c9a826f0611b81d20a32d86679df596a7" - integrity sha512-cG68qggdXxCAHq9THtuSi4nEVVMAefufknzKI3jsNtH3NMrCC1g2rxw1HKKku0ssAiO2MAyqKvlLp2kfzb1HVw== +"@react-native/js-polyfills@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.0-nightly-20231124-c464b215e.tgz#4fe906bc6a4d228c7ba4825ae29794a73b51b817" + integrity sha512-WbrqA79/8t7Jq/k5CacAC/0ptKw/Cign/NbNIAqWoZoGCPySQ3v6mPW9DgudH6J9dofoxL2If4elj38Wj+ryYA== "@react-native/js-polyfills@^0.73.1": version "0.73.1" @@ -2635,13 +2635,13 @@ hermes-parser "0.15.0" nullthrows "^1.1.1" -"@react-native/metro-babel-transformer@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.0-nightly-20231116-fa89dd68b.tgz#f0f092e037aac448981bdbd2c88d8b4a85b10bd7" - integrity sha512-Xce2eVKfM0NsnyJq/S34iUYz1A4uPDdZ+JdkI05eCk6WYt5JKAuTkx9cdIfRtilHa5xnes6amFAUgAZ2dp2sJA== +"@react-native/metro-babel-transformer@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.0-nightly-20231124-c464b215e.tgz#9f850d0795b91160889921aa98ec1ed71b6075af" + integrity sha512-5nPB9eaP1gZAtLDhxbpRGAhvOd46JVkFXJ2RtwHqbtSmCzowI8dKLEizVNkTKXGXKTRhiLS63XyStaTDOvfDzw== dependencies: "@babel/core" "^7.20.0" - "@react-native/babel-preset" "0.74.0-nightly-20231116-fa89dd68b" + "@react-native/babel-preset" "0.74.0-nightly-20231124-c464b215e" hermes-parser "0.17.1" nullthrows "^1.1.1" @@ -2665,20 +2665,20 @@ metro-config "0.79.1" metro-runtime "0.79.1" -"@react-native/normalize-colors@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.0-nightly-20231116-fa89dd68b.tgz#6196973e254961f42f67d2da177a0923148195c4" - integrity sha512-xkblOcuJnC2JtApsvCEccr/qP29Srq/q6kXPsicphQLK2PVjwfJYesBK6J/ZYWR55xxhaSJ6enC/HibAsJ+8Vg== +"@react-native/normalize-colors@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.0-nightly-20231124-c464b215e.tgz#6af8d017ce3347e8fc15b91fe718669110c148f5" + integrity sha512-e3f/FM1eVpig8r2+GqXLJTJ9X7teCEhva3GdwMeYjzZoMkgglix8W6G9uurNz2Iz6t8yH/G5SUcaVmgWtASmnA== "@react-native/normalize-colors@^0.73.0": version "0.73.2" resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.73.2.tgz#cc8e48fbae2bbfff53e12f209369e8d2e4cf34ec" integrity sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w== -"@react-native/virtualized-lists@0.74.0-nightly-20231116-fa89dd68b": - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.0-nightly-20231116-fa89dd68b.tgz#bf93d23b5ad8d3886303ea98516bf52194c1e8ff" - integrity sha512-v9NM7h3rF5gcjoUAx14Td5x6ifFEfc1/qWSYHIMLAR2C6K4ogh2oz2YpMhz/EfdhDviTG2wYFOtxaMspr+hi7g== +"@react-native/virtualized-lists@0.74.0-nightly-20231124-c464b215e": + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.0-nightly-20231124-c464b215e.tgz#2680ae3133ef4ece2e4001a65db70aa5c5de8767" + integrity sha512-f67WObQLElPbjCYCPwlRPMjsZslKjgi+tAKepWhT1WBWv04tiWpLOFy7DUCTHg4JPT41kfBqL6MWLNM98BNVyw== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -10896,22 +10896,22 @@ react-native-xaml@^0.0.76: "@types/react-native" "*" typescript "^4.4.3" -react-native@0.74.0-nightly-20231116-fa89dd68b: - version "0.74.0-nightly-20231116-fa89dd68b" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.0-nightly-20231116-fa89dd68b.tgz#591619c184dd7647d56abdd7b873fa8324472425" - integrity sha512-vxzuHrch/rnAH9mVApfRrXP3dHavnyBRDsbQI31d+2mGWKwccsHpXChhkLVbelUinkx7FoZ0Eimq+ekQ4Z4gVg== +react-native@0.74.0-nightly-20231124-c464b215e: + version "0.74.0-nightly-20231124-c464b215e" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.0-nightly-20231124-c464b215e.tgz#f344f12f7f5985bfb5e7283fc1fab6e6ae566d5c" + integrity sha512-86SbzahKF0cwt2eMDDhsd1PZWrI14MdGtwWSBMV8HkrPWkYwgkMdrzbNkx7xOwa3QDZXGw3d0wwhG56AeSnQxA== dependencies: "@jest/create-cache-key-function" "^29.6.3" "@react-native-community/cli" "12.0.0" "@react-native-community/cli-platform-android" "12.0.0" "@react-native-community/cli-platform-ios" "12.0.0" - "@react-native/assets-registry" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/codegen" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/community-cli-plugin" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/gradle-plugin" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/js-polyfills" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/normalize-colors" "0.74.0-nightly-20231116-fa89dd68b" - "@react-native/virtualized-lists" "0.74.0-nightly-20231116-fa89dd68b" + "@react-native/assets-registry" "0.74.0-nightly-20231124-c464b215e" + "@react-native/codegen" "0.74.0-nightly-20231124-c464b215e" + "@react-native/community-cli-plugin" "0.74.0-nightly-20231124-c464b215e" + "@react-native/gradle-plugin" "0.74.0-nightly-20231124-c464b215e" + "@react-native/js-polyfills" "0.74.0-nightly-20231124-c464b215e" + "@react-native/normalize-colors" "0.74.0-nightly-20231124-c464b215e" + "@react-native/virtualized-lists" "0.74.0-nightly-20231124-c464b215e" abort-controller "^3.0.0" anser "^1.4.9" ansi-regex "^5.0.0" From 27377fa97bfec35d2d2630ebbf565824537defcc Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Mon, 8 Jan 2024 16:19:16 -0800 Subject: [PATCH 02/16] Change files --- ...-native-win32-8cc96e90-b3d9-43c7-9a01-663777232bf1.json | 7 +++++++ ...ation-channel-4190900e-d505-4fa1-a49f-2e5d49026ef2.json | 7 +++++++ ...ative-windows-537fd685-b9ff-4b3a-b0a0-6aa00a49d729.json | 7 +++++++ 3 files changed, 21 insertions(+) create mode 100644 change/@office-iss-react-native-win32-8cc96e90-b3d9-43c7-9a01-663777232bf1.json create mode 100644 change/@react-native-windows-automation-channel-4190900e-d505-4fa1-a49f-2e5d49026ef2.json create mode 100644 change/react-native-windows-537fd685-b9ff-4b3a-b0a0-6aa00a49d729.json diff --git a/change/@office-iss-react-native-win32-8cc96e90-b3d9-43c7-9a01-663777232bf1.json b/change/@office-iss-react-native-win32-8cc96e90-b3d9-43c7-9a01-663777232bf1.json new file mode 100644 index 00000000000..a1f3ac191a5 --- /dev/null +++ b/change/@office-iss-react-native-win32-8cc96e90-b3d9-43c7-9a01-663777232bf1.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "integrate 12/1", + "packageName": "@office-iss/react-native-win32", + "email": "tatianakapos@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/@react-native-windows-automation-channel-4190900e-d505-4fa1-a49f-2e5d49026ef2.json b/change/@react-native-windows-automation-channel-4190900e-d505-4fa1-a49f-2e5d49026ef2.json new file mode 100644 index 00000000000..123af741228 --- /dev/null +++ b/change/@react-native-windows-automation-channel-4190900e-d505-4fa1-a49f-2e5d49026ef2.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "integrate c464b215e", + "packageName": "@react-native-windows/automation-channel", + "email": "tatianakapos@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/change/react-native-windows-537fd685-b9ff-4b3a-b0a0-6aa00a49d729.json b/change/react-native-windows-537fd685-b9ff-4b3a-b0a0-6aa00a49d729.json new file mode 100644 index 00000000000..5ab2d32c2a7 --- /dev/null +++ b/change/react-native-windows-537fd685-b9ff-4b3a-b0a0-6aa00a49d729.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "integrate 12/1", + "packageName": "react-native-windows", + "email": "tatianakapos@microsoft.com", + "dependentChangeType": "patch" +} From b262a1af0818823ca34a686c612d130388ce102c Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Mon, 8 Jan 2024 17:33:45 -0800 Subject: [PATCH 03/16] force to use latest JSIDynamic --- .../jsi/jsi/JSIDynamic.cpp | 212 ++++ .../jsi/jsi/JSIDynamic.h | 26 + .../view/YogaLayoutableShadowNode.cpp | 1031 ----------------- vnext/overrides.json | 9 +- 4 files changed, 239 insertions(+), 1039 deletions(-) create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp new file mode 100644 index 00000000000..6606410290e --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp @@ -0,0 +1,212 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "JSIDynamic.h" + +#include + +#include +#include + +using namespace facebook::jsi; + +namespace facebook { +namespace jsi { + +namespace { + +struct FromDynamic { + FromDynamic(const folly::dynamic* dynArg, Object objArg) + : dyn(dynArg), obj(std::move(objArg)) {} + + const folly::dynamic* dyn; + Object obj; +}; + +// This converts one element. If it's a collection, it gets pushed onto +// the stack for later processing. +Value valueFromDynamicShallow( + Runtime& runtime, + std::vector& stack, + const folly::dynamic& dyn) { + switch (dyn.type()) { + case folly::dynamic::NULLT: + return Value::null(); + case folly::dynamic::ARRAY: { + Object arr = Array(runtime, dyn.size()); + Value ret = Value(runtime, arr); + stack.emplace_back(&dyn, std::move(arr)); + return ret; + } + case folly::dynamic::BOOL: + return Value(dyn.getBool()); + case folly::dynamic::DOUBLE: + return dyn.getDouble(); + case folly::dynamic::INT64: + return Value((double)dyn.getInt()); + case folly::dynamic::OBJECT: { + auto obj = Object(runtime); + Value ret = Value(runtime, obj); + stack.emplace_back(&dyn, std::move(obj)); + return ret; + } + case folly::dynamic::STRING: + return Value(String::createFromUtf8(runtime, dyn.getString())); + } + CHECK(false); +} + +} // namespace + +Value valueFromDynamic(Runtime& runtime, const folly::dynamic& dynInput) { + std::vector stack; + + Value ret = valueFromDynamicShallow(runtime, stack, dynInput); + + while (!stack.empty()) { + auto top = std::move(stack.back()); + stack.pop_back(); + + switch (top.dyn->type()) { + case folly::dynamic::ARRAY: { + Array arr = std::move(top.obj).getArray(runtime); + for (size_t i = 0; i < top.dyn->size(); ++i) { + arr.setValueAtIndex( + runtime, + i, + valueFromDynamicShallow(runtime, stack, (*top.dyn)[i])); + } + break; + } + case folly::dynamic::OBJECT: { + Object obj = std::move(top.obj); + for (const auto& element : top.dyn->items()) { + if (element.first.isNumber() || element.first.isString()) { + obj.setProperty( + runtime, + PropNameID::forUtf8(runtime, element.first.asString()), + valueFromDynamicShallow(runtime, stack, element.second)); + } + } + break; + } + default: + CHECK(false); + } + } + + return ret; +} + +namespace { + +struct FromValue { + FromValue(folly::dynamic* dynArg, Object objArg) + : dyn(dynArg), obj(std::move(objArg)) {} + + folly::dynamic* dyn; + Object obj; +}; + +// This converts one element. If it's a collection, it gets pushed +// onto the stack for later processing. The output is created by +// mutating the output argument, because we need its actual pointer to +// push onto the stack. +void dynamicFromValueShallow( + Runtime& runtime, + std::vector& stack, + const jsi::Value& value, + folly::dynamic& output) { + if (value.isUndefined() || value.isNull()) { + output = nullptr; + } else if (value.isBool()) { + output = value.getBool(); + } else if (value.isNumber()) { + output = value.getNumber(); + } else if (value.isString()) { + output = value.getString(runtime).utf8(runtime); + } else if (value.isObject()) { + Object obj = value.getObject(runtime); + if (obj.isArray(runtime)) { + output = folly::dynamic::array(); + } else if (obj.isFunction(runtime)) { + throw JSError(runtime, "JS Functions are not convertible to dynamic"); + } else { + output = folly::dynamic::object(); + } + stack.emplace_back(&output, std::move(obj)); + } else if (value.isBigInt()) { + throw JSError(runtime, "JS BigInts are not convertible to dynamic"); + } else if (value.isSymbol()) { + throw JSError(runtime, "JS Symbols are not convertible to dynamic"); + } else { + throw JSError(runtime, "Value is not convertible to dynamic"); + } +} + +} // namespace + +folly::dynamic dynamicFromValue( + Runtime& runtime, + const Value& valueInput, + std::function filterObjectKeys) { + std::vector stack; + folly::dynamic ret; + + dynamicFromValueShallow(runtime, stack, valueInput, ret); + + while (!stack.empty()) { + auto top = std::move(stack.back()); + stack.pop_back(); + + if (top.obj.isArray(runtime)) { + // Inserting into a dyn can invalidate references into it, so we + // need to insert new elements up front, then push stuff onto + // the stack. + Array array = top.obj.getArray(runtime); + size_t arraySize = array.size(runtime); + for (size_t i = 0; i < arraySize; ++i) { + top.dyn->push_back(nullptr); + } + for (size_t i = 0; i < arraySize; ++i) { + dynamicFromValueShallow( + runtime, stack, array.getValueAtIndex(runtime, i), top.dyn->at(i)); + } + } else { + Array names = top.obj.getPropertyNames(runtime); + std::vector> props; + for (size_t i = 0; i < names.size(runtime); ++i) { + String name = names.getValueAtIndex(runtime, i).getString(runtime); + Value prop = top.obj.getProperty(runtime, name); + if (prop.isUndefined()) { + continue; + } + auto nameStr = name.utf8(runtime); + if (filterObjectKeys && filterObjectKeys(nameStr)) { + continue; + } + // The JSC conversion uses JSON.stringify, which substitutes + // null for a function, so we do the same here. Just dropping + // the pair might also work, but would require more testing. + if (prop.isObject() && prop.getObject(runtime).isFunction(runtime)) { + prop = Value::null(); + } + props.emplace_back(std::move(nameStr), std::move(prop)); + top.dyn->insert(props.back().first, nullptr); + } + for (const auto& prop : props) { + dynamicFromValueShallow( + runtime, stack, prop.second, (*top.dyn)[prop.first]); + } + } + } + + return ret; +} + +} // namespace jsi +} // namespace facebook \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h new file mode 100644 index 00000000000..05836ff8d76 --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +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, + std::function filterObjectKeys = nullptr); + +} // namespace jsi +} // namespace facebook \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp deleted file mode 100644 index a3d5f60fcca..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaLayoutableShadowNode.cpp +++ /dev/null @@ -1,1031 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "YogaLayoutableShadowNode.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace facebook::react { - -static int FabricDefaultYogaLog( - const YGConfigConstRef /*unused*/, - const YGNodeConstRef /*unused*/, - YGLogLevel level, - const char* format, - va_list args) { - va_list args_copy; - va_copy(args_copy, args); - - // Adding 1 to add space for terminating null character. - int size_s = vsnprintf(nullptr, 0, format, args); - auto size = static_cast(size_s); - std::vector buffer(size); - - vsnprintf(buffer.data(), size, format, args_copy); - switch (level) { - case YGLogLevelError: - react_native_log_error(buffer.data()); - break; - case YGLogLevelFatal: - react_native_log_fatal(buffer.data()); - break; - case YGLogLevelWarn: - react_native_log_warn(buffer.data()); - break; - case YGLogLevelInfo: - case YGLogLevelDebug: - case YGLogLevelVerbose: - default: - react_native_log_info(buffer.data()); - } - - return size_s; -} - -thread_local LayoutContext threadLocalLayoutContext; - -ShadowNodeTraits YogaLayoutableShadowNode::BaseTraits() { - auto traits = LayoutableShadowNode::BaseTraits(); - traits.set(IdentifierTrait()); - return traits; -} - -ShadowNodeTraits::Trait YogaLayoutableShadowNode::IdentifierTrait() { - return ShadowNodeTraits::Trait::YogaLayoutableKind; -} - -YogaLayoutableShadowNode::YogaLayoutableShadowNode( - const ShadowNodeFragment& fragment, - const ShadowNodeFamily::Shared& family, - ShadowNodeTraits traits) - : LayoutableShadowNode(fragment, family, traits), - yogaConfig_(FabricDefaultYogaLog), - yogaNode_(&initializeYogaConfig(yogaConfig_)) { - yogaNode_.setContext(this); - - // Newly created node must be `dirty` just because it is new. - // This is not a default for `yoga::Node`. - yogaNode_.setDirty(true); - - if (getTraits().check(ShadowNodeTraits::Trait::MeasurableYogaNode)) { - react_native_assert( - getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)); - - yogaNode_.setMeasureFunc( - YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector); - } - - updateYogaProps(); - updateYogaChildren(); - - ensureConsistency(); -} - -YogaLayoutableShadowNode::YogaLayoutableShadowNode( - const ShadowNode& sourceShadowNode, - const ShadowNodeFragment& fragment) - : LayoutableShadowNode(sourceShadowNode, fragment), - yogaConfig_(FabricDefaultYogaLog), - yogaNode_(static_cast(sourceShadowNode) - .yogaNode_) { -// Note, cloned `yoga::Node` instance (copied using copy-constructor) inherits -// dirty flag, measure function, and other properties being set originally in -// the `YogaLayoutableShadowNode` constructor above. - -// There is a known race condition when background executor is enabled, where -// a tree may be laid out on the Fabric background thread concurrently with -// the ShadowTree being created on the JS thread. This assert can be -// re-enabled after disabling background executor everywhere. -#if 0 - react_native_assert( - static_cast(sourceShadowNode) - .yogaNode_.isDirty() == yogaNode_.isDirty() && - "Yoga node must inherit dirty flag."); -#endif - - if (!getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) { - for (auto& child : getChildren()) { - if (auto layoutableChild = traitCast(child)) { - yogaLayoutableChildren_.push_back(layoutableChild); - } - } - } - - YGConfigConstRef previousConfig = - &static_cast(sourceShadowNode) - .yogaConfig_; - - yogaNode_.setContext(this); - yogaNode_.setOwner(nullptr); - yogaNode_.setConfig(&initializeYogaConfig(yogaConfig_, previousConfig)); - updateYogaChildrenOwnersIfNeeded(); - - // This is the only legit place where we can dirty cloned Yoga node. - // If we do it later, ancestor nodes will not be able to observe this and - // dirty (and clone) themselves as a result. - if (getTraits().check(ShadowNodeTraits::Trait::DirtyYogaNode) || - getTraits().check(ShadowNodeTraits::Trait::MeasurableYogaNode)) { - yogaNode_.setDirty(true); - } - - // We do not need to reconfigure this subtree before the next layout pass if - // the previous node with the same props and children has already been - // configured. - if (!fragment.props && !fragment.children) { - yogaTreeHasBeenConfigured_ = - static_cast(sourceShadowNode) - .yogaTreeHasBeenConfigured_; - } - - if (fragment.props) { - updateYogaProps(); - } - - if (fragment.children) { - updateYogaChildren(); - } - - ensureConsistency(); -} - -void YogaLayoutableShadowNode::cleanLayout() { - yogaNode_.setDirty(false); -} - -void YogaLayoutableShadowNode::dirtyLayout() { - yogaNode_.setDirty(true); -} - -bool YogaLayoutableShadowNode::getIsLayoutClean() const { - return !yogaNode_.isDirty(); -} - -#pragma mark - Mutating Methods - -void YogaLayoutableShadowNode::enableMeasurement() { - ensureUnsealed(); - - yogaNode_.setMeasureFunc( - YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector); -} - -void YogaLayoutableShadowNode::appendYogaChild( - const YogaLayoutableShadowNode::Shared& childNode) { - // The caller must check this before calling this method. - react_native_assert( - !getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)); - - ensureYogaChildrenLookFine(); - - yogaLayoutableChildren_.push_back(childNode); - yogaNode_.insertChild(&childNode->yogaNode_, yogaNode_.getChildren().size()); - - ensureYogaChildrenLookFine(); -} - -void YogaLayoutableShadowNode::adoptYogaChild(size_t index) { - ensureUnsealed(); - ensureYogaChildrenLookFine(); - - // The caller must check this before calling this method. - react_native_assert( - !getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)); - - auto& childNode = - traitCast(*getChildren().at(index)); - - if (childNode.yogaNode_.getOwner() == nullptr) { - // The child node is not owned. - childNode.yogaNode_.setOwner(&yogaNode_); - // At this point the child yoga node must be already inserted by the caller. - // react_native_assert(layoutableChildNode.yogaNode_.isDirty()); - } else { - // The child is owned by some other node, we need to clone that. - // TODO: At this point, React has wrong reference to the node. (T138668036) - auto clonedChildNode = childNode.clone({}); - - // Replace the child node with a newly cloned one in the children list. - replaceChild(childNode, clonedChildNode, static_cast(index)); - } - - ensureYogaChildrenLookFine(); -} - -void YogaLayoutableShadowNode::appendChild( - const ShadowNode::Shared& childNode) { - ensureUnsealed(); - ensureConsistency(); - - // Calling the base class (`ShadowNode`) method. - LayoutableShadowNode::appendChild(childNode); - - if (getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) { - // This node is a declared leaf. - return; - } - - if (auto yogaLayoutableChild = - traitCast(childNode)) { - // Here we don't have information about the previous structure of the node - // (if it that existed before), so we don't have anything to compare the - // Yoga node with (like a previous version of this node). Therefore we must - // dirty the node. - yogaNode_.setDirty(true); - - // Appending the Yoga node. - appendYogaChild(yogaLayoutableChild); - - ensureYogaChildrenLookFine(); - ensureYogaChildrenAlignment(); - - // Adopting the Yoga node. - adoptYogaChild(getChildren().size() - 1); - - ensureConsistency(); - } -} - -void YogaLayoutableShadowNode::replaceChild( - const ShadowNode& oldChild, - const ShadowNode::Shared& newChild, - int32_t suggestedIndex) { - LayoutableShadowNode::replaceChild(oldChild, newChild, suggestedIndex); - - ensureUnsealed(); - ensureYogaChildrenLookFine(); - - auto layoutableOldChild = - traitCast(&oldChild); - auto layoutableNewChild = traitCast(newChild); - - if (layoutableOldChild == nullptr && layoutableNewChild == nullptr) { - // No need to mutate yogaLayoutableChildren_ - return; - } - - bool suggestedIndexAccurate = suggestedIndex >= 0 && - suggestedIndex < static_cast(yogaLayoutableChildren_.size()) && - yogaLayoutableChildren_[suggestedIndex].get() == layoutableOldChild; - - auto oldChildIter = suggestedIndexAccurate - ? yogaLayoutableChildren_.begin() + suggestedIndex - : std::find_if( - yogaLayoutableChildren_.begin(), - yogaLayoutableChildren_.end(), - [&](const YogaLayoutableShadowNode::Shared& layoutableChild) { - return layoutableChild.get() == layoutableOldChild; - }); - auto oldChildIndex = - static_cast(oldChildIter - yogaLayoutableChildren_.begin()); - - if (oldChildIter == yogaLayoutableChildren_.end()) { - // oldChild does not exist as part of our node - return; - } - - if (layoutableNewChild) { - // Both children are layoutable, replace the old one with the new one - react_native_assert(layoutableNewChild->yogaNode_.getOwner() == nullptr); - layoutableNewChild->yogaNode_.setOwner(&yogaNode_); - *oldChildIter = layoutableNewChild; - yogaNode_.replaceChild(&layoutableNewChild->yogaNode_, oldChildIndex); - } else { - // Layoutable child replaced with non layoutable child. Remove the previous - // child from the layoutable children list. - yogaLayoutableChildren_.erase(oldChildIter); - yogaNode_.removeChild(oldChildIndex); - } - - ensureYogaChildrenLookFine(); -} - -bool YogaLayoutableShadowNode::doesOwn( - const YogaLayoutableShadowNode& child) const { - return child.yogaNode_.getOwner() == &yogaNode_; -} - -void YogaLayoutableShadowNode::updateYogaChildrenOwnersIfNeeded() { - for (auto& childYogaNode : yogaNode_.getChildren()) { - if (childYogaNode->getOwner() == &yogaNode_) { - childYogaNode->setOwner( - reinterpret_cast(0xBADC0FFEE0DDF00D)); - } - } -} - -void YogaLayoutableShadowNode::updateYogaChildren() { - if (getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) { - return; - } - - ensureUnsealed(); - - bool isClean = !yogaNode_.isDirty() && - getChildren().size() == yogaNode_.getChildren().size(); - - auto oldYogaChildren = - isClean ? yogaNode_.getChildren() : std::vector{}; - - yogaNode_.setChildren({}); - yogaLayoutableChildren_.clear(); - - for (size_t i = 0; i < getChildren().size(); i++) { - if (auto yogaLayoutableChild = - traitCast(getChildren()[i])) { - appendYogaChild(yogaLayoutableChild); - adoptYogaChild(i); - - if (isClean) { - auto yogaChildIndex = yogaLayoutableChildren_.size() - 1; - auto& oldYogaChildNode = *oldYogaChildren.at(yogaChildIndex); - auto& newYogaChildNode = - yogaLayoutableChildren_.at(yogaChildIndex)->yogaNode_; - - isClean = isClean && !newYogaChildNode.isDirty() && - (newYogaChildNode.getStyle() == oldYogaChildNode.getStyle()); - } - } - } - - react_native_assert( - yogaLayoutableChildren_.size() == yogaNode_.getChildren().size()); - - yogaNode_.setDirty(!isClean); -} - -void YogaLayoutableShadowNode::updateYogaProps() { - ensureUnsealed(); - - auto& props = static_cast(*props_); - auto styleResult = applyAliasedProps(props.yogaStyle, props); - - // Resetting `dirty` flag only if `yogaStyle` portion of `Props` was changed. - if (!yogaNode_.isDirty() && (styleResult != yogaNode_.getStyle())) { - yogaNode_.setDirty(true); - } - - yogaNode_.setStyle(styleResult); -} - -/*static*/ yoga::Style YogaLayoutableShadowNode::applyAliasedProps( - const yoga::Style& baseStyle, - const YogaStylableProps& props) { - yoga::Style result{baseStyle}; - - // Aliases with precedence - if (props.insetInlineEnd.isDefined()) { - result.setPosition(YGEdgeEnd, props.insetInlineEnd); - } - if (props.insetInlineStart.isDefined()) { - result.setPosition(YGEdgeStart, props.insetInlineStart); - } - if (props.marginInline.isDefined()) { - result.setMargin(YGEdgeHorizontal, props.marginInline); - } - if (props.marginInlineStart.isDefined()) { - result.setMargin(YGEdgeStart, props.marginInlineStart); - } - if (props.marginInlineEnd.isDefined()) { - result.setMargin(YGEdgeEnd, props.marginInlineEnd); - } - if (props.marginBlock.isDefined()) { - result.setMargin(YGEdgeVertical, props.marginBlock); - } - if (props.paddingInline.isDefined()) { - result.setPadding(YGEdgeHorizontal, props.paddingInline); - } - if (props.paddingInlineStart.isDefined()) { - result.setPadding(YGEdgeStart, props.paddingInlineStart); - } - if (props.paddingInlineEnd.isDefined()) { - result.setPadding(YGEdgeEnd, props.paddingInlineEnd); - } - if (props.paddingBlock.isDefined()) { - result.setPadding(YGEdgeVertical, props.paddingBlock); - } - - // Aliases without precedence - if (result.position(YGEdgeBottom).isUndefined()) { - result.setPosition(YGEdgeBottom, props.insetBlockEnd); - } - if (result.position(YGEdgeTop).isUndefined()) { - result.setPosition(YGEdgeTop, props.insetBlockStart); - } - if (result.margin(YGEdgeTop).isUndefined()) { - result.setMargin(YGEdgeTop, props.marginBlockStart); - } - if (result.margin(YGEdgeBottom).isUndefined()) { - result.setMargin(YGEdgeBottom, props.marginBlockEnd); - } - if (result.padding(YGEdgeTop).isUndefined()) { - result.setPadding(YGEdgeTop, props.paddingBlockStart); - } - if (result.padding(YGEdgeBottom).isUndefined()) { - result.setPadding(YGEdgeBottom, props.paddingBlockEnd); - } - - return result; -} - -void YogaLayoutableShadowNode::configureYogaTree( - float pointScaleFactor, - YGErrata defaultErrata, - bool swapLeftAndRight) { - ensureUnsealed(); - - // Set state on our own Yoga node - YGErrata errata = resolveErrata(defaultErrata); - YGConfigSetErrata(&yogaConfig_, errata); - YGConfigSetPointScaleFactor(&yogaConfig_, pointScaleFactor); - - // TODO: `swapLeftAndRight` modified backing props and cannot be undone - if (swapLeftAndRight) { - swapStyleLeftAndRight(); - } - - yogaTreeHasBeenConfigured_ = true; - - // Recursively propagate the configuration to child nodes. If a child was - // already configured as part of a previous ShadowTree generation, we only - // need to reconfigure it if the context values passed to the Node have - // changed. - for (size_t i = 0; i < yogaLayoutableChildren_.size(); i++) { - const auto& child = *yogaLayoutableChildren_[i]; - auto childLayoutMetrics = child.getLayoutMetrics(); - auto childErrata = - YGConfigGetErrata(const_cast(&child.yogaConfig_)); - - if (child.yogaTreeHasBeenConfigured_ && - childLayoutMetrics.pointScaleFactor == pointScaleFactor && - childLayoutMetrics.wasLeftAndRightSwapped == swapLeftAndRight && - childErrata == child.resolveErrata(errata)) { - continue; - } - - if (doesOwn(child)) { - auto& mutableChild = const_cast(child); - mutableChild.configureYogaTree( - pointScaleFactor, child.resolveErrata(errata), swapLeftAndRight); - } else { - cloneChildInPlace(i).configureYogaTree( - pointScaleFactor, errata, swapLeftAndRight); - } - } -} - -YGErrata YogaLayoutableShadowNode::resolveErrata(YGErrata defaultErrata) const { - if (auto viewShadowNode = traitCast(this)) { - const auto& props = viewShadowNode->getConcreteProps(); - switch (props.experimental_layoutConformance) { - case LayoutConformance::Classic: - return YGErrataAll; - case LayoutConformance::Strict: - return YGErrataNone; - case LayoutConformance::Undefined: - return defaultErrata; - } - } - - return defaultErrata; -} - -YogaLayoutableShadowNode& YogaLayoutableShadowNode::cloneChildInPlace( - size_t layoutableChildIndex) { - ensureUnsealed(); - - const auto& childNode = *yogaLayoutableChildren_[layoutableChildIndex]; - - // TODO: Why does this not use `ShadowNodeFragment::statePlaceholder()` like - // `adoptYogaChild()`? - auto clonedChildNode = childNode.clone( - {ShadowNodeFragment::propsPlaceholder(), - ShadowNodeFragment::childrenPlaceholder(), - childNode.getState()}); - - replaceChild( - childNode, clonedChildNode, static_cast(layoutableChildIndex)); - return static_cast(*clonedChildNode); -} - -void YogaLayoutableShadowNode::setSize(Size size) const { - ensureUnsealed(); - - auto style = yogaNode_.getStyle(); - style.setDimension( - yoga::Dimension::Width, - yoga::CompactValue::ofMaybe(size.width)); - style.setDimension( - yoga::Dimension::Height, - yoga::CompactValue::ofMaybe(size.height)); - yogaNode_.setStyle(style); - yogaNode_.setDirty(true); -} - -void YogaLayoutableShadowNode::setPadding(RectangleEdges padding) const { - ensureUnsealed(); - - auto style = yogaNode_.getStyle(); - - auto leftPadding = yoga::CompactValue::ofMaybe(padding.left); - auto topPadding = yoga::CompactValue::ofMaybe(padding.top); - auto rightPadding = yoga::CompactValue::ofMaybe(padding.right); - auto bottomPadding = yoga::CompactValue::ofMaybe(padding.bottom); - - if (leftPadding != style.padding(YGEdgeLeft) || - topPadding != style.padding(YGEdgeTop) || - rightPadding != style.padding(YGEdgeRight) || - bottomPadding != style.padding(YGEdgeBottom)) { - style.setPadding( - YGEdgeTop, yoga::CompactValue::ofMaybe(padding.top)); - style.setPadding( - YGEdgeLeft, yoga::CompactValue::ofMaybe(padding.left)); - style.setPadding( - YGEdgeRight, yoga::CompactValue::ofMaybe(padding.right)); - style.setPadding( - YGEdgeBottom, yoga::CompactValue::ofMaybe(padding.bottom)); - yogaNode_.setStyle(style); - yogaNode_.setDirty(true); - } -} - -void YogaLayoutableShadowNode::setPositionType( - YGPositionType positionType) const { - ensureUnsealed(); - - auto style = yogaNode_.getStyle(); - style.positionType() = yoga::scopedEnum(positionType); - yogaNode_.setStyle(style); - yogaNode_.setDirty(true); -} - -void YogaLayoutableShadowNode::layoutTree( - LayoutContext layoutContext, - LayoutConstraints layoutConstraints) { - ensureUnsealed(); - - SystraceSection s1("YogaLayoutableShadowNode::layoutTree"); - - bool swapLeftAndRight = layoutContext.swapLeftAndRightInRTL && - (layoutConstraints.layoutDirection == LayoutDirection::RightToLeft || - !CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR); - - { - SystraceSection s2("YogaLayoutableShadowNode::configureYogaTree"); - configureYogaTree( - layoutContext.pointScaleFactor, - YGErrataAll /*defaultErrata*/, - swapLeftAndRight); - } - - auto minimumSize = layoutConstraints.minimumSize; - auto maximumSize = layoutConstraints.maximumSize; - - // The caller must ensure that layout constraints make sense. - // Values cannot be NaN. - react_native_assert(!std::isnan(minimumSize.width)); - react_native_assert(!std::isnan(minimumSize.height)); - react_native_assert(!std::isnan(maximumSize.width)); - react_native_assert(!std::isnan(maximumSize.height)); - // Values cannot be negative. - react_native_assert(minimumSize.width >= 0); - react_native_assert(minimumSize.height >= 0); - react_native_assert(maximumSize.width >= 0); - react_native_assert(maximumSize.height >= 0); - // Minimum size cannot be infinity. - react_native_assert(!std::isinf(minimumSize.width)); - react_native_assert(!std::isinf(minimumSize.height)); - - // Internally Yoga uses three different measurement modes controlling layout - // constraints: `Undefined`, `Exactly`, and `AtMost`. These modes are an - // implementation detail and are not defined in `CSS Flexible Box Layout - // Module`. Yoga C++ API (and `YGNodeCalculateLayout` function particularly) - // does not allow to specify the measure modes explicitly. Instead, it infers - // these from styles associated with the root node. - // To pass the actual layout constraints to Yoga we represent them as - // `(min/max)(Height/Width)` style properties. Also, we pass `ownerWidth` & - // `ownerHeight` to allow proper calculation of relative (e.g. specified in - // percents) style values. - - auto& yogaStyle = yogaNode_.getStyle(); - - auto ownerWidth = yogaFloatFromFloat(maximumSize.width); - auto ownerHeight = yogaFloatFromFloat(maximumSize.height); - - yogaStyle.setMaxDimension( - yoga::Dimension::Width, - yoga::CompactValue::ofMaybe(maximumSize.width)); - - yogaStyle.setMaxDimension( - yoga::Dimension::Height, - yoga::CompactValue::ofMaybe(maximumSize.height)); - - yogaStyle.setMinDimension( - yoga::Dimension::Width, - yoga::CompactValue::ofMaybe(minimumSize.width)); - - yogaStyle.setMinDimension( - yoga::Dimension::Height, - yoga::CompactValue::ofMaybe(minimumSize.height)); - - auto direction = - yogaDirectionFromLayoutDirection(layoutConstraints.layoutDirection); - - threadLocalLayoutContext = layoutContext; - - { - SystraceSection s3("YogaLayoutableShadowNode::YGNodeCalculateLayout"); - YGNodeCalculateLayout(&yogaNode_, ownerWidth, ownerHeight, direction); - } - - // Update layout metrics for root node. Updated for children in - // YogaLayoutableShadowNode::layout - if (yogaNode_.getHasNewLayout()) { - auto layoutMetrics = layoutMetricsFromYogaNode(yogaNode_); - layoutMetrics.pointScaleFactor = layoutContext.pointScaleFactor; - layoutMetrics.wasLeftAndRightSwapped = swapLeftAndRight; - setLayoutMetrics(layoutMetrics); - yogaNode_.setHasNewLayout(false); - } - - layout(layoutContext); -} - -static EdgeInsets calculateOverflowInset( - Rect contentFrame, - Rect contentBounds) { - auto size = contentFrame.size; - auto overflowInset = EdgeInsets{}; - overflowInset.left = std::min(contentBounds.getMinX(), Float{0.0}); - overflowInset.top = std::min(contentBounds.getMinY(), Float{0.0}); - overflowInset.right = - -std::max(contentBounds.getMaxX() - size.width, Float{0.0}); - overflowInset.bottom = - -std::max(contentBounds.getMaxY() - size.height, Float{0.0}); - return overflowInset; -} - -void YogaLayoutableShadowNode::layout(LayoutContext layoutContext) { - // Reading data from a dirtied node does not make sense. - react_native_assert(!yogaNode_.isDirty()); - - for (auto childYogaNode : yogaNode_.getChildren()) { - auto& childNode = shadowNodeFromContext(childYogaNode); - - // Verifying that the Yoga node belongs to the ShadowNode. - react_native_assert(&childNode.yogaNode_ == childYogaNode); - - if (childYogaNode->getHasNewLayout()) { - childYogaNode->setHasNewLayout(false); - - // Reading data from a dirtied node does not make sense. - react_native_assert(!childYogaNode->isDirty()); - - // We must copy layout metrics from Yoga node only once (when the parent - // node exclusively ownes the child node). - react_native_assert(childYogaNode->getOwner() == &yogaNode_); - - // We are about to mutate layout metrics of the node. - childNode.ensureUnsealed(); - - auto newLayoutMetrics = layoutMetricsFromYogaNode(*childYogaNode); - newLayoutMetrics.pointScaleFactor = layoutContext.pointScaleFactor; - newLayoutMetrics.wasLeftAndRightSwapped = - layoutContext.swapLeftAndRightInRTL && - (newLayoutMetrics.layoutDirection == LayoutDirection::RightToLeft || - !CoreFeatures::doNotSwapLeftAndRightOnAndroidInLTR); - - // Child node's layout has changed. When a node is added to - // `affectedNodes`, onLayout event is called on the component. Comparing - // `newLayoutMetrics.frame` with `childNode.getLayoutMetrics().frame` to - // detect if layout has not changed is not advised, please refer to - // D22999891 for details. - if (layoutContext.affectedNodes != nullptr) { - layoutContext.affectedNodes->push_back(&childNode); - } - - childNode.setLayoutMetrics(newLayoutMetrics); - - if (newLayoutMetrics.displayType != DisplayType::None) { - childNode.layout(layoutContext); - } - } - } - - if (yogaNode_.getStyle().overflow() == yoga::Overflow::Visible) { - // Note that the parent node's overflow layout is NOT affected by its - // transform matrix. That transform matrix is applied on the parent node as - // well as all of its child nodes, which won't cause changes on the - // overflowInset values. A special note on the scale transform -- the scaled - // layout may look like it's causing overflowInset changes, but it's purely - // cosmetic and will be handled by pixel density conversion logic later when - // render the view. The actual overflowInset value is not changed as if the - // transform is not happening here. - auto contentBounds = getContentBounds(); - layoutMetrics_.overflowInset = - calculateOverflowInset(layoutMetrics_.frame, contentBounds); - } else { - layoutMetrics_.overflowInset = {}; - } -} - -Rect YogaLayoutableShadowNode::getContentBounds() const { - auto contentBounds = Rect{}; - - for (auto childYogaNode : yogaNode_.getChildren()) { - auto& childNode = shadowNodeFromContext(childYogaNode); - - // Verifying that the Yoga node belongs to the ShadowNode. - react_native_assert(&childNode.yogaNode_ == childYogaNode); - - auto layoutMetricsWithOverflowInset = childNode.getLayoutMetrics(); - if (layoutMetricsWithOverflowInset.displayType != DisplayType::None) { - auto viewChildNode = traitCast(&childNode); - auto hitSlop = viewChildNode != nullptr - ? viewChildNode->getConcreteProps().hitSlop - : EdgeInsets{}; - - // The contentBounds should always union with existing child node layout + - // overflowInset. The transform may in a deferred animation and not - // applied yet. - contentBounds.unionInPlace(insetBy( - layoutMetricsWithOverflowInset.frame, - layoutMetricsWithOverflowInset.overflowInset)); - contentBounds.unionInPlace( - outsetBy(layoutMetricsWithOverflowInset.frame, hitSlop)); - - auto childTransform = childNode.getTransform(); - if (childTransform != Transform::Identity()) { - // The child node's transform matrix will affect the parent node's - // contentBounds. We need to union with child node's after transform - // layout here. - contentBounds.unionInPlace(insetBy( - layoutMetricsWithOverflowInset.frame * childTransform, - layoutMetricsWithOverflowInset.overflowInset * childTransform)); - contentBounds.unionInPlace(outsetBy( - layoutMetricsWithOverflowInset.frame * childTransform, hitSlop)); - } - } - } - - return contentBounds; -} - -#pragma mark - Yoga Connectors - -YGNodeRef YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector( - YGNodeConstRef /*oldYogaNode*/, - YGNodeConstRef parentYogaNode, - size_t childIndex) { - SystraceSection s("YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector"); - - auto& parentNode = shadowNodeFromContext(parentYogaNode); - return &parentNode.cloneChildInPlace(childIndex).yogaNode_; -} - -YGSize YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector( - YGNodeConstRef yogaNode, - float width, - YGMeasureMode widthMode, - float height, - YGMeasureMode heightMode) { - SystraceSection s( - "YogaLayoutableShadowNode::yogaNodeMeasureCallbackConnector"); - - auto& shadowNode = shadowNodeFromContext(yogaNode); - - auto minimumSize = Size{0, 0}; - auto maximumSize = Size{ - std::numeric_limits::infinity(), - std::numeric_limits::infinity()}; - - switch (widthMode) { - case YGMeasureModeUndefined: - break; - case YGMeasureModeExactly: - minimumSize.width = floatFromYogaFloat(width); - maximumSize.width = floatFromYogaFloat(width); - break; - case YGMeasureModeAtMost: - maximumSize.width = floatFromYogaFloat(width); - break; - } - - switch (heightMode) { - case YGMeasureModeUndefined: - break; - case YGMeasureModeExactly: - minimumSize.height = floatFromYogaFloat(height); - maximumSize.height = floatFromYogaFloat(height); - break; - case YGMeasureModeAtMost: - maximumSize.height = floatFromYogaFloat(height); - break; - } - - auto size = shadowNode.measureContent( - threadLocalLayoutContext, {minimumSize, maximumSize}); - - return YGSize{ - yogaFloatFromFloat(size.width), yogaFloatFromFloat(size.height)}; -} - -YogaLayoutableShadowNode& YogaLayoutableShadowNode::shadowNodeFromContext( - YGNodeConstRef yogaNode) { - return traitCast( - *static_cast(YGNodeGetContext(yogaNode))); -} - -yoga::Config& YogaLayoutableShadowNode::initializeYogaConfig( - yoga::Config& config, - YGConfigConstRef previousConfig) { - YGConfigSetCloneNodeFunc( - &config, YogaLayoutableShadowNode::yogaNodeCloneCallbackConnector); - if (previousConfig != nullptr) { - YGConfigSetPointScaleFactor( - &config, YGConfigGetPointScaleFactor(previousConfig)); - YGConfigSetErrata(&config, YGConfigGetErrata(previousConfig)); - } - -#ifdef RN_DEBUG_YOGA_LOGGER - YGConfigSetPrintTreeFlag(&config, true); -#endif - return config; -} - -#pragma mark - RTL left and right swapping - -void YogaLayoutableShadowNode::swapStyleLeftAndRight() { - ensureUnsealed(); - - swapLeftAndRightInYogaStyleProps(*this); - swapLeftAndRightInViewProps(*this); -} - -void YogaLayoutableShadowNode::swapLeftAndRightInYogaStyleProps( - const YogaLayoutableShadowNode& shadowNode) { - auto yogaStyle = shadowNode.yogaNode_.getStyle(); - - // Swap Yoga node values, position, padding and margin. - - if (yogaStyle.position(YGEdgeLeft).isDefined()) { - yogaStyle.setPosition(YGEdgeStart, yogaStyle.position(YGEdgeLeft)); - yogaStyle.setPosition(YGEdgeLeft, yoga::CompactValue::ofUndefined()); - } - - if (yogaStyle.position(YGEdgeRight).isDefined()) { - yogaStyle.setPosition(YGEdgeEnd, yogaStyle.position(YGEdgeRight)); - yogaStyle.setPosition(YGEdgeRight, yoga::CompactValue::ofUndefined()); - } - - if (yogaStyle.padding(YGEdgeLeft).isDefined()) { - yogaStyle.setPadding(YGEdgeStart, yogaStyle.padding(YGEdgeLeft)); - yogaStyle.setPadding(YGEdgeLeft, yoga::CompactValue::ofUndefined()); - } - - if (yogaStyle.padding(YGEdgeRight).isDefined()) { - yogaStyle.setPadding(YGEdgeEnd, yogaStyle.padding(YGEdgeRight)); - yogaStyle.setPadding(YGEdgeRight, yoga::CompactValue::ofUndefined()); - } - - if (yogaStyle.margin(YGEdgeLeft).isDefined()) { - yogaStyle.setMargin(YGEdgeStart, yogaStyle.margin(YGEdgeLeft)); - yogaStyle.setMargin(YGEdgeLeft, yoga::CompactValue::ofUndefined()); - } - - if (yogaStyle.margin(YGEdgeRight).isDefined()) { - yogaStyle.setMargin(YGEdgeEnd, yogaStyle.margin(YGEdgeRight)); - yogaStyle.setMargin(YGEdgeRight, yoga::CompactValue::ofUndefined()); - } - - shadowNode.yogaNode_.setStyle(yogaStyle); -} - -void YogaLayoutableShadowNode::swapLeftAndRightInViewProps( - const YogaLayoutableShadowNode& shadowNode) { - auto& typedCasting = static_cast(*shadowNode.props_); - auto& props = const_cast(typedCasting); - - // Swap border node values, borderRadii, borderColors and borderStyles. - - if (props.borderRadii.topLeft.has_value()) { - props.borderRadii.topStart = props.borderRadii.topLeft; - props.borderRadii.topLeft.reset(); - } - - if (props.borderRadii.bottomLeft.has_value()) { - props.borderRadii.bottomStart = props.borderRadii.bottomLeft; - props.borderRadii.bottomLeft.reset(); - } - - if (props.borderRadii.topRight.has_value()) { - props.borderRadii.topEnd = props.borderRadii.topRight; - props.borderRadii.topRight.reset(); - } - - if (props.borderRadii.bottomRight.has_value()) { - props.borderRadii.bottomEnd = props.borderRadii.bottomRight; - props.borderRadii.bottomRight.reset(); - } - - if (props.borderColors.left.has_value()) { - props.borderColors.start = props.borderColors.left; - props.borderColors.left.reset(); - } - - if (props.borderColors.right.has_value()) { - props.borderColors.end = props.borderColors.right; - props.borderColors.right.reset(); - } - - if (props.borderStyles.left.has_value()) { - props.borderStyles.start = props.borderStyles.left; - props.borderStyles.left.reset(); - } - - if (props.borderStyles.right.has_value()) { - props.borderStyles.end = props.borderStyles.right; - props.borderStyles.right.reset(); - } - - if (props.yogaStyle.border(YGEdgeLeft).isDefined()) { - props.yogaStyle.setBorder(YGEdgeStart, props.yogaStyle.border(YGEdgeLeft)); - props.yogaStyle.setBorder(YGEdgeLeft, yoga::CompactValue::ofUndefined()); - } - - if (props.yogaStyle.border(YGEdgeRight).isDefined()) { - props.yogaStyle.setBorder(YGEdgeEnd, props.yogaStyle.border(YGEdgeRight)); - props.yogaStyle.setBorder(YGEdgeRight, yoga::CompactValue::ofUndefined()); - } -} - -#pragma mark - Consistency Ensuring Helpers - -void YogaLayoutableShadowNode::ensureConsistency() const { - ensureYogaChildrenLookFine(); - ensureYogaChildrenAlignment(); -} - -void YogaLayoutableShadowNode::ensureYogaChildrenLookFine() const { -#ifdef REACT_NATIVE_DEBUG - // Checking that the shapes of Yoga node children object look fine. - // This is the only heuristic that might produce false-positive results - // (really broken dangled nodes might look fine). This is useful as an early - // signal that something went wrong. - auto& yogaChildren = yogaNode_.getChildren(); - - for (const auto& yogaChild : yogaChildren) { - react_native_assert(yogaChild->getContext()); - react_native_assert(yogaChild->getChildren().size() < 16384); - if (!yogaChild->getChildren().empty()) { - react_native_assert(!yogaChild->hasMeasureFunc()); - } - } -#endif -} - -void YogaLayoutableShadowNode::ensureYogaChildrenAlignment() const { -#ifdef REACT_NATIVE_DEBUG - // If the node is not a leaf node, checking that: - // - All children are `YogaLayoutableShadowNode` subclasses. - // - All Yoga children are owned/connected to corresponding children of - // this node. - - auto& yogaChildren = yogaNode_.getChildren(); - auto& children = yogaLayoutableChildren_; - - if (getTraits().check(ShadowNodeTraits::Trait::LeafYogaNode)) { - react_native_assert(yogaChildren.empty()); - return; - } - - react_native_assert(yogaChildren.size() == children.size()); - - for (size_t i = 0; i < children.size(); i++) { - auto& yogaChild = yogaChildren.at(i); - auto& child = children.at(i); - react_native_assert( - yogaChild->getContext() == - traitCast(child.get())); - } -#endif -} - -} // namespace facebook::react \ No newline at end of file diff --git a/vnext/overrides.json b/vnext/overrides.json index 0ce35454b3a..c027aeb0dd7 100644 --- a/vnext/overrides.json +++ b/vnext/overrides.json @@ -52,13 +52,6 @@ "baseFile": "packages/react-native/ReactCommon/react/renderer/imagemanager/ImageRequest.cpp", "baseHash": "a72d01a2516c09f453090181cb22beeef2a4b29c" }, - { - "type": "copy", - "file": "Microsoft.ReactNative/Fabric/platform/react/renderer/components/view/YogaLayoutableShadowNode.cpp", - "baseFile": "packages/react-native/ReactCommon/react/renderer/components/view/YogaLayoutableShadowNode.cpp", - "baseHash": "a5821ed70a5be50febe8f69dfbef10be1147b2d5", - "issue": 7821 - }, { "type": "copy", "file": "Microsoft.ReactNative/Fabric/platform/react/renderer/graphics/Float.h", @@ -68,7 +61,7 @@ }, { "type": "patch", - "file": "ReactCommon/TEMP_UntilReactCommonUPdate/jsi/jsi/test/testlib.cpp", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp", "baseFile": "packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp", "baseHash": "224ddd5bc92672790e8875bf3078f0529aca05d0", "issue": 12210 From 98d427c3d2e9795c9285d72c60b93d1901b14558 Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Tue, 9 Jan 2024 12:00:26 -0800 Subject: [PATCH 04/16] integrate c30f2b620 --- .../react-native-win32-tester/overrides.json | 2 +- .../react-native-win32-tester/package.json | 4 +- .../react-native-win32/.flowconfig | 2 +- .../react-native-win32/overrides.json | 10 +- .../react-native-win32/package.json | 18 +- .../Components/ScrollView/ScrollView.win32.js | 15 - .../Components/TextInput/TextInput.win32.js | 5 +- .../src/Libraries/Utilities/useMergeRefs.js | 14 +- .../automation-channel/package.json | 2 +- .../tester/overrides.json | 2 +- .../@react-native-windows/tester/package.json | 4 +- .../@react-native/monorepo/overrides.json | 4 +- packages/@react-native/monorepo/package.json | 8 +- packages/@react-native/tester/overrides.json | 2 +- packages/e2e-test-app-fabric/package.json | 2 +- packages/e2e-test-app/package.json | 2 +- packages/integration-test-app/package.json | 2 +- packages/playground/package.json | 2 +- packages/sample-apps/package.json | 2 +- vnext/.flowconfig | 2 +- .../CompositionViewComponentView.cpp | 3 +- .../jsi/jsi/JSIDynamic.cpp | 2 +- .../jsi/jsi/JSIDynamic.h | 2 +- .../jsi/jsi/test/testlib.cpp | 19 + .../components/view/YogaStylableProps.cpp | 361 +-- .../yoga/yoga/node/LayoutResults.h | 81 +- .../yoga/yoga/node/Node.h | 24 +- .../yoga/yoga/style/Style.h | 301 ++ vnext/ReactCommon/Yoga.cpp | 273 +- .../react/components/rnwcore/Props.cpp | 4 +- .../codegen/react/components/rnwcore/Props.h | 4 +- vnext/codegen/rnwcoreJSI.h | 2637 +++++++++++++++-- vnext/overrides.json | 40 +- vnext/package.json | 18 +- .../Components/Switch/Switch.windows.js | 1 - .../Components/TextInput/TextInput.windows.js | 5 +- yarn.lock | 210 +- 37 files changed, 3364 insertions(+), 725 deletions(-) create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h diff --git a/packages/@office-iss/react-native-win32-tester/overrides.json b/packages/@office-iss/react-native-win32-tester/overrides.json index 33ded5a9ade..309883ab6c2 100644 --- a/packages/@office-iss/react-native-win32-tester/overrides.json +++ b/packages/@office-iss/react-native-win32-tester/overrides.json @@ -5,7 +5,7 @@ "excludePatterns": [ "src/js/examples-win32/**" ], - "baseVersion": "0.74.0-nightly-20231124-c464b215e", + "baseVersion": "0.74.0-nightly-20231201-c30f2b620", "overrides": [ { "type": "patch", diff --git a/packages/@office-iss/react-native-win32-tester/package.json b/packages/@office-iss/react-native-win32-tester/package.json index 4dfb9b44238..5c5d5714cfe 100644 --- a/packages/@office-iss/react-native-win32-tester/package.json +++ b/packages/@office-iss/react-native-win32-tester/package.json @@ -19,7 +19,7 @@ "peerDependencies": { "@office-iss/react-native-win32": "^0.0.0-canary.225", "react": "18.0.0", - "react-native": "0.74.0-nightly-20231124-c464b215e" + "react-native": "0.74.0-nightly-20231201-c30f2b620" }, "devDependencies": { "@office-iss/react-native-win32": "^0.0.0-canary.225", @@ -30,7 +30,7 @@ "@types/node": "^18.0.0", "eslint": "^8.19.0", "just-scripts": "^1.3.3", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-platform-override": "^1.9.17", "typescript": "^4.9.5" }, diff --git a/packages/@office-iss/react-native-win32/.flowconfig b/packages/@office-iss/react-native-win32/.flowconfig index c9d5a3cb0b3..14895bbccc1 100644 --- a/packages/@office-iss/react-native-win32/.flowconfig +++ b/packages/@office-iss/react-native-win32/.flowconfig @@ -148,4 +148,4 @@ untyped-import untyped-type-import [version] -^0.222.0 +^0.223.0 diff --git a/packages/@office-iss/react-native-win32/overrides.json b/packages/@office-iss/react-native-win32/overrides.json index c69d132b08b..a3ead795aa4 100644 --- a/packages/@office-iss/react-native-win32/overrides.json +++ b/packages/@office-iss/react-native-win32/overrides.json @@ -7,13 +7,13 @@ "**/__snapshots__/**", "src/rntypes/**" ], - "baseVersion": "0.74.0-nightly-20231124-c464b215e", + "baseVersion": "0.74.0-nightly-20231201-c30f2b620", "overrides": [ { "type": "derived", "file": ".flowconfig", "baseFile": ".flowconfig", - "baseHash": "397a9d59e4415e8758adc635d5e016070e6d85d7" + "baseHash": "172a4663d9243a77e3b35a2d8a5e403fd62062cf" }, { "type": "derived", @@ -112,7 +112,7 @@ "type": "derived", "file": "src/Libraries/Components/ScrollView/ScrollView.win32.js", "baseFile": "packages/react-native/Libraries/Components/ScrollView/ScrollView.js", - "baseHash": "6e3e4933173d1f910232f3f46602e2f525127eb5" + "baseHash": "6367cf4ba4637cd8292b68c629cb9d59df99ade1" }, { "type": "platform", @@ -130,7 +130,7 @@ "type": "derived", "file": "src/Libraries/Components/TextInput/TextInput.win32.js", "baseFile": "packages/react-native/Libraries/Components/TextInput/TextInput.js", - "baseHash": "fa10fcf147f79ede6f3a49fac45faefed48e1693" + "baseHash": "f6742637eda13080bd175a45eb0edbc83fa260c5" }, { "type": "patch", @@ -511,7 +511,7 @@ "type": "copy", "file": "src/Libraries/Utilities/useMergeRefs.js", "baseFile": "packages/react-native/Libraries/Utilities/useMergeRefs.js", - "baseHash": "d21cc9b2de5af9f398429e7a03c5f13ea7dc7227" + "baseHash": "1f1ca637132e6e0fe1549ba520d98508269ca2bd" } ] } \ No newline at end of file diff --git a/packages/@office-iss/react-native-win32/package.json b/packages/@office-iss/react-native-win32/package.json index 665a848aec5..1e0d3da0ffc 100644 --- a/packages/@office-iss/react-native-win32/package.json +++ b/packages/@office-iss/react-native-win32/package.json @@ -30,14 +30,14 @@ "@react-native-community/cli-platform-android": "12.0.0", "@react-native-community/cli-platform-ios": "12.0.0", "@react-native/assets": "1.0.0", - "@react-native/assets-registry": "0.74.0-nightly-20231124-c464b215e", - "@react-native/codegen": "0.74.0-nightly-20231124-c464b215e", - "@react-native/community-cli-plugin": "0.74.0-nightly-20231124-c464b215e", - "@react-native/gradle-plugin": "0.74.0-nightly-20231124-c464b215e", - "@react-native/js-polyfills": "0.74.0-nightly-20231124-c464b215e", + "@react-native/assets-registry": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/codegen": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/community-cli-plugin": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/gradle-plugin": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/js-polyfills": "0.74.0-nightly-20231201-c30f2b620", "@react-native/metro-config": "^0.73.0", - "@react-native/normalize-colors": "0.74.0-nightly-20231124-c464b215e", - "@react-native/virtualized-lists": "0.74.0-nightly-20231124-c464b215e", + "@react-native/normalize-colors": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/virtualized-lists": "0.74.0-nightly-20231201-c30f2b620", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", @@ -85,13 +85,13 @@ "just-scripts": "^1.3.3", "prettier": "^2.4.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-platform-override": "^1.9.17", "typescript": "^4.9.5" }, "peerDependencies": { "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e" + "react-native": "0.74.0-nightly-20231201-c30f2b620" }, "beachball": { "defaultNpmTag": "canary", diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Components/ScrollView/ScrollView.win32.js b/packages/@office-iss/react-native-win32/src/Libraries/Components/ScrollView/ScrollView.win32.js index a650c003de4..5370f189dcd 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Components/ScrollView/ScrollView.win32.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Components/ScrollView/ScrollView.win32.js @@ -1148,21 +1148,6 @@ class ScrollView extends React.Component { } _handleScroll = (e: ScrollEvent) => { - if (__DEV__) { - if ( - this.props.onScroll && - this.props.scrollEventThrottle == null && - Platform.OS === 'ios' - ) { - console.log( - 'You specified `onScroll` on a but not ' + - '`scrollEventThrottle`. You will only receive one event. ' + - 'Using `16` you get all the events but be aware that it may ' + - "cause frame drops, use a bigger number if you don't need as " + - 'much precision.', - ); - } - } this._observedScrollSinceBecomingResponder = true; this.props.onScroll && this.props.onScroll(e); }; diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js b/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js index 09ddfa2f2e9..11fcf5771aa 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Components/TextInput/TextInput.win32.js @@ -1338,10 +1338,7 @@ function InternalTextInput(props: Props): React.Node { [mostRecentEventCount, viewCommands], ); - const ref = useMergeRefs( - setLocalRef, - props.forwardedRef, - ); + const ref = useMergeRefs(setLocalRef, props.forwardedRef); const _onChange = (event: ChangeEvent) => { const currentText = event.nativeEvent.text; diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Utilities/useMergeRefs.js b/packages/@office-iss/react-native-win32/src/Libraries/Utilities/useMergeRefs.js index 15bd982d036..1499e4eab3a 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Utilities/useMergeRefs.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Utilities/useMergeRefs.js @@ -8,13 +8,9 @@ * @format */ +import * as React from 'react'; import {useCallback} from 'react'; -type CallbackRef = T => mixed; -type ObjectRef = {current: T, ...}; - -type Ref = CallbackRef | ObjectRef; - /** * Constructs a new ref that forwards new values to each of the given refs. The * given refs will always be invoked in the order that they are supplied. @@ -24,11 +20,11 @@ type Ref = CallbackRef | ObjectRef; * the returned callback ref is supplied as a `ref` to a React element, this may * lead to problems with the given refs being invoked more times than desired. */ -export default function useMergeRefs( - ...refs: $ReadOnlyArray> -): CallbackRef { +export default function useMergeRefs( + ...refs: $ReadOnlyArray> +): (Instance | null) => void { return useCallback( - (current: T) => { + (current: Instance | null) => { for (const ref of refs) { if (ref != null) { if (typeof ref === 'function') { diff --git a/packages/@react-native-windows/automation-channel/package.json b/packages/@react-native-windows/automation-channel/package.json index fa2175b3ef2..29e28b8e5e1 100644 --- a/packages/@react-native-windows/automation-channel/package.json +++ b/packages/@react-native-windows/automation-channel/package.json @@ -31,7 +31,7 @@ "just-scripts": "^1.3.2", "prettier": "^2.4.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749", "typescript": "^4.9.5" }, diff --git a/packages/@react-native-windows/tester/overrides.json b/packages/@react-native-windows/tester/overrides.json index 0c0a7fcbcac..e0853e05892 100644 --- a/packages/@react-native-windows/tester/overrides.json +++ b/packages/@react-native-windows/tester/overrides.json @@ -5,7 +5,7 @@ "excludePatterns": [ "src/js/examples-win/**" ], - "baseVersion": "0.74.0-nightly-20231124-c464b215e", + "baseVersion": "0.74.0-nightly-20231201-c30f2b620", "overrides": [ { "type": "derived", diff --git a/packages/@react-native-windows/tester/package.json b/packages/@react-native-windows/tester/package.json index d8dd812649a..f70e2c53bc6 100644 --- a/packages/@react-native-windows/tester/package.json +++ b/packages/@react-native-windows/tester/package.json @@ -18,7 +18,7 @@ "peerDependencies": { "@react-native-picker/picker": "2.4.10", "react": "18.0.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749", "react-native-xaml": "^0.0.50" }, @@ -31,7 +31,7 @@ "@types/node": "^18.0.0", "eslint": "^8.19.0", "just-scripts": "^1.3.3", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-platform-override": "^1.9.17", "react-native-windows": "^0.0.0-canary.749", "typescript": "^4.9.5" diff --git a/packages/@react-native/monorepo/overrides.json b/packages/@react-native/monorepo/overrides.json index 8303ac5ed6d..cffec296054 100644 --- a/packages/@react-native/monorepo/overrides.json +++ b/packages/@react-native/monorepo/overrides.json @@ -1,11 +1,11 @@ { - "baseVersion": "0.74.0-nightly-20231124-c464b215e", + "baseVersion": "0.74.0-nightly-20231201-c30f2b620", "overrides": [ { "type": "patch", "file": "package.json", "baseFile": "package.json", - "baseHash": "fefc1a41353735adfc86885e6d11eebb659501a5" + "baseHash": "0e97ea56e9b9e6203f390035e923cb0a888d35a5" } ] } \ No newline at end of file diff --git a/packages/@react-native/monorepo/package.json b/packages/@react-native/monorepo/package.json index 6086c1a05ae..7945bcca150 100644 --- a/packages/@react-native/monorepo/package.json +++ b/packages/@react-native/monorepo/package.json @@ -80,10 +80,10 @@ "eslint-plugin-react-native": "^4.0.0", "eslint-plugin-redundant-undefined": "^0.4.0", "eslint-plugin-relay": "^1.8.3", - "flow-api-translator": "0.17.1", - "flow-bin": "^0.222.0", + "flow-api-translator": "0.18.0", + "flow-bin": "^0.223.0", "glob": "^7.1.1", - "hermes-eslint": "0.17.1", + "hermes-eslint": "0.18.0", "inquirer": "^7.1.0", "jest": "^29.6.3", "jest-junit": "^10.0.0", @@ -95,7 +95,7 @@ "mock-fs": "^5.1.4", "nullthrows": "^1.1.1", "prettier": "2.8.8", - "prettier-plugin-hermes-parser": "0.17.1", + "prettier-plugin-hermes-parser": "0.18.0", "react": "18.2.0", "react-test-renderer": "18.2.0", "rimraf": "^3.0.2", diff --git a/packages/@react-native/tester/overrides.json b/packages/@react-native/tester/overrides.json index 6fc2abd04eb..92b23162927 100644 --- a/packages/@react-native/tester/overrides.json +++ b/packages/@react-native/tester/overrides.json @@ -1,5 +1,5 @@ { - "baseVersion": "0.74.0-nightly-20231124-c464b215e", + "baseVersion": "0.74.0-nightly-20231201-c30f2b620", "overrides": [ { "type": "copy", diff --git a/packages/e2e-test-app-fabric/package.json b/packages/e2e-test-app-fabric/package.json index 4ef29bb42fa..eb1564367ba 100644 --- a/packages/e2e-test-app-fabric/package.json +++ b/packages/e2e-test-app-fabric/package.json @@ -19,7 +19,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/packages/e2e-test-app/package.json b/packages/e2e-test-app/package.json index 28cf65adc13..57b699bb650 100644 --- a/packages/e2e-test-app/package.json +++ b/packages/e2e-test-app/package.json @@ -19,7 +19,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749", "react-native-xaml": "^0.0.76" }, diff --git a/packages/integration-test-app/package.json b/packages/integration-test-app/package.json index 6af22ead138..f43010d839e 100644 --- a/packages/integration-test-app/package.json +++ b/packages/integration-test-app/package.json @@ -16,7 +16,7 @@ "@typescript-eslint/parser": "^5.21.0", "chai": "^4.2.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/packages/playground/package.json b/packages/playground/package.json index 4931e94638e..a8f4b46ffdb 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -15,7 +15,7 @@ "@typescript-eslint/eslint-plugin": "^5.21.0", "@typescript-eslint/parser": "^5.21.0", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/packages/sample-apps/package.json b/packages/sample-apps/package.json index 438a29f9c96..32f8ad3954b 100644 --- a/packages/sample-apps/package.json +++ b/packages/sample-apps/package.json @@ -15,7 +15,7 @@ "@typescript-eslint/eslint-plugin": "^5.30.5", "@typescript-eslint/parser": "^5.57.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-windows": "^0.0.0-canary.749" }, "devDependencies": { diff --git a/vnext/.flowconfig b/vnext/.flowconfig index f3e8f1e1d8f..02be1bcf144 100644 --- a/vnext/.flowconfig +++ b/vnext/.flowconfig @@ -140,4 +140,4 @@ untyped-import untyped-type-import [version] -^0.222.0 +^0.223.0 diff --git a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp index f77e34b99ed..0b206b865f0 100644 --- a/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp +++ b/vnext/Microsoft.ReactNative/Fabric/Composition/CompositionViewComponentView.cpp @@ -1190,7 +1190,8 @@ void CompositionBaseComponentView::updateBorderProps( const facebook::react::ViewProps &oldViewProps, const facebook::react::ViewProps &newViewProps) noexcept { if (oldViewProps.borderColors != newViewProps.borderColors || oldViewProps.borderRadii != newViewProps.borderRadii || - !(oldViewProps.yogaStyle.border(YGEdgeAll) == newViewProps.yogaStyle.border(YGEdgeAll)) || + !(oldViewProps.yogaStyle.border(facebook::yoga::Edge::All) == + newViewProps.yogaStyle.border(facebook::yoga::Edge::All)) || oldViewProps.borderStyles != newViewProps.borderStyles) { m_needsBorderUpdate = true; } diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp index 6606410290e..5a2d38d9dd3 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp @@ -209,4 +209,4 @@ folly::dynamic dynamicFromValue( } } // namespace jsi -} // namespace facebook \ No newline at end of file +} // namespace facebook diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h index 05836ff8d76..a96cc281b0d 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h @@ -23,4 +23,4 @@ folly::dynamic dynamicFromValue( std::function filterObjectKeys = nullptr); } // namespace jsi -} // namespace facebook \ No newline at end of file +} // namespace facebook diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp index b0d1a724e05..d858fb2ede0 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp @@ -1520,6 +1520,25 @@ TEST_P(JSITest, NativeStateSymbolOverrides) { 42); } +TEST_P(JSITest, UTF8ExceptionTest) { + // Test that a native exception containing UTF-8 characters is correctly + // passed through. + Function throwUtf8 = Function::createFromHostFunction( + rt, + PropNameID::forAscii(rt, "throwUtf8"), + 1, + [](Runtime& rt, const Value&, const Value* args, size_t) -> Value { + throw JSINativeException(args[0].asString(rt).utf8(rt)); + }); + std::string utf8 = "👍"; + try { + throwUtf8.call(rt, utf8); + FAIL(); + } catch (const JSError& e) { + EXPECT_NE(e.getMessage().find(utf8), std::string::npos); + } +} + INSTANTIATE_TEST_CASE_P( Runtimes, JSITest, diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp index 52915bb62cc..a272b29667f 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp @@ -35,6 +35,18 @@ YogaStylableProps::YogaStylableProps( } }; +/*static*/ const yoga::Style& YogaStylableProps::defaultStyle() { + static const auto defaultStyle = []() { + yoga::Style style; + style.setPositionType( + CoreFeatures::positionRelativeDefault ? yoga::PositionType::Relative + : yoga::PositionType::Static); + return style; + }(); + + return defaultStyle; +} + template static inline T const getFieldValue( const PropsParserContext& context, @@ -49,20 +61,19 @@ static inline T const getFieldValue( return defaultValue; } -#define REBUILD_FIELD_SWITCH_CASE2(field, fieldName) \ - case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ - yogaStyle.field() = getFieldValue(context, value, ygDefaults.field()); \ - return; \ +#define REBUILD_FIELD_SWITCH_CASE2(field, setter, fieldName) \ + case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ + yogaStyle.setter(getFieldValue(context, value, defaultStyle().field())); \ + return; \ } -// @lint-ignore CLANGTIDY cppcoreguidelines-macro-usage -#define REBUILD_FIELD_SWITCH_CASE_YSP(field) \ - REBUILD_FIELD_SWITCH_CASE2(field, #field) +#define REBUILD_FIELD_SWITCH_CASE_YSP(field, setter) \ + REBUILD_FIELD_SWITCH_CASE2(field, setter, #field) #define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, setter, index, fieldName) \ case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ yogaStyle.setter( \ - index, getFieldValue(context, value, ygDefaults.field(index))); \ + index, getFieldValue(context, value, defaultStyle().field(index))); \ return; \ } @@ -81,73 +92,72 @@ static inline T const getFieldValue( REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ field, setter, yoga::Gutter::All, gapStr); -#define REBUILD_FIELD_YG_EDGES(field, setter, prefix, suffix) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeLeft, prefix "Left" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeTop, prefix "Top" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeRight, prefix "Right" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeBottom, prefix "Bottom" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeStart, prefix "Start" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeEnd, prefix "End" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeHorizontal, prefix "Horizontal" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeVertical, prefix "Vertical" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, YGEdgeAll, prefix "" suffix); +#define REBUILD_FIELD_YG_EDGES(field, setter, prefix, suffix) \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Left, prefix "Left" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Top, prefix "Top" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Right, prefix "Right" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Bottom, prefix "Bottom" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Start, prefix "Start" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::End, prefix "End" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Horizontal, prefix "Horizontal" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::Vertical, prefix "Vertical" suffix); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + field, setter, yoga::Edge::All, prefix "" suffix); -#define REBUILD_FIELD_YG_EDGES_POSITION() \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeLeft, "left"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeTop, "top"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeRight, "right"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeBottom, "bottom"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeStart, "start"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeEnd, "end"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeHorizontal, "insetInline"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeVertical, "insetBlock"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, YGEdgeAll, "inset"); +#define REBUILD_FIELD_YG_EDGES_POSITION() \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Left, "left"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Top, "top"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Right, "right"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Bottom, "bottom"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Start, "start"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::End, "end"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Horizontal, "insetInline"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::Vertical, "insetBlock"); \ + REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ + position, setPosition, yoga::Edge::All, "inset"); void YogaStylableProps::setProp( const PropsParserContext& context, RawPropsPropNameHash hash, const char* propName, const RawValue& value) { - static const auto ygDefaults = yoga::Style{}; static const auto defaults = YogaStylableProps{}; Props::setProp(context, hash, propName, value); switch (hash) { - REBUILD_FIELD_SWITCH_CASE_YSP(direction); - REBUILD_FIELD_SWITCH_CASE_YSP(flexDirection); - REBUILD_FIELD_SWITCH_CASE_YSP(justifyContent); - REBUILD_FIELD_SWITCH_CASE_YSP(alignContent); - REBUILD_FIELD_SWITCH_CASE_YSP(alignItems); - REBUILD_FIELD_SWITCH_CASE_YSP(alignSelf); - REBUILD_FIELD_SWITCH_CASE_YSP(flexWrap); - REBUILD_FIELD_SWITCH_CASE_YSP(overflow); - REBUILD_FIELD_SWITCH_CASE_YSP(display); - REBUILD_FIELD_SWITCH_CASE_YSP(flex); - REBUILD_FIELD_SWITCH_CASE_YSP(flexGrow); - REBUILD_FIELD_SWITCH_CASE_YSP(flexShrink); - REBUILD_FIELD_SWITCH_CASE_YSP(flexBasis); - REBUILD_FIELD_SWITCH_CASE2(positionType, "position"); + REBUILD_FIELD_SWITCH_CASE_YSP(direction, setDirection); + REBUILD_FIELD_SWITCH_CASE_YSP(flexDirection, setFlexDirection); + REBUILD_FIELD_SWITCH_CASE_YSP(justifyContent, setJustifyContent); + REBUILD_FIELD_SWITCH_CASE_YSP(alignContent, setAlignContent); + REBUILD_FIELD_SWITCH_CASE_YSP(alignItems, setAlignItems); + REBUILD_FIELD_SWITCH_CASE_YSP(alignSelf, setAlignSelf); + REBUILD_FIELD_SWITCH_CASE_YSP(flexWrap, setFlexWrap); + REBUILD_FIELD_SWITCH_CASE_YSP(overflow, setOverflow); + REBUILD_FIELD_SWITCH_CASE_YSP(display, setDisplay); + REBUILD_FIELD_SWITCH_CASE_YSP(flex, setFlex); + REBUILD_FIELD_SWITCH_CASE_YSP(flexGrow, setFlexGrow); + REBUILD_FIELD_SWITCH_CASE_YSP(flexShrink, setFlexShrink); + REBUILD_FIELD_SWITCH_CASE_YSP(flexBasis, setFlexBasis); + REBUILD_FIELD_SWITCH_CASE2(positionType, setPositionType, "position"); REBUILD_FIELD_YG_GUTTER(gap, setGap, "rowGap", "columnGap", "gap"); - REBUILD_FIELD_SWITCH_CASE_YSP(aspectRatio); + REBUILD_FIELD_SWITCH_CASE_YSP(aspectRatio, setAspectRatio); REBUILD_FIELD_YG_DIMENSION(dimension, setDimension, "width", "height"); REBUILD_FIELD_YG_DIMENSION( minDimension, setMinDimension, "minWidth", "minHeight"); @@ -182,228 +192,225 @@ void YogaStylableProps::setProp( #if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const { - const auto defaultYogaStyle = yoga::Style{}; return { debugStringConvertibleItem( - "direction", yogaStyle.direction(), defaultYogaStyle.direction()), + "direction", yogaStyle.direction(), defaultStyle().direction()), debugStringConvertibleItem( "flexDirection", yogaStyle.flexDirection(), - defaultYogaStyle.flexDirection()), + defaultStyle().flexDirection()), debugStringConvertibleItem( "justifyContent", yogaStyle.justifyContent(), - defaultYogaStyle.justifyContent()), + defaultStyle().justifyContent()), debugStringConvertibleItem( "alignContent", yogaStyle.alignContent(), - defaultYogaStyle.alignContent()), + defaultStyle().alignContent()), debugStringConvertibleItem( - "alignItems", yogaStyle.alignItems(), defaultYogaStyle.alignItems()), + "alignItems", yogaStyle.alignItems(), defaultStyle().alignItems()), debugStringConvertibleItem( - "alignSelf", yogaStyle.alignSelf(), defaultYogaStyle.alignSelf()), + "alignSelf", yogaStyle.alignSelf(), defaultStyle().alignSelf()), debugStringConvertibleItem( "positionType", yogaStyle.positionType(), - defaultYogaStyle.positionType()), + defaultStyle().positionType()), debugStringConvertibleItem( - "flexWrap", yogaStyle.flexWrap(), defaultYogaStyle.flexWrap()), + "flexWrap", yogaStyle.flexWrap(), defaultStyle().flexWrap()), debugStringConvertibleItem( - "overflow", yogaStyle.overflow(), defaultYogaStyle.overflow()), + "overflow", yogaStyle.overflow(), defaultStyle().overflow()), debugStringConvertibleItem( - "display", yogaStyle.display(), defaultYogaStyle.display()), + "display", yogaStyle.display(), defaultStyle().display()), debugStringConvertibleItem( - "flex", yogaStyle.flex(), defaultYogaStyle.flex()), + "flex", yogaStyle.flex(), defaultStyle().flex()), debugStringConvertibleItem( - "flexGrow", yogaStyle.flexGrow(), defaultYogaStyle.flexGrow()), + "flexGrow", yogaStyle.flexGrow(), defaultStyle().flexGrow()), debugStringConvertibleItem( "rowGap", yogaStyle.gap(yoga::Gutter::Row), - defaultYogaStyle.gap(yoga::Gutter::Row)), + defaultStyle().gap(yoga::Gutter::Row)), debugStringConvertibleItem( "columnGap", yogaStyle.gap(yoga::Gutter::Column), - defaultYogaStyle.gap(yoga::Gutter::Column)), + defaultStyle().gap(yoga::Gutter::Column)), debugStringConvertibleItem( "gap", yogaStyle.gap(yoga::Gutter::All), - defaultYogaStyle.gap(yoga::Gutter::All)), + defaultStyle().gap(yoga::Gutter::All)), debugStringConvertibleItem( - "flexShrink", yogaStyle.flexShrink(), defaultYogaStyle.flexShrink()), + "flexShrink", yogaStyle.flexShrink(), defaultStyle().flexShrink()), debugStringConvertibleItem( - "flexBasis", yogaStyle.flexBasis(), defaultYogaStyle.flexBasis()), + "flexBasis", yogaStyle.flexBasis(), defaultStyle().flexBasis()), debugStringConvertibleItem( "marginLeft", - yogaStyle.margin(YGEdgeLeft), - defaultYogaStyle.margin(YGEdgeLeft)), + yogaStyle.margin(yoga::Edge::Left), + defaultStyle().margin(yoga::Edge::Left)), debugStringConvertibleItem( "marginTop", - yogaStyle.margin(YGEdgeTop), - defaultYogaStyle.margin(YGEdgeTop)), + yogaStyle.margin(yoga::Edge::Top), + defaultStyle().margin(yoga::Edge::Top)), debugStringConvertibleItem( "marginRight", - yogaStyle.margin(YGEdgeRight), - defaultYogaStyle.margin(YGEdgeRight)), + yogaStyle.margin(yoga::Edge::Right), + defaultStyle().margin(yoga::Edge::Right)), debugStringConvertibleItem( "marginBottom", - yogaStyle.margin(YGEdgeBottom), - defaultYogaStyle.margin(YGEdgeBottom)), + yogaStyle.margin(yoga::Edge::Bottom), + defaultStyle().margin(yoga::Edge::Bottom)), debugStringConvertibleItem( "marginStart", - yogaStyle.margin(YGEdgeStart), - defaultYogaStyle.margin(YGEdgeStart)), + yogaStyle.margin(yoga::Edge::Start), + defaultStyle().margin(yoga::Edge::Start)), debugStringConvertibleItem( "marginEnd", - yogaStyle.margin(YGEdgeEnd), - defaultYogaStyle.margin(YGEdgeEnd)), + yogaStyle.margin(yoga::Edge::End), + defaultStyle().margin(yoga::Edge::End)), debugStringConvertibleItem( "marginHorizontal", - yogaStyle.margin(YGEdgeHorizontal), - defaultYogaStyle.margin(YGEdgeHorizontal)), + yogaStyle.margin(yoga::Edge::Horizontal), + defaultStyle().margin(yoga::Edge::Horizontal)), debugStringConvertibleItem( "marginVertical", - yogaStyle.margin(YGEdgeVertical), - defaultYogaStyle.margin(YGEdgeVertical)), + yogaStyle.margin(yoga::Edge::Vertical), + defaultStyle().margin(yoga::Edge::Vertical)), debugStringConvertibleItem( "margin", - yogaStyle.margin(YGEdgeAll), - defaultYogaStyle.margin(YGEdgeAll)), + yogaStyle.margin(yoga::Edge::All), + defaultStyle().margin(yoga::Edge::All)), debugStringConvertibleItem( "left", - yogaStyle.position(YGEdgeLeft), - defaultYogaStyle.position(YGEdgeLeft)), + yogaStyle.position(yoga::Edge::Left), + defaultStyle().position(yoga::Edge::Left)), debugStringConvertibleItem( "top", - yogaStyle.position(YGEdgeTop), - defaultYogaStyle.position(YGEdgeTop)), + yogaStyle.position(yoga::Edge::Top), + defaultStyle().position(yoga::Edge::Top)), debugStringConvertibleItem( "right", - yogaStyle.position(YGEdgeRight), - defaultYogaStyle.position(YGEdgeRight)), + yogaStyle.position(yoga::Edge::Right), + defaultStyle().position(yoga::Edge::Right)), debugStringConvertibleItem( "bottom", - yogaStyle.position(YGEdgeBottom), - defaultYogaStyle.position(YGEdgeBottom)), + yogaStyle.position(yoga::Edge::Bottom), + defaultStyle().position(yoga::Edge::Bottom)), debugStringConvertibleItem( "start", - yogaStyle.position(YGEdgeStart), - defaultYogaStyle.position(YGEdgeStart)), + yogaStyle.position(yoga::Edge::Start), + defaultStyle().position(yoga::Edge::Start)), debugStringConvertibleItem( "end", - yogaStyle.position(YGEdgeEnd), - defaultYogaStyle.position(YGEdgeEnd)), + yogaStyle.position(yoga::Edge::End), + defaultStyle().position(yoga::Edge::End)), debugStringConvertibleItem( "inseInline", - yogaStyle.position(YGEdgeHorizontal), - defaultYogaStyle.position(YGEdgeHorizontal)), + yogaStyle.position(yoga::Edge::Horizontal), + defaultStyle().position(yoga::Edge::Horizontal)), debugStringConvertibleItem( "insetBlock", - yogaStyle.position(YGEdgeVertical), - defaultYogaStyle.position(YGEdgeVertical)), + yogaStyle.position(yoga::Edge::Vertical), + defaultStyle().position(yoga::Edge::Vertical)), debugStringConvertibleItem( "inset", - yogaStyle.position(YGEdgeAll), - defaultYogaStyle.position(YGEdgeAll)), + yogaStyle.position(yoga::Edge::All), + defaultStyle().position(yoga::Edge::All)), debugStringConvertibleItem( "paddingLeft", - yogaStyle.padding(YGEdgeLeft), - defaultYogaStyle.padding(YGEdgeLeft)), + yogaStyle.padding(yoga::Edge::Left), + defaultStyle().padding(yoga::Edge::Left)), debugStringConvertibleItem( "paddingTop", - yogaStyle.padding(YGEdgeTop), - defaultYogaStyle.padding(YGEdgeTop)), + yogaStyle.padding(yoga::Edge::Top), + defaultStyle().padding(yoga::Edge::Top)), debugStringConvertibleItem( "paddingRight", - yogaStyle.padding(YGEdgeRight), - defaultYogaStyle.padding(YGEdgeRight)), + yogaStyle.padding(yoga::Edge::Right), + defaultStyle().padding(yoga::Edge::Right)), debugStringConvertibleItem( "paddingBottom", - yogaStyle.padding(YGEdgeBottom), - defaultYogaStyle.padding(YGEdgeBottom)), + yogaStyle.padding(yoga::Edge::Bottom), + defaultStyle().padding(yoga::Edge::Bottom)), debugStringConvertibleItem( "paddingStart", - yogaStyle.padding(YGEdgeStart), - defaultYogaStyle.padding(YGEdgeStart)), + yogaStyle.padding(yoga::Edge::Start), + defaultStyle().padding(yoga::Edge::Start)), debugStringConvertibleItem( "paddingEnd", - yogaStyle.padding(YGEdgeEnd), - defaultYogaStyle.padding(YGEdgeEnd)), + yogaStyle.padding(yoga::Edge::End), + defaultStyle().padding(yoga::Edge::End)), debugStringConvertibleItem( "paddingHorizontal", - yogaStyle.padding(YGEdgeHorizontal), - defaultYogaStyle.padding(YGEdgeHorizontal)), + yogaStyle.padding(yoga::Edge::Horizontal), + defaultStyle().padding(yoga::Edge::Horizontal)), debugStringConvertibleItem( "paddingVertical", - yogaStyle.padding(YGEdgeVertical), - defaultYogaStyle.padding(YGEdgeVertical)), + yogaStyle.padding(yoga::Edge::Vertical), + defaultStyle().padding(yoga::Edge::Vertical)), debugStringConvertibleItem( "padding", - yogaStyle.padding(YGEdgeAll), - defaultYogaStyle.padding(YGEdgeAll)), + yogaStyle.padding(yoga::Edge::All), + defaultStyle().padding(yoga::Edge::All)), debugStringConvertibleItem( "borderLeftWidth", - yogaStyle.border(YGEdgeLeft), - defaultYogaStyle.border(YGEdgeLeft)), + yogaStyle.border(yoga::Edge::Left), + defaultStyle().border(yoga::Edge::Left)), debugStringConvertibleItem( "borderTopWidth", - yogaStyle.border(YGEdgeTop), - defaultYogaStyle.border(YGEdgeTop)), + yogaStyle.border(yoga::Edge::Top), + defaultStyle().border(yoga::Edge::Top)), debugStringConvertibleItem( "borderRightWidth", - yogaStyle.border(YGEdgeRight), - defaultYogaStyle.border(YGEdgeRight)), + yogaStyle.border(yoga::Edge::Right), + defaultStyle().border(yoga::Edge::Right)), debugStringConvertibleItem( "borderBottomWidth", - yogaStyle.border(YGEdgeBottom), - defaultYogaStyle.border(YGEdgeBottom)), + yogaStyle.border(yoga::Edge::Bottom), + defaultStyle().border(yoga::Edge::Bottom)), debugStringConvertibleItem( "borderStartWidth", - yogaStyle.border(YGEdgeStart), - defaultYogaStyle.border(YGEdgeStart)), + yogaStyle.border(yoga::Edge::Start), + defaultStyle().border(yoga::Edge::Start)), debugStringConvertibleItem( "borderEndWidth", - yogaStyle.border(YGEdgeEnd), - defaultYogaStyle.border(YGEdgeEnd)), + yogaStyle.border(yoga::Edge::End), + defaultStyle().border(yoga::Edge::End)), debugStringConvertibleItem( "borderHorizontalWidth", - yogaStyle.border(YGEdgeHorizontal), - defaultYogaStyle.border(YGEdgeHorizontal)), + yogaStyle.border(yoga::Edge::Horizontal), + defaultStyle().border(yoga::Edge::Horizontal)), debugStringConvertibleItem( "borderVerticalWidth", - yogaStyle.border(YGEdgeVertical), - defaultYogaStyle.border(YGEdgeVertical)), + yogaStyle.border(yoga::Edge::Vertical), + defaultStyle().border(yoga::Edge::Vertical)), debugStringConvertibleItem( "bordeWidth", - yogaStyle.border(YGEdgeAll), - defaultYogaStyle.border(YGEdgeAll)), + yogaStyle.border(yoga::Edge::All), + defaultStyle().border(yoga::Edge::All)), debugStringConvertibleItem( "width", yogaStyle.dimension(yoga::Dimension::Width), - defaultYogaStyle.dimension(yoga::Dimension::Width)), + defaultStyle().dimension(yoga::Dimension::Width)), debugStringConvertibleItem( "height", yogaStyle.dimension(yoga::Dimension::Height), - defaultYogaStyle.dimension(yoga::Dimension::Height)), + defaultStyle().dimension(yoga::Dimension::Height)), debugStringConvertibleItem( "minWidth", yogaStyle.minDimension(yoga::Dimension::Width), - defaultYogaStyle.minDimension(yoga::Dimension::Width)), + defaultStyle().minDimension(yoga::Dimension::Width)), debugStringConvertibleItem( "minHeight", yogaStyle.minDimension(yoga::Dimension::Height), - defaultYogaStyle.minDimension(yoga::Dimension::Height)), + defaultStyle().minDimension(yoga::Dimension::Height)), debugStringConvertibleItem( "maxWidth", yogaStyle.maxDimension(yoga::Dimension::Width), - defaultYogaStyle.maxDimension(yoga::Dimension::Width)), + defaultStyle().maxDimension(yoga::Dimension::Width)), debugStringConvertibleItem( "maxHeight", yogaStyle.maxDimension(yoga::Dimension::Height), - defaultYogaStyle.maxDimension(yoga::Dimension::Height)), + defaultStyle().maxDimension(yoga::Dimension::Height)), debugStringConvertibleItem( - "aspectRatio", - yogaStyle.aspectRatio(), - defaultYogaStyle.aspectRatio()), + "aspectRatio", yogaStyle.aspectRatio(), defaultStyle().aspectRatio()), }; } #endif @@ -417,98 +424,98 @@ void YogaStylableProps::convertRawPropAliases( rawProps, "insetBlockEnd", sourceProps.insetBlockEnd, - CompactValue::ofUndefined()); + yoga::value::undefined()); insetBlockStart = convertRawProp( context, rawProps, "insetBlockStart", sourceProps.insetBlockStart, - CompactValue::ofUndefined()); + yoga::value::undefined()); insetInlineEnd = convertRawProp( context, rawProps, "insetInlineEnd", sourceProps.insetInlineEnd, - CompactValue::ofUndefined()); + yoga::value::undefined()); insetInlineStart = convertRawProp( context, rawProps, "insetInlineStart", sourceProps.insetInlineStart, - CompactValue::ofUndefined()); + yoga::value::undefined()); marginInline = convertRawProp( context, rawProps, "marginInline", sourceProps.marginInline, - CompactValue::ofUndefined()); + yoga::value::undefined()); marginInlineStart = convertRawProp( context, rawProps, "marginInlineStart", sourceProps.marginInlineStart, - CompactValue::ofUndefined()); + yoga::value::undefined()); marginInlineEnd = convertRawProp( context, rawProps, "marginInlineEnd", sourceProps.marginInlineEnd, - CompactValue::ofUndefined()); + yoga::value::undefined()); marginBlock = convertRawProp( context, rawProps, "marginBlock", sourceProps.marginBlock, - CompactValue::ofUndefined()); + yoga::value::undefined()); marginBlockStart = convertRawProp( context, rawProps, "marginBlockStart", sourceProps.marginBlockStart, - CompactValue::ofUndefined()); + yoga::value::undefined()); marginBlockEnd = convertRawProp( context, rawProps, "marginBlockEnd", sourceProps.marginBlockEnd, - CompactValue::ofUndefined()); + yoga::value::undefined()); paddingInline = convertRawProp( context, rawProps, "paddingInline", sourceProps.paddingInline, - CompactValue::ofUndefined()); + yoga::value::undefined()); paddingInlineStart = convertRawProp( context, rawProps, "paddingInlineStart", sourceProps.paddingInlineStart, - CompactValue::ofUndefined()); + yoga::value::undefined()); paddingInlineEnd = convertRawProp( context, rawProps, "paddingInlineEnd", sourceProps.paddingInlineEnd, - CompactValue::ofUndefined()); + yoga::value::undefined()); paddingBlock = convertRawProp( context, rawProps, "paddingBlock", sourceProps.paddingBlock, - CompactValue::ofUndefined()); + yoga::value::undefined()); paddingBlockStart = convertRawProp( context, rawProps, "paddingBlockStart", sourceProps.paddingBlockStart, - CompactValue::ofUndefined()); + yoga::value::undefined()); paddingBlockEnd = convertRawProp( context, rawProps, "paddingBlockEnd", sourceProps.paddingBlockEnd, - CompactValue::ofUndefined()); + yoga::value::undefined()); } } // namespace facebook::react \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h index 997448380b4..6ba3b430d8c 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h @@ -9,32 +9,25 @@ #include -#include +#include #include #include +#include #include #include namespace facebook::yoga { struct LayoutResults { + + // [Windows C++20 fix + LayoutResults() : direction_(Direction::Inherit), hadOverflow_(false) {} + // Windows] + // This value was chosen based on empirical data: // 98% of analyzed layouts require less than 8 entries. static constexpr int32_t MaxCachedMeasurements = 8; - std::array position = {}; - std::array margin = {}; - std::array border = {}; - std::array padding = {}; - - private: - Direction direction_ = Direction::Inherit; - bool hadOverflow_ = false; - - std::array dimensions_ = {{YGUndefined, YGUndefined}}; - std::array measuredDimensions_ = {{YGUndefined, YGUndefined}}; - - public: uint32_t computedFlexBasisGeneration = 0; FloatOptional computedFlexBasis = {}; @@ -80,10 +73,68 @@ struct LayoutResults { measuredDimensions_[yoga::to_underlying(axis)] = dimension; } + float position(Edge cardinalEdge) const { + assertCardinalEdge(cardinalEdge); + return position_[yoga::to_underlying(cardinalEdge)]; + } + + void setPosition(Edge cardinalEdge, float dimension) { + assertCardinalEdge(cardinalEdge); + position_[yoga::to_underlying(cardinalEdge)] = dimension; + } + + float margin(Edge cardinalEdge) const { + assertCardinalEdge(cardinalEdge); + return margin_[yoga::to_underlying(cardinalEdge)]; + } + + void setMargin(Edge cardinalEdge, float dimension) { + assertCardinalEdge(cardinalEdge); + margin_[yoga::to_underlying(cardinalEdge)] = dimension; + } + + float border(Edge cardinalEdge) const { + assertCardinalEdge(cardinalEdge); + return border_[yoga::to_underlying(cardinalEdge)]; + } + + void setBorder(Edge cardinalEdge, float dimension) { + assertCardinalEdge(cardinalEdge); + border_[yoga::to_underlying(cardinalEdge)] = dimension; + } + + float padding(Edge cardinalEdge) const { + assertCardinalEdge(cardinalEdge); + return padding_[yoga::to_underlying(cardinalEdge)]; + } + + void setPadding(Edge cardinalEdge, float dimension) { + assertCardinalEdge(cardinalEdge); + padding_[yoga::to_underlying(cardinalEdge)] = dimension; + } + bool operator==(LayoutResults layout) const; bool operator!=(LayoutResults layout) const { return !(*this == layout); } + + private: + static inline void assertCardinalEdge(Edge edge) { + assertFatal( + static_cast(edge) <= 3, "Edge must be top/left/bottom/right"); + } + + // [Windows c++20 fix + Direction direction_ : bitCount(); + bool hadOverflow_ : 1; + // Windows] + + std::array dimensions_ = {{YGUndefined, YGUndefined}}; + std::array measuredDimensions_ = {{YGUndefined, YGUndefined}}; + std::array position_ = {}; + std::array margin_ = {}; + std::array border_ = {}; + std::array padding_ = {}; }; -} // namespace facebook::yoga +} // namespace facebook::yoga \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h index fec0b9bd3ea..f87cd63d4a1 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h @@ -16,11 +16,11 @@ #include #include #include +#include #include #include #include #include -#include #include // Tag struct used to form the opaque YGNodeRef for the public C API @@ -53,23 +53,23 @@ class YG_EXPORT Node : public ::YGNode { Direction direction, const float axisSize) const; - YGEdge getInlineStartEdgeUsingErrata( + Edge getInlineStartEdgeUsingErrata( FlexDirection flexDirection, Direction direction) const; - YGEdge getInlineEndEdgeUsingErrata( + Edge getInlineEndEdgeUsingErrata( FlexDirection flexDirection, Direction direction) const; void useWebDefaults() { - style_.flexDirection() = FlexDirection::Row; - style_.alignContent() = Align::Stretch; + style_.setFlexDirection(FlexDirection::Row); + style_.setAlignContent(Align::Stretch); } template - CompactValue computeEdgeValueForColumn(YGEdge edge) const; + Style::Length computeEdgeValueForColumn(Edge edge) const; template - CompactValue computeEdgeValueForRow(YGEdge rowEdge, YGEdge edge) const; + Style::Length computeEdgeValueForRow(Edge rowEdge, Edge edge) const; // DANGER DANGER DANGER! // If the node assigned to has children, we'd either have to deallocate @@ -327,12 +327,12 @@ class YG_EXPORT Node : public ::YGNode { uint32_t computedFlexBasisGeneration); void setLayoutMeasuredDimension(float measuredDimension, Dimension dimension); void setLayoutHadOverflow(bool hadOverflow); - void setLayoutDimension(float dimensionValue, Dimension dimension); + void setLayoutDimension(float LengthValue, Dimension dimension); void setLayoutDirection(Direction direction); - void setLayoutMargin(float margin, YGEdge edge); - void setLayoutBorder(float border, YGEdge edge); - void setLayoutPadding(float padding, YGEdge edge); - void setLayoutPosition(float position, YGEdge edge); + void setLayoutMargin(float margin, Edge edge); + void setLayoutBorder(float border, Edge edge); + void setLayoutPadding(float padding, Edge edge); + void setLayoutPosition(float position, Edge edge); void setPosition( const Direction direction, const float mainSize, diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h new file mode 100644 index 00000000000..8b9e331d720 --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace facebook::yoga { + +class YG_EXPORT Style { + public: + /** + * Style::Length represents a CSS Value which may be one of: + * 1. Undefined + * 2. A keyword (e.g. auto) + * 3. A CSS value: + * a. value (e.g. 10px) + * b. value of a reference + * 4. (soon) A math function which returns a value + * + * References: + * 1. https://www.w3.org/TR/css-values-4/#lengths + * 2. https://www.w3.org/TR/css-values-4/#percentage-value + * 3. https://www.w3.org/TR/css-values-4/#mixed-percentages + * 4. https://www.w3.org/TR/css-values-4/#math + */ + using Length = CompactValue; + + static constexpr float DefaultFlexGrow = 0.0f; + static constexpr float DefaultFlexShrink = 0.0f; + static constexpr float WebDefaultFlexShrink = 1.0f; + + // [Windows C++20 fix + Style() : direction_(Direction::Inherit), flexDirection_(FlexDirection::Column), justifyContent_(Justify::FlexStart), + alignContent_(Align::FlexStart), alignItems_(Align::Stretch), alignSelf_(Align::Auto), positionType_(PositionType::Relative), flexWrap_(Wrap::NoWrap), overflow_(Overflow::Visible), + display_(Display::Flex) {} + // Windows] + + + 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 flex_; + } + void setFlex(FloatOptional value) { + flex_ = value; + } + + FloatOptional flexGrow() const { + return flexGrow_; + } + void setFlexGrow(FloatOptional value) { + flexGrow_ = value; + } + + FloatOptional flexShrink() const { + return flexShrink_; + } + void setFlexShrink(FloatOptional value) { + flexShrink_ = value; + } + + Style::Length flexBasis() const { + return flexBasis_; + } + void setFlexBasis(Style::Length value) { + flexBasis_ = value; + } + + Style::Length margin(Edge edge) const { + return margin_[yoga::to_underlying(edge)]; + } + void setMargin(Edge edge, Style::Length value) { + margin_[yoga::to_underlying(edge)] = value; + } + + Style::Length position(Edge edge) const { + return position_[yoga::to_underlying(edge)]; + } + void setPosition(Edge edge, Style::Length value) { + position_[yoga::to_underlying(edge)] = value; + } + + Style::Length padding(Edge edge) const { + return padding_[yoga::to_underlying(edge)]; + } + void setPadding(Edge edge, Style::Length value) { + padding_[yoga::to_underlying(edge)] = value; + } + + Style::Length border(Edge edge) const { + return border_[yoga::to_underlying(edge)]; + } + void setBorder(Edge edge, Style::Length value) { + border_[yoga::to_underlying(edge)] = value; + } + + Style::Length gap(Gutter gutter) const { + return gap_[yoga::to_underlying(gutter)]; + } + void setGap(Gutter gutter, Style::Length value) { + gap_[yoga::to_underlying(gutter)] = value; + } + + Style::Length dimension(Dimension axis) const { + return dimensions_[yoga::to_underlying(axis)]; + } + void setDimension(Dimension axis, Style::Length value) { + dimensions_[yoga::to_underlying(axis)] = value; + } + + Style::Length minDimension(Dimension axis) const { + return minDimensions_[yoga::to_underlying(axis)]; + } + void setMinDimension(Dimension axis, Style::Length value) { + minDimensions_[yoga::to_underlying(axis)] = value; + } + + Style::Length maxDimension(Dimension axis) const { + return maxDimensions_[yoga::to_underlying(axis)]; + } + void setMaxDimension(Dimension axis, Style::Length value) { + maxDimensions_[yoga::to_underlying(axis)] = value; + } + + FloatOptional aspectRatio() const { + return aspectRatio_; + } + void setAspectRatio(FloatOptional value) { + aspectRatio_ = value; + } + + Length resolveColumnGap() const { + if (gap_[yoga::to_underlying(Gutter::Column)].isDefined()) { + return gap_[yoga::to_underlying(Gutter::Column)]; + } else { + return gap_[yoga::to_underlying(Gutter::All)]; + } + } + + Style::Length resolveRowGap() const { + if (gap_[yoga::to_underlying(Gutter::Row)].isDefined()) { + return gap_[yoga::to_underlying(Gutter::Row)]; + } else { + return gap_[yoga::to_underlying(Gutter::All)]; + } + } + + 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_ && + inexactEquals(flex_, other.flex_) && + inexactEquals(flexGrow_, other.flexGrow_) && + inexactEquals(flexShrink_, other.flexShrink_) && + inexactEquals(flexBasis_, other.flexBasis_) && + inexactEquals(margin_, other.margin_) && + inexactEquals(position_, other.position_) && + inexactEquals(padding_, other.padding_) && + inexactEquals(border_, other.border_) && + inexactEquals(gap_, other.gap_) && + inexactEquals(dimensions_, other.dimensions_) && + inexactEquals(minDimensions_, other.minDimensions_) && + inexactEquals(maxDimensions_, other.maxDimensions_) && + inexactEquals(aspectRatio_, other.aspectRatio_); + } + + bool operator!=(const Style& other) const { + return !(*this == other); + } + + private: + using Dimensions = std::array()>; + using Edges = std::array()>; + using Gutters = std::array()>; + + // [Window C++20 fix + Direction direction_ : bitCount(); + FlexDirection flexDirection_ : bitCount(); + Justify justifyContent_ : bitCount(); + Align alignContent_ : bitCount(); + Align alignItems_ : bitCount(); + Align alignSelf_ : bitCount(); + PositionType positionType_: bitCount(); + Wrap flexWrap_ : bitCount(); + Overflow overflow_ : bitCount(); + Display display_ : bitCount(); + // Windows] + + FloatOptional flex_{}; + FloatOptional flexGrow_{}; + FloatOptional flexShrink_{}; + Style::Length flexBasis_{value::ofAuto()}; + Edges margin_{}; + Edges position_{}; + Edges padding_{}; + Edges border_{}; + Gutters gap_{}; + Dimensions dimensions_{value::ofAuto(), value::ofAuto()}; + Dimensions minDimensions_{}; + Dimensions maxDimensions_{}; + FloatOptional aspectRatio_{}; +}; + +} // namespace facebook::yoga \ No newline at end of file diff --git a/vnext/ReactCommon/Yoga.cpp b/vnext/ReactCommon/Yoga.cpp index 542f6fbbae3..7d6bd8e2222 100644 --- a/vnext/ReactCommon/Yoga.cpp +++ b/vnext/ReactCommon/Yoga.cpp @@ -15,6 +15,7 @@ #include #include #include +#include using namespace facebook; using namespace facebook::yoga; @@ -369,47 +370,28 @@ float YGNodeStyleGetFlexShrink(const YGNodeConstRef nodeRef) { namespace { -template -void updateStyle( - yoga::Node* node, - T value, - NeedsUpdate &&needsUpdate, - Update &&update) { - if (needsUpdate(node->getStyle(), value)) { - update(node->getStyle(), value); - node->markDirtyAndPropagate(); +template +void updateStyle(YGNodeRef node, ValueT value) { + auto& style = resolveRef(node)->getStyle(); + if ((style.*GetterT)() != value) { + (style.*SetterT)(value); + resolveRef(node)->markDirtyAndPropagate(); } } -template -void updateStyle(YGNodeRef node, Ref (Style::*prop)(), T value) { - updateStyle( - resolveRef(node), - value, - [prop](Style& s, T x) { return (s.*prop)() != x; }, - [prop](Style& s, T x) { (s.*prop)() = x; }); -} - -template -void updateIndexedStyleProp(YGNodeRef node, IdxT idx, CompactValue value) { - updateStyle( - resolveRef(node), - value, - [idx](Style& s, CompactValue x) { return (s.*GetterT)(idx) != x; }, - [idx](Style& s, CompactValue x) { (s.*SetterT)(idx, x); }); +template +void updateStyle(YGNodeRef node, IdxT idx, ValueT value) { + auto& style = resolveRef(node)->getStyle(); + if ((style.*GetterT)(idx) != value) { + (style.*SetterT)(idx, value); + resolveRef(node)->markDirtyAndPropagate(); + } } } // namespace -// MSVC has trouble inferring the return type of pointer to member functions -// with const and non-const overloads, instead of preferring the non-const -// overload like clang and GCC. For the purposes of updateStyle(), we can help -// MSVC by specifying that return type explicitly. In combination with -// decltype, MSVC will prefer the non-const version. -#define MSVC_HINT(PROP) decltype(Style{}.PROP()) - void YGNodeStyleSetDirection(const YGNodeRef node, const YGDirection value) { - updateStyle(node, &Style::direction, scopedEnum(value)); + updateStyle<&Style::direction, &Style::setDirection>(node, scopedEnum(value)); } YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().direction()); @@ -418,8 +400,8 @@ YGDirection YGNodeStyleGetDirection(const YGNodeConstRef node) { void YGNodeStyleSetFlexDirection( const YGNodeRef node, const YGFlexDirection flexDirection) { - updateStyle( - node, &Style::flexDirection, scopedEnum(flexDirection)); + updateStyle<&Style::flexDirection, &Style::setFlexDirection>( + node, scopedEnum(flexDirection)); } YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().flexDirection()); @@ -428,8 +410,8 @@ YGFlexDirection YGNodeStyleGetFlexDirection(const YGNodeConstRef node) { void YGNodeStyleSetJustifyContent( const YGNodeRef node, const YGJustify justifyContent) { - updateStyle( - node, &Style::justifyContent, scopedEnum(justifyContent)); + updateStyle<&Style::justifyContent, &Style::setJustifyContent>( + node, scopedEnum(justifyContent)); } YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().justifyContent()); @@ -438,24 +420,24 @@ YGJustify YGNodeStyleGetJustifyContent(const YGNodeConstRef node) { void YGNodeStyleSetAlignContent( const YGNodeRef node, const YGAlign alignContent) { - updateStyle( - node, &Style::alignContent, scopedEnum(alignContent)); + updateStyle<&Style::alignContent, &Style::setAlignContent>( + node, scopedEnum(alignContent)); } YGAlign YGNodeStyleGetAlignContent(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().alignContent()); } void YGNodeStyleSetAlignItems(const YGNodeRef node, const YGAlign alignItems) { - updateStyle( - node, &Style::alignItems, scopedEnum(alignItems)); + updateStyle<&Style::alignItems, &Style::setAlignItems>( + node, scopedEnum(alignItems)); } YGAlign YGNodeStyleGetAlignItems(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().alignItems()); } void YGNodeStyleSetAlignSelf(const YGNodeRef node, const YGAlign alignSelf) { - updateStyle( - node, &Style::alignSelf, scopedEnum(alignSelf)); + updateStyle<&Style::alignSelf, &Style::setAlignSelf>( + node, scopedEnum(alignSelf)); } YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().alignSelf()); @@ -464,38 +446,38 @@ YGAlign YGNodeStyleGetAlignSelf(const YGNodeConstRef node) { void YGNodeStyleSetPositionType( const YGNodeRef node, const YGPositionType positionType) { - updateStyle( - node, &Style::positionType, scopedEnum(positionType)); + updateStyle<&Style::positionType, &Style::setPositionType>( + node, scopedEnum(positionType)); } YGPositionType YGNodeStyleGetPositionType(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().positionType()); } void YGNodeStyleSetFlexWrap(const YGNodeRef node, const YGWrap flexWrap) { - updateStyle( - node, &Style::flexWrap, scopedEnum(flexWrap)); + updateStyle<&Style::flexWrap, &Style::setFlexWrap>( + node, scopedEnum(flexWrap)); } YGWrap YGNodeStyleGetFlexWrap(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().flexWrap()); } void YGNodeStyleSetOverflow(const YGNodeRef node, const YGOverflow overflow) { - updateStyle( - node, &Style::overflow, scopedEnum(overflow)); + updateStyle<&Style::overflow, &Style::setOverflow>( + node, scopedEnum(overflow)); } YGOverflow YGNodeStyleGetOverflow(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().overflow()); } void YGNodeStyleSetDisplay(const YGNodeRef node, const YGDisplay display) { - updateStyle(node, &Style::display, scopedEnum(display)); + updateStyle<&Style::display, &Style::setDisplay>(node, scopedEnum(display)); } YGDisplay YGNodeStyleGetDisplay(const YGNodeConstRef node) { return unscopedEnum(resolveRef(node)->getStyle().display()); } void YGNodeStyleSetFlex(const YGNodeRef node, const float flex) { - updateStyle(node, &Style::flex, FloatOptional{flex}); + updateStyle<&Style::flex, &Style::setFlex>(node, FloatOptional{flex}); } float YGNodeStyleGetFlex(const YGNodeConstRef nodeRef) { @@ -506,13 +488,13 @@ float YGNodeStyleGetFlex(const YGNodeConstRef nodeRef) { } void YGNodeStyleSetFlexGrow(const YGNodeRef node, const float flexGrow) { - updateStyle( - node, &Style::flexGrow, FloatOptional{flexGrow}); + updateStyle<&Style::flexGrow, &Style::setFlexGrow>( + node, FloatOptional{flexGrow}); } void YGNodeStyleSetFlexShrink(const YGNodeRef node, const float flexShrink) { - updateStyle( - node, &Style::flexShrink, FloatOptional{flexShrink}); + updateStyle<&Style::flexShrink, &Style::setFlexShrink>( + node, FloatOptional{flexShrink}); } YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { @@ -524,75 +506,70 @@ YGValue YGNodeStyleGetFlexBasis(const YGNodeConstRef node) { } void YGNodeStyleSetFlexBasis(const YGNodeRef node, const float flexBasis) { - auto value = CompactValue::ofMaybe(flexBasis); - updateStyle(node, &Style::flexBasis, value); + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, value::points(flexBasis)); } void YGNodeStyleSetFlexBasisPercent( const YGNodeRef node, const float flexBasisPercent) { - auto value = CompactValue::ofMaybe(flexBasisPercent); - updateStyle(node, &Style::flexBasis, value); + updateStyle<&Style::flexBasis, &Style::setFlexBasis>( + node, value::percent(flexBasisPercent)); } void YGNodeStyleSetFlexBasisAuto(const YGNodeRef node) { - updateStyle( - node, &Style::flexBasis, CompactValue::ofAuto()); + updateStyle<&Style::flexBasis, &Style::setFlexBasis>(node, value::ofAuto()); } void YGNodeStyleSetPosition(YGNodeRef node, YGEdge edge, float points) { - auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp<&Style::position, &Style::setPosition>( - node, edge, value); + updateStyle<&Style::position, &Style::setPosition>( + node, scopedEnum(edge), value::points(points)); } void YGNodeStyleSetPositionPercent(YGNodeRef node, YGEdge edge, float percent) { - auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp<&Style::position, &Style::setPosition>( - node, edge, value); + updateStyle<&Style::position, &Style::setPosition>( + node, scopedEnum(edge), value::percent(percent)); } YGValue YGNodeStyleGetPosition(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().position(edge); + return resolveRef(node)->getStyle().position(scopedEnum(edge)); } void YGNodeStyleSetMargin(YGNodeRef node, YGEdge edge, float points) { - auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value); + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), value::points(points)); } void YGNodeStyleSetMarginPercent(YGNodeRef node, YGEdge edge, float percent) { - auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, value); + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), value::percent(percent)); } void YGNodeStyleSetMarginAuto(YGNodeRef node, YGEdge edge) { - updateIndexedStyleProp<&Style::margin, &Style::setMargin>(node, edge, CompactValue::ofAuto()); + updateStyle<&Style::margin, &Style::setMargin>( + node, scopedEnum(edge), value::ofAuto()); } YGValue YGNodeStyleGetMargin(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().margin(edge); + return resolveRef(node)->getStyle().margin(scopedEnum(edge)); } void YGNodeStyleSetPadding(YGNodeRef node, YGEdge edge, float points) { - auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp<&Style::padding, &Style::setPadding>( - node, edge, value); + updateStyle<&Style::padding, &Style::setPadding>( + node, scopedEnum(edge), value::points(points)); } void YGNodeStyleSetPaddingPercent(YGNodeRef node, YGEdge edge, float percent) { - auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp<&Style::padding, &Style::setPadding>( - node, edge, value); + updateStyle<&Style::padding, &Style::setPadding>( + node, scopedEnum(edge), value::percent(percent)); } YGValue YGNodeStyleGetPadding(YGNodeConstRef node, YGEdge edge) { - return resolveRef(node)->getStyle().padding(edge); + return resolveRef(node)->getStyle().padding(scopedEnum(edge)); } void YGNodeStyleSetBorder( const YGNodeRef node, const YGEdge edge, const float border) { - auto value = CompactValue::ofMaybe(border); - updateIndexedStyleProp<&Style::border, &Style::setBorder>(node, edge, value); + updateStyle<&Style::border, &Style::setBorder>(node, scopedEnum(edge), value::points(border)); } float YGNodeStyleGetBorder(const YGNodeConstRef node, const YGEdge edge) { - auto border = resolveRef(node)->getStyle().border(edge); + auto border = resolveRef(node)->getStyle().border(scopedEnum(edge)); if (border.isUndefined() || border.isAuto()) { return YGUndefined; } @@ -604,9 +581,8 @@ void YGNodeStyleSetGap( const YGNodeRef node, const YGGutter gutter, const float gapLength) { - auto length = CompactValue::ofMaybe(gapLength); - updateIndexedStyleProp<&Style::gap, &Style::setGap>( - node, scopedEnum(gutter), length); + updateStyle<&Style::gap, &Style::setGap>( + node, scopedEnum(gutter), value::points(gapLength)); } float YGNodeStyleGetGap(const YGNodeConstRef node, const YGGutter gutter) { @@ -626,101 +602,95 @@ float YGNodeStyleGetAspectRatio(const YGNodeConstRef node) { } void YGNodeStyleSetAspectRatio(const YGNodeRef node, const float aspectRatio) { - updateStyle( - node, &Style::aspectRatio, FloatOptional{aspectRatio}); + updateStyle<&Style::aspectRatio, &Style::setAspectRatio>( + node, FloatOptional{aspectRatio}); } void YGNodeStyleSetWidth(YGNodeRef node, float points) { - auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, Dimension::Width, value); + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, value::points(points)); } void YGNodeStyleSetWidthPercent(YGNodeRef node, float percent) { - auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, Dimension::Width, value); + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, value::percent(percent)); } void YGNodeStyleSetWidthAuto(YGNodeRef node) { - updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, Dimension::Width, CompactValue::ofAuto()); + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Width, value::ofAuto()); } YGValue YGNodeStyleGetWidth(YGNodeConstRef node) { return resolveRef(node)->getStyle().dimension(Dimension::Width); } void YGNodeStyleSetHeight(YGNodeRef node, float points) { - auto value = CompactValue::ofMaybe(points); - updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, Dimension::Height, value); + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, value::points(points)); } + void YGNodeStyleSetHeightPercent(YGNodeRef node, float percent) { - auto value = CompactValue::ofMaybe(percent); - updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, Dimension::Height, value); + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, value::percent(percent)); } + void YGNodeStyleSetHeightAuto(YGNodeRef node) { - updateIndexedStyleProp<&Style::dimension, &Style::setDimension>( - node, Dimension::Height, CompactValue::ofAuto()); + updateStyle<&Style::dimension, &Style::setDimension>( + node, Dimension::Height, value::ofAuto()); } YGValue YGNodeStyleGetHeight(YGNodeConstRef node) { return resolveRef(node)->getStyle().dimension(Dimension::Height); } void YGNodeStyleSetMinWidth(const YGNodeRef node, const float minWidth) { - auto value = CompactValue::ofMaybe(minWidth); - updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Width, value); + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, value::points(minWidth)); } + void YGNodeStyleSetMinWidthPercent(const YGNodeRef node, const float minWidth) { - auto value = CompactValue::ofMaybe(minWidth); - updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Width, value); + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Width, value::percent(minWidth)); } YGValue YGNodeStyleGetMinWidth(const YGNodeConstRef node) { return resolveRef(node)->getStyle().minDimension(Dimension::Width); } void YGNodeStyleSetMinHeight(const YGNodeRef node, const float minHeight) { - auto value = CompactValue::ofMaybe(minHeight); - updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Height, value); + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, value::points(minHeight)); } + void YGNodeStyleSetMinHeightPercent( const YGNodeRef node, const float minHeight) { - auto value = CompactValue::ofMaybe(minHeight); - updateIndexedStyleProp<&Style::minDimension, &Style::setMinDimension>( - node, Dimension::Height, value); + updateStyle<&Style::minDimension, &Style::setMinDimension>( + node, Dimension::Height, value::percent(minHeight)); } YGValue YGNodeStyleGetMinHeight(const YGNodeConstRef node) { return resolveRef(node)->getStyle().minDimension(Dimension::Height); } void YGNodeStyleSetMaxWidth(const YGNodeRef node, const float maxWidth) { - auto value = CompactValue::ofMaybe(maxWidth); - updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Width, value); + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, value::points(maxWidth)); } + void YGNodeStyleSetMaxWidthPercent(const YGNodeRef node, const float maxWidth) { - auto value = CompactValue::ofMaybe(maxWidth); - updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Width, value); + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Width, value::percent(maxWidth)); } YGValue YGNodeStyleGetMaxWidth(const YGNodeConstRef node) { return resolveRef(node)->getStyle().maxDimension(Dimension::Width); } void YGNodeStyleSetMaxHeight(const YGNodeRef node, const float maxHeight) { - auto value = CompactValue::ofMaybe(maxHeight); - updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Height, value); + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, value::points(maxHeight)); } + void YGNodeStyleSetMaxHeightPercent( const YGNodeRef node, const float maxHeight) { - auto value = CompactValue::ofMaybe(maxHeight); - updateIndexedStyleProp<&Style::maxDimension, &Style::setMaxDimension>( - node, Dimension::Height, value); + updateStyle<&Style::maxDimension, &Style::setMaxDimension>( + node, Dimension::Height, value::percent(maxHeight)); } YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { return resolveRef(node)->getStyle().maxDimension(Dimension::Height); @@ -729,50 +699,48 @@ YGValue YGNodeStyleGetMaxHeight(const YGNodeConstRef node) { namespace { template -float getResolvedLayoutProperty( - const YGNodeConstRef nodeRef, - const YGEdge edge) { +float getResolvedLayoutProperty(const YGNodeConstRef nodeRef, const Edge edge) { const auto node = resolveRef(nodeRef); yoga::assertFatalWithNode( node, - edge <= YGEdgeEnd, + edge <= Edge::End, "Cannot get layout properties of multi-edge shorthands"); - if (edge == YGEdgeStart) { + if (edge == Edge::Start) { if (node->getLayout().direction() == Direction::RTL) { - return (node->getLayout().*LayoutMember)[YGEdgeRight]; + return (node->getLayout().*LayoutMember)(Edge::Right); } else { - return (node->getLayout().*LayoutMember)[YGEdgeLeft]; + return (node->getLayout().*LayoutMember)(Edge::Left); } } - if (edge == YGEdgeEnd) { + if (edge == Edge::End) { if (node->getLayout().direction() == Direction::RTL) { - return (node->getLayout().*LayoutMember)[YGEdgeLeft]; + return (node->getLayout().*LayoutMember)(Edge::Left); } else { - return (node->getLayout().*LayoutMember)[YGEdgeRight]; + return (node->getLayout().*LayoutMember)(Edge::Right); } } - return (node->getLayout().*LayoutMember)[edge]; + return (node->getLayout().*LayoutMember)(edge); } } // namespace float YGNodeLayoutGetLeft(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position[YGEdgeLeft]; + return resolveRef(node)->getLayout().position(Edge::Left); } float YGNodeLayoutGetTop(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position[YGEdgeTop]; + return resolveRef(node)->getLayout().position(Edge::Top); } float YGNodeLayoutGetRight(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position[YGEdgeRight]; + return resolveRef(node)->getLayout().position(Edge::Right); } float YGNodeLayoutGetBottom(const YGNodeConstRef node) { - return resolveRef(node)->getLayout().position[YGEdgeBottom]; + return resolveRef(node)->getLayout().position(Edge::Bottom); } float YGNodeLayoutGetWidth(const YGNodeConstRef node) { @@ -792,15 +760,18 @@ bool YGNodeLayoutGetHadOverflow(const YGNodeConstRef node) { } float YGNodeLayoutGetMargin(YGNodeConstRef node, YGEdge edge) { - return getResolvedLayoutProperty<&LayoutResults::margin>(node, edge); + return getResolvedLayoutProperty<&LayoutResults::margin>( + node, scopedEnum(edge)); } float YGNodeLayoutGetBorder(YGNodeConstRef node, YGEdge edge) { - return getResolvedLayoutProperty<&LayoutResults::border>(node, edge); + return getResolvedLayoutProperty<&LayoutResults::border>( + node, scopedEnum(edge)); } float YGNodeLayoutGetPadding(YGNodeConstRef node, YGEdge edge) { - return getResolvedLayoutProperty<&LayoutResults::padding>(node, edge); + return getResolvedLayoutProperty<&LayoutResults::padding>( + node, scopedEnum(edge)); } #ifdef DEBUG @@ -908,13 +879,13 @@ bool YGNodeCanUseCachedMeasurement( float marginColumn, YGConfigRef config) { return yoga::canUseCachedMeasurement( - scopedEnum(widthMode), + sizingMode(scopedEnum(widthMode)), availableWidth, - scopedEnum(heightMode), + sizingMode(scopedEnum(heightMode)), availableHeight, - scopedEnum(lastWidthMode), + sizingMode(scopedEnum(lastWidthMode)), lastAvailableWidth, - scopedEnum(lastHeightMode), + sizingMode(scopedEnum(lastHeightMode)), lastAvailableHeight, lastComputedWidth, lastComputedHeight, diff --git a/vnext/codegen/react/components/rnwcore/Props.cpp b/vnext/codegen/react/components/rnwcore/Props.cpp index bb6c2d0ac89..070df7ab692 100644 --- a/vnext/codegen/react/components/rnwcore/Props.cpp +++ b/vnext/codegen/react/components/rnwcore/Props.cpp @@ -42,8 +42,8 @@ ActivityIndicatorViewProps::ActivityIndicatorViewProps( const ActivityIndicatorViewProps &sourceProps, const RawProps &rawProps): ViewProps(context, sourceProps, rawProps), - hidesWhenStopped(convertRawProp(context, rawProps, "hidesWhenStopped", sourceProps.hidesWhenStopped, {false})), - animating(convertRawProp(context, rawProps, "animating", sourceProps.animating, {false})), + hidesWhenStopped(convertRawProp(context, rawProps, "hidesWhenStopped", sourceProps.hidesWhenStopped, {true})), + animating(convertRawProp(context, rawProps, "animating", sourceProps.animating, {true})), color(convertRawProp(context, rawProps, "color", sourceProps.color, {})), size(convertRawProp(context, rawProps, "size", sourceProps.size, {ActivityIndicatorViewSize::Small})) {} diff --git a/vnext/codegen/react/components/rnwcore/Props.h b/vnext/codegen/react/components/rnwcore/Props.h index bcc5840b376..a176b156766 100644 --- a/vnext/codegen/react/components/rnwcore/Props.h +++ b/vnext/codegen/react/components/rnwcore/Props.h @@ -185,8 +185,8 @@ class ActivityIndicatorViewProps final : public ViewProps { #pragma mark - Props - bool hidesWhenStopped{false}; - bool animating{false}; + bool hidesWhenStopped{true}; + bool animating{true}; SharedColor color{}; ActivityIndicatorViewSize size{ActivityIndicatorViewSize::Small}; }; diff --git a/vnext/codegen/rnwcoreJSI.h b/vnext/codegen/rnwcoreJSI.h index 23295a92375..a9375099c52 100644 --- a/vnext/codegen/rnwcoreJSI.h +++ b/vnext/codegen/rnwcoreJSI.h @@ -93,7 +93,7 @@ class JSI_EXPORT NativeActionSheetManagerCxxSpec : public TurboModule { #pragma mark - AlertManagerBaseArgs template -struct AlertManagerBaseArgs { +struct [[deprecated("Use AlertManagerArgs instead.")]] AlertManagerBaseArgs { P0 title; P1 message; P2 buttons; @@ -110,7 +110,7 @@ struct AlertManagerBaseArgs { }; template -struct AlertManagerBaseArgsBridging { +struct [[deprecated("Use AlertManagerArgsBridging instead.")]] AlertManagerBaseArgsBridging { static AlertManagerBaseArgs fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -210,6 +210,129 @@ struct AlertManagerBaseArgsBridging { } }; + +#pragma mark - AlertManagerArgs + +template +struct AlertManagerArgs { + P0 title; + P1 message; + P2 buttons; + P3 type; + P4 defaultValue; + P5 cancelButtonKey; + P6 destructiveButtonKey; + P7 preferredButtonKey; + P8 keyboardType; + P9 userInterfaceStyle; + bool operator==(const AlertManagerArgs &other) const { + return title == other.title && message == other.message && buttons == other.buttons && type == other.type && defaultValue == other.defaultValue && cancelButtonKey == other.cancelButtonKey && destructiveButtonKey == other.destructiveButtonKey && preferredButtonKey == other.preferredButtonKey && keyboardType == other.keyboardType && userInterfaceStyle == other.userInterfaceStyle; + } +}; + +template +struct AlertManagerArgsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "message"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttons"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "type"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "defaultValue"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "cancelButtonKey"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "destructiveButtonKey"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "preferredButtonKey"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "keyboardType"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "userInterfaceStyle"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static jsi::String messageToJs(jsi::Runtime &rt, decltype(types.message) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array buttonsToJs(jsi::Runtime &rt, decltype(types.buttons) value) { + return bridging::toJs(rt, value); + } + + static jsi::String typeToJs(jsi::Runtime &rt, decltype(types.type) value) { + return bridging::toJs(rt, value); + } + + static jsi::String defaultValueToJs(jsi::Runtime &rt, decltype(types.defaultValue) value) { + return bridging::toJs(rt, value); + } + + static jsi::String cancelButtonKeyToJs(jsi::Runtime &rt, decltype(types.cancelButtonKey) value) { + return bridging::toJs(rt, value); + } + + static jsi::String destructiveButtonKeyToJs(jsi::Runtime &rt, decltype(types.destructiveButtonKey) value) { + return bridging::toJs(rt, value); + } + + static jsi::String preferredButtonKeyToJs(jsi::Runtime &rt, decltype(types.preferredButtonKey) value) { + return bridging::toJs(rt, value); + } + + static jsi::String keyboardTypeToJs(jsi::Runtime &rt, decltype(types.keyboardType) value) { + return bridging::toJs(rt, value); + } + + static jsi::String userInterfaceStyleToJs(jsi::Runtime &rt, decltype(types.userInterfaceStyle) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.message) { + result.setProperty(rt, "message", bridging::toJs(rt, value.message.value(), jsInvoker)); + } + if (value.buttons) { + result.setProperty(rt, "buttons", bridging::toJs(rt, value.buttons.value(), jsInvoker)); + } + if (value.type) { + result.setProperty(rt, "type", bridging::toJs(rt, value.type.value(), jsInvoker)); + } + if (value.defaultValue) { + result.setProperty(rt, "defaultValue", bridging::toJs(rt, value.defaultValue.value(), jsInvoker)); + } + if (value.cancelButtonKey) { + result.setProperty(rt, "cancelButtonKey", bridging::toJs(rt, value.cancelButtonKey.value(), jsInvoker)); + } + if (value.destructiveButtonKey) { + result.setProperty(rt, "destructiveButtonKey", bridging::toJs(rt, value.destructiveButtonKey.value(), jsInvoker)); + } + if (value.preferredButtonKey) { + result.setProperty(rt, "preferredButtonKey", bridging::toJs(rt, value.preferredButtonKey.value(), jsInvoker)); + } + if (value.keyboardType) { + result.setProperty(rt, "keyboardType", bridging::toJs(rt, value.keyboardType.value(), jsInvoker)); + } + if (value.userInterfaceStyle) { + result.setProperty(rt, "userInterfaceStyle", bridging::toJs(rt, value.userInterfaceStyle.value(), jsInvoker)); + } + return result; + } +}; + class JSI_EXPORT NativeAlertManagerCxxSpecJSI : public TurboModule { protected: NativeAlertManagerCxxSpecJSI(std::shared_ptr jsInvoker); @@ -260,7 +383,7 @@ class JSI_EXPORT NativeAlertManagerCxxSpec : public TurboModule { #pragma mark - AlertBaseDialogOptions template -struct AlertBaseDialogOptions { +struct [[deprecated("Use AlertDialogOptions instead.")]] AlertBaseDialogOptions { P0 title; P1 message; P2 buttonPositive; @@ -276,7 +399,7 @@ struct AlertBaseDialogOptions { }; template -struct AlertBaseDialogOptionsBridging { +struct [[deprecated("Use AlertDialogOptionsBridging instead.")]] AlertBaseDialogOptionsBridging { static AlertBaseDialogOptions fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -368,6 +491,120 @@ struct AlertBaseDialogOptionsBridging { } }; + +#pragma mark - AlertDialogOptions + +template +struct AlertDialogOptions { + P0 title; + P1 message; + P2 buttonPositive; + P3 buttonNegative; + P4 buttonNeutral; + P5 items; + P6 cancelable; + P7 defaultButton; + P8 rootTag; + bool operator==(const AlertDialogOptions &other) const { + return title == other.title && message == other.message && buttonPositive == other.buttonPositive && buttonNegative == other.buttonNegative && buttonNeutral == other.buttonNeutral && items == other.items && cancelable == other.cancelable && defaultButton == other.defaultButton && rootTag == other.rootTag; + } +}; + +template +struct AlertDialogOptionsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "message"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttonPositive"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttonNegative"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttonNeutral"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "items"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "cancelable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "defaultButton"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "rootTag"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static jsi::String messageToJs(jsi::Runtime &rt, decltype(types.message) value) { + return bridging::toJs(rt, value); + } + + static jsi::String buttonPositiveToJs(jsi::Runtime &rt, decltype(types.buttonPositive) value) { + return bridging::toJs(rt, value); + } + + static jsi::String buttonNegativeToJs(jsi::Runtime &rt, decltype(types.buttonNegative) value) { + return bridging::toJs(rt, value); + } + + static jsi::String buttonNeutralToJs(jsi::Runtime &rt, decltype(types.buttonNeutral) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array itemsToJs(jsi::Runtime &rt, decltype(types.items) value) { + return bridging::toJs(rt, value); + } + + static bool cancelableToJs(jsi::Runtime &rt, decltype(types.cancelable) value) { + return bridging::toJs(rt, value); + } + + static int defaultButtonToJs(jsi::Runtime &rt, decltype(types.defaultButton) value) { + return bridging::toJs(rt, value); + } + + static int rootTagToJs(jsi::Runtime &rt, decltype(types.rootTag) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.message) { + result.setProperty(rt, "message", bridging::toJs(rt, value.message.value(), jsInvoker)); + } + if (value.buttonPositive) { + result.setProperty(rt, "buttonPositive", bridging::toJs(rt, value.buttonPositive.value(), jsInvoker)); + } + if (value.buttonNegative) { + result.setProperty(rt, "buttonNegative", bridging::toJs(rt, value.buttonNegative.value(), jsInvoker)); + } + if (value.buttonNeutral) { + result.setProperty(rt, "buttonNeutral", bridging::toJs(rt, value.buttonNeutral.value(), jsInvoker)); + } + if (value.items) { + result.setProperty(rt, "items", bridging::toJs(rt, value.items.value(), jsInvoker)); + } + if (value.cancelable) { + result.setProperty(rt, "cancelable", bridging::toJs(rt, value.cancelable.value(), jsInvoker)); + } + if (value.defaultButton) { + result.setProperty(rt, "defaultButton", bridging::toJs(rt, value.defaultButton.value(), jsInvoker)); + } + if (value.rootTag) { + result.setProperty(rt, "rootTag", bridging::toJs(rt, value.rootTag.value(), jsInvoker)); + } + return result; + } +}; + class JSI_EXPORT NativeDialogManagerWindowsCxxSpecJSI : public TurboModule { protected: NativeDialogManagerWindowsCxxSpecJSI(std::shared_ptr jsInvoker); @@ -427,7 +664,7 @@ class JSI_EXPORT NativeDialogManagerWindowsCxxSpec : public TurboModule { #pragma mark - NativeAnimatedModuleBaseEndResult template -struct NativeAnimatedModuleBaseEndResult { +struct [[deprecated("Use NativeAnimatedModuleEndResult instead.")]] NativeAnimatedModuleBaseEndResult { P0 finished; P1 value; bool operator==(const NativeAnimatedModuleBaseEndResult &other) const { @@ -436,7 +673,7 @@ struct NativeAnimatedModuleBaseEndResult { }; template -struct NativeAnimatedModuleBaseEndResultBridging { +struct [[deprecated("Use NativeAnimatedModuleEndResultBridging instead.")]] NativeAnimatedModuleBaseEndResultBridging { static NativeAnimatedModuleBaseEndResult fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -475,7 +712,7 @@ struct NativeAnimatedModuleBaseEndResultBridging { #pragma mark - NativeAnimatedModuleBaseEventMapping template -struct NativeAnimatedModuleBaseEventMapping { +struct [[deprecated("Use NativeAnimatedModuleEventMapping instead.")]] NativeAnimatedModuleBaseEventMapping { P0 nativeEventPath; P1 animatedValueTag; bool operator==(const NativeAnimatedModuleBaseEventMapping &other) const { @@ -484,7 +721,7 @@ struct NativeAnimatedModuleBaseEventMapping { }; template -struct NativeAnimatedModuleBaseEventMappingBridging { +struct [[deprecated("Use NativeAnimatedModuleEventMappingBridging instead.")]] NativeAnimatedModuleBaseEventMappingBridging { static NativeAnimatedModuleBaseEventMapping fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -516,6 +753,103 @@ struct NativeAnimatedModuleBaseEventMappingBridging { } }; + +#pragma mark - NativeAnimatedModuleEndResult + +template +struct NativeAnimatedModuleEndResult { + P0 finished; + P1 value; + bool operator==(const NativeAnimatedModuleEndResult &other) const { + return finished == other.finished && value == other.value; + } +}; + +template +struct NativeAnimatedModuleEndResultBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "finished"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "value"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool finishedToJs(jsi::Runtime &rt, decltype(types.finished) value) { + return bridging::toJs(rt, value); + } + + static double valueToJs(jsi::Runtime &rt, decltype(types.value) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "finished", bridging::toJs(rt, value.finished, jsInvoker)); + if (value.value) { + result.setProperty(rt, "value", bridging::toJs(rt, value.value.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeAnimatedModuleEventMapping + +template +struct NativeAnimatedModuleEventMapping { + P0 nativeEventPath; + P1 animatedValueTag; + bool operator==(const NativeAnimatedModuleEventMapping &other) const { + return nativeEventPath == other.nativeEventPath && animatedValueTag == other.animatedValueTag; + } +}; + +template +struct NativeAnimatedModuleEventMappingBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "nativeEventPath"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "animatedValueTag"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array nativeEventPathToJs(jsi::Runtime &rt, decltype(types.nativeEventPath) value) { + return bridging::toJs(rt, value); + } + + static std::optional animatedValueTagToJs(jsi::Runtime &rt, decltype(types.animatedValueTag) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "nativeEventPath", bridging::toJs(rt, value.nativeEventPath, jsInvoker)); + result.setProperty(rt, "animatedValueTag", bridging::toJs(rt, value.animatedValueTag, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeAnimatedModuleCxxSpecJSI : public TurboModule { protected: NativeAnimatedModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -773,7 +1107,7 @@ class JSI_EXPORT NativeAnimatedModuleCxxSpec : public TurboModule { #pragma mark - NativeAnimatedTurboModuleBaseEndResult template -struct NativeAnimatedTurboModuleBaseEndResult { +struct [[deprecated("Use NativeAnimatedTurboModuleEndResult instead.")]] NativeAnimatedTurboModuleBaseEndResult { P0 finished; P1 value; bool operator==(const NativeAnimatedTurboModuleBaseEndResult &other) const { @@ -782,7 +1116,7 @@ struct NativeAnimatedTurboModuleBaseEndResult { }; template -struct NativeAnimatedTurboModuleBaseEndResultBridging { +struct [[deprecated("Use NativeAnimatedTurboModuleEndResultBridging instead.")]] NativeAnimatedTurboModuleBaseEndResultBridging { static NativeAnimatedTurboModuleBaseEndResult fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -821,7 +1155,7 @@ struct NativeAnimatedTurboModuleBaseEndResultBridging { #pragma mark - NativeAnimatedTurboModuleBaseEventMapping template -struct NativeAnimatedTurboModuleBaseEventMapping { +struct [[deprecated("Use NativeAnimatedTurboModuleEventMapping instead.")]] NativeAnimatedTurboModuleBaseEventMapping { P0 nativeEventPath; P1 animatedValueTag; bool operator==(const NativeAnimatedTurboModuleBaseEventMapping &other) const { @@ -830,7 +1164,7 @@ struct NativeAnimatedTurboModuleBaseEventMapping { }; template -struct NativeAnimatedTurboModuleBaseEventMappingBridging { +struct [[deprecated("Use NativeAnimatedTurboModuleEventMappingBridging instead.")]] NativeAnimatedTurboModuleBaseEventMappingBridging { static NativeAnimatedTurboModuleBaseEventMapping fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -862,6 +1196,103 @@ struct NativeAnimatedTurboModuleBaseEventMappingBridging { } }; + +#pragma mark - NativeAnimatedTurboModuleEndResult + +template +struct NativeAnimatedTurboModuleEndResult { + P0 finished; + P1 value; + bool operator==(const NativeAnimatedTurboModuleEndResult &other) const { + return finished == other.finished && value == other.value; + } +}; + +template +struct NativeAnimatedTurboModuleEndResultBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "finished"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "value"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool finishedToJs(jsi::Runtime &rt, decltype(types.finished) value) { + return bridging::toJs(rt, value); + } + + static double valueToJs(jsi::Runtime &rt, decltype(types.value) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "finished", bridging::toJs(rt, value.finished, jsInvoker)); + if (value.value) { + result.setProperty(rt, "value", bridging::toJs(rt, value.value.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativeAnimatedTurboModuleEventMapping + +template +struct NativeAnimatedTurboModuleEventMapping { + P0 nativeEventPath; + P1 animatedValueTag; + bool operator==(const NativeAnimatedTurboModuleEventMapping &other) const { + return nativeEventPath == other.nativeEventPath && animatedValueTag == other.animatedValueTag; + } +}; + +template +struct NativeAnimatedTurboModuleEventMappingBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "nativeEventPath"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "animatedValueTag"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array nativeEventPathToJs(jsi::Runtime &rt, decltype(types.nativeEventPath) value) { + return bridging::toJs(rt, value); + } + + static std::optional animatedValueTagToJs(jsi::Runtime &rt, decltype(types.animatedValueTag) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "nativeEventPath", bridging::toJs(rt, value.nativeEventPath, jsInvoker)); + result.setProperty(rt, "animatedValueTag", bridging::toJs(rt, value.animatedValueTag, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeAnimatedTurboModuleCxxSpecJSI : public TurboModule { protected: NativeAnimatedTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1119,7 +1550,7 @@ class JSI_EXPORT NativeAnimatedTurboModuleCxxSpec : public TurboModule { #pragma mark - AppStateBaseAppStateConstants template -struct AppStateBaseAppStateConstants { +struct [[deprecated("Use AppStateAppStateConstants instead.")]] AppStateBaseAppStateConstants { P0 initialAppState; bool operator==(const AppStateBaseAppStateConstants &other) const { return initialAppState == other.initialAppState; @@ -1127,7 +1558,7 @@ struct AppStateBaseAppStateConstants { }; template -struct AppStateBaseAppStateConstantsBridging { +struct [[deprecated("Use AppStateAppStateConstantsBridging instead.")]] AppStateBaseAppStateConstantsBridging { static AppStateBaseAppStateConstants fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -1158,7 +1589,7 @@ struct AppStateBaseAppStateConstantsBridging { #pragma mark - AppStateBaseAppState template -struct AppStateBaseAppState { +struct [[deprecated("Use AppStateAppState instead.")]] AppStateBaseAppState { P0 app_state; bool operator==(const AppStateBaseAppState &other) const { return app_state == other.app_state; @@ -1166,7 +1597,7 @@ struct AppStateBaseAppState { }; template -struct AppStateBaseAppStateBridging { +struct [[deprecated("Use AppStateAppStateBridging instead.")]] AppStateBaseAppStateBridging { static AppStateBaseAppState fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -1192,6 +1623,87 @@ struct AppStateBaseAppStateBridging { } }; + +#pragma mark - AppStateAppStateConstants + +template +struct AppStateAppStateConstants { + P0 initialAppState; + bool operator==(const AppStateAppStateConstants &other) const { + return initialAppState == other.initialAppState; + } +}; + +template +struct AppStateAppStateConstantsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "initialAppState"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String initialAppStateToJs(jsi::Runtime &rt, decltype(types.initialAppState) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "initialAppState", bridging::toJs(rt, value.initialAppState, jsInvoker)); + return result; + } +}; + + + +#pragma mark - AppStateAppState + +template +struct AppStateAppState { + P0 app_state; + bool operator==(const AppStateAppState &other) const { + return app_state == other.app_state; + } +}; + +template +struct AppStateAppStateBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "app_state"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String app_stateToJs(jsi::Runtime &rt, decltype(types.app_state) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "app_state", bridging::toJs(rt, value.app_state, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeAppStateCxxSpecJSI : public TurboModule { protected: NativeAppStateCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1269,7 +1781,7 @@ class JSI_EXPORT NativeAppStateCxxSpec : public TurboModule { #pragma mark - AppThemeBaseHighContrastColors template -struct AppThemeBaseHighContrastColors { +struct [[deprecated("Use AppThemeHighContrastColors instead.")]] AppThemeBaseHighContrastColors { P0 ButtonFaceColor; P1 ButtonTextColor; P2 GrayTextColor; @@ -1284,7 +1796,7 @@ struct AppThemeBaseHighContrastColors { }; template -struct AppThemeBaseHighContrastColorsBridging { +struct [[deprecated("Use AppThemeHighContrastColorsBridging instead.")]] AppThemeBaseHighContrastColorsBridging { static AppThemeBaseHighContrastColors fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -1357,7 +1869,7 @@ struct AppThemeBaseHighContrastColorsBridging { #pragma mark - AppThemeBaseAppThemeData template -struct AppThemeBaseAppThemeData { +struct [[deprecated("Use AppThemeAppThemeData instead.")]] AppThemeBaseAppThemeData { P0 isHighContrast; P1 highContrastColors; bool operator==(const AppThemeBaseAppThemeData &other) const { @@ -1366,7 +1878,7 @@ struct AppThemeBaseAppThemeData { }; template -struct AppThemeBaseAppThemeDataBridging { +struct [[deprecated("Use AppThemeAppThemeDataBridging instead.")]] AppThemeBaseAppThemeDataBridging { static AppThemeBaseAppThemeData fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -1398,6 +1910,143 @@ struct AppThemeBaseAppThemeDataBridging { } }; + +#pragma mark - AppThemeHighContrastColors + +template +struct AppThemeHighContrastColors { + P0 ButtonFaceColor; + P1 ButtonTextColor; + P2 GrayTextColor; + P3 HighlightColor; + P4 HighlightTextColor; + P5 HotlightColor; + P6 WindowColor; + P7 WindowTextColor; + bool operator==(const AppThemeHighContrastColors &other) const { + return ButtonFaceColor == other.ButtonFaceColor && ButtonTextColor == other.ButtonTextColor && GrayTextColor == other.GrayTextColor && HighlightColor == other.HighlightColor && HighlightTextColor == other.HighlightTextColor && HotlightColor == other.HotlightColor && WindowColor == other.WindowColor && WindowTextColor == other.WindowTextColor; + } +}; + +template +struct AppThemeHighContrastColorsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "ButtonFaceColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "ButtonTextColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "GrayTextColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "HighlightColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "HighlightTextColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "HotlightColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "WindowColor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "WindowTextColor"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String ButtonFaceColorToJs(jsi::Runtime &rt, decltype(types.ButtonFaceColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String ButtonTextColorToJs(jsi::Runtime &rt, decltype(types.ButtonTextColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String GrayTextColorToJs(jsi::Runtime &rt, decltype(types.GrayTextColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String HighlightColorToJs(jsi::Runtime &rt, decltype(types.HighlightColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String HighlightTextColorToJs(jsi::Runtime &rt, decltype(types.HighlightTextColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String HotlightColorToJs(jsi::Runtime &rt, decltype(types.HotlightColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String WindowColorToJs(jsi::Runtime &rt, decltype(types.WindowColor) value) { + return bridging::toJs(rt, value); + } + + static jsi::String WindowTextColorToJs(jsi::Runtime &rt, decltype(types.WindowTextColor) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "ButtonFaceColor", bridging::toJs(rt, value.ButtonFaceColor, jsInvoker)); + result.setProperty(rt, "ButtonTextColor", bridging::toJs(rt, value.ButtonTextColor, jsInvoker)); + result.setProperty(rt, "GrayTextColor", bridging::toJs(rt, value.GrayTextColor, jsInvoker)); + result.setProperty(rt, "HighlightColor", bridging::toJs(rt, value.HighlightColor, jsInvoker)); + result.setProperty(rt, "HighlightTextColor", bridging::toJs(rt, value.HighlightTextColor, jsInvoker)); + result.setProperty(rt, "HotlightColor", bridging::toJs(rt, value.HotlightColor, jsInvoker)); + result.setProperty(rt, "WindowColor", bridging::toJs(rt, value.WindowColor, jsInvoker)); + result.setProperty(rt, "WindowTextColor", bridging::toJs(rt, value.WindowTextColor, jsInvoker)); + return result; + } +}; + + + +#pragma mark - AppThemeAppThemeData + +template +struct AppThemeAppThemeData { + P0 isHighContrast; + P1 highContrastColors; + bool operator==(const AppThemeAppThemeData &other) const { + return isHighContrast == other.isHighContrast && highContrastColors == other.highContrastColors; + } +}; + +template +struct AppThemeAppThemeDataBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "isHighContrast"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "highContrastColors"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool isHighContrastToJs(jsi::Runtime &rt, decltype(types.isHighContrast) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object highContrastColorsToJs(jsi::Runtime &rt, decltype(types.highContrastColors) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "isHighContrast", bridging::toJs(rt, value.isHighContrast, jsInvoker)); + result.setProperty(rt, "highContrastColors", bridging::toJs(rt, value.highContrastColors, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeAppThemeCxxSpecJSI : public TurboModule { protected: NativeAppThemeCxxSpecJSI(std::shared_ptr jsInvoker); @@ -1667,7 +2316,7 @@ class JSI_EXPORT NativeBugReportingCxxSpec : public TurboModule { #pragma mark - ExceptionsManagerBaseStackFrame template -struct ExceptionsManagerBaseStackFrame { +struct [[deprecated("Use ExceptionsManagerStackFrame instead.")]] ExceptionsManagerBaseStackFrame { P0 column; P1 file; P2 lineNumber; @@ -1679,7 +2328,7 @@ struct ExceptionsManagerBaseStackFrame { }; template -struct ExceptionsManagerBaseStackFrameBridging { +struct [[deprecated("Use ExceptionsManagerStackFrameBridging instead.")]] ExceptionsManagerBaseStackFrameBridging { static ExceptionsManagerBaseStackFrame fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -1736,7 +2385,7 @@ struct ExceptionsManagerBaseStackFrameBridging { #pragma mark - ExceptionsManagerBaseExceptionData template -struct ExceptionsManagerBaseExceptionData { +struct [[deprecated("Use ExceptionsManagerExceptionData instead.")]] ExceptionsManagerBaseExceptionData { P0 message; P1 originalMessage; P2 name; @@ -1751,7 +2400,7 @@ struct ExceptionsManagerBaseExceptionData { }; template -struct ExceptionsManagerBaseExceptionDataBridging { +struct [[deprecated("Use ExceptionsManagerExceptionDataBridging instead.")]] ExceptionsManagerBaseExceptionDataBridging { static ExceptionsManagerBaseExceptionData fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -1821,24 +2470,186 @@ struct ExceptionsManagerBaseExceptionDataBridging { } }; -class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule { -protected: - NativeExceptionsManagerCxxSpecJSI(std::shared_ptr jsInvoker); -public: - virtual void reportFatalException(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) = 0; - virtual void reportSoftException(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) = 0; - virtual void reportException(jsi::Runtime &rt, jsi::Object data) = 0; - virtual void updateExceptionMessage(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) = 0; - virtual void dismissRedbox(jsi::Runtime &rt) = 0; +#pragma mark - ExceptionsManagerStackFrame +template +struct ExceptionsManagerStackFrame { + P0 column; + P1 file; + P2 lineNumber; + P3 methodName; + P4 collapse; + bool operator==(const ExceptionsManagerStackFrame &other) const { + return column == other.column && file == other.file && lineNumber == other.lineNumber && methodName == other.methodName && collapse == other.collapse; + } }; template -class JSI_EXPORT NativeExceptionsManagerCxxSpec : public TurboModule { -public: - jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { - return delegate_.get(rt, propName); +struct ExceptionsManagerStackFrameBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "column"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "file"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "lineNumber"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "methodName"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "collapse"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static std::optional columnToJs(jsi::Runtime &rt, decltype(types.column) value) { + return bridging::toJs(rt, value); + } + + static std::optional fileToJs(jsi::Runtime &rt, decltype(types.file) value) { + return bridging::toJs(rt, value); + } + + static std::optional lineNumberToJs(jsi::Runtime &rt, decltype(types.lineNumber) value) { + return bridging::toJs(rt, value); + } + + static jsi::String methodNameToJs(jsi::Runtime &rt, decltype(types.methodName) value) { + return bridging::toJs(rt, value); + } + + static bool collapseToJs(jsi::Runtime &rt, decltype(types.collapse) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "column", bridging::toJs(rt, value.column, jsInvoker)); + result.setProperty(rt, "file", bridging::toJs(rt, value.file, jsInvoker)); + result.setProperty(rt, "lineNumber", bridging::toJs(rt, value.lineNumber, jsInvoker)); + result.setProperty(rt, "methodName", bridging::toJs(rt, value.methodName, jsInvoker)); + if (value.collapse) { + result.setProperty(rt, "collapse", bridging::toJs(rt, value.collapse.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - ExceptionsManagerExceptionData + +template +struct ExceptionsManagerExceptionData { + P0 message; + P1 originalMessage; + P2 name; + P3 componentStack; + P4 stack; + P5 id; + P6 isFatal; + P7 extraData; + bool operator==(const ExceptionsManagerExceptionData &other) const { + return message == other.message && originalMessage == other.originalMessage && name == other.name && componentStack == other.componentStack && stack == other.stack && id == other.id && isFatal == other.isFatal && extraData == other.extraData; + } +}; + +template +struct ExceptionsManagerExceptionDataBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "message"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "originalMessage"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "name"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "componentStack"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "stack"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "id"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isFatal"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "extraData"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String messageToJs(jsi::Runtime &rt, decltype(types.message) value) { + return bridging::toJs(rt, value); + } + + static std::optional originalMessageToJs(jsi::Runtime &rt, decltype(types.originalMessage) value) { + return bridging::toJs(rt, value); + } + + static std::optional nameToJs(jsi::Runtime &rt, decltype(types.name) value) { + return bridging::toJs(rt, value); + } + + static std::optional componentStackToJs(jsi::Runtime &rt, decltype(types.componentStack) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array stackToJs(jsi::Runtime &rt, decltype(types.stack) value) { + return bridging::toJs(rt, value); + } + + static double idToJs(jsi::Runtime &rt, decltype(types.id) value) { + return bridging::toJs(rt, value); + } + + static bool isFatalToJs(jsi::Runtime &rt, decltype(types.isFatal) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object extraDataToJs(jsi::Runtime &rt, decltype(types.extraData) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "message", bridging::toJs(rt, value.message, jsInvoker)); + result.setProperty(rt, "originalMessage", bridging::toJs(rt, value.originalMessage, jsInvoker)); + result.setProperty(rt, "name", bridging::toJs(rt, value.name, jsInvoker)); + result.setProperty(rt, "componentStack", bridging::toJs(rt, value.componentStack, jsInvoker)); + result.setProperty(rt, "stack", bridging::toJs(rt, value.stack, jsInvoker)); + result.setProperty(rt, "id", bridging::toJs(rt, value.id, jsInvoker)); + result.setProperty(rt, "isFatal", bridging::toJs(rt, value.isFatal, jsInvoker)); + if (value.extraData) { + result.setProperty(rt, "extraData", bridging::toJs(rt, value.extraData.value(), jsInvoker)); + } + return result; + } +}; + +class JSI_EXPORT NativeExceptionsManagerCxxSpecJSI : public TurboModule { +protected: + NativeExceptionsManagerCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual void reportFatalException(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) = 0; + virtual void reportSoftException(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) = 0; + virtual void reportException(jsi::Runtime &rt, jsi::Object data) = 0; + virtual void updateExceptionMessage(jsi::Runtime &rt, jsi::String message, jsi::Array stack, double exceptionId) = 0; + virtual void dismissRedbox(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeExceptionsManagerCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); } static constexpr std::string_view kModuleName = "ExceptionsManager"; @@ -2026,7 +2837,7 @@ class JSI_EXPORT NativeJSCHeapCaptureCxxSpec : public TurboModule { #pragma mark - ImageEditingManagerBaseOptions template -struct ImageEditingManagerBaseOptions { +struct [[deprecated("Use ImageEditingManagerOptions instead.")]] ImageEditingManagerBaseOptions { P0 offset; P1 size; P2 displaySize; @@ -2038,7 +2849,7 @@ struct ImageEditingManagerBaseOptions { }; template -struct ImageEditingManagerBaseOptionsBridging { +struct [[deprecated("Use ImageEditingManagerOptionsBridging instead.")]] ImageEditingManagerBaseOptionsBridging { static ImageEditingManagerBaseOptions fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -2094,6 +2905,80 @@ struct ImageEditingManagerBaseOptionsBridging { } }; + +#pragma mark - ImageEditingManagerOptions + +template +struct ImageEditingManagerOptions { + P0 offset; + P1 size; + P2 displaySize; + P3 resizeMode; + P4 allowExternalStorage; + bool operator==(const ImageEditingManagerOptions &other) const { + return offset == other.offset && size == other.size && displaySize == other.displaySize && resizeMode == other.resizeMode && allowExternalStorage == other.allowExternalStorage; + } +}; + +template +struct ImageEditingManagerOptionsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "offset"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "size"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "displaySize"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "resizeMode"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "allowExternalStorage"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object offsetToJs(jsi::Runtime &rt, decltype(types.offset) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object sizeToJs(jsi::Runtime &rt, decltype(types.size) value) { + return bridging::toJs(rt, value); + } + + static std::optional displaySizeToJs(jsi::Runtime &rt, decltype(types.displaySize) value) { + return bridging::toJs(rt, value); + } + + static std::optional resizeModeToJs(jsi::Runtime &rt, decltype(types.resizeMode) value) { + return bridging::toJs(rt, value); + } + + static bool allowExternalStorageToJs(jsi::Runtime &rt, decltype(types.allowExternalStorage) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "offset", bridging::toJs(rt, value.offset, jsInvoker)); + result.setProperty(rt, "size", bridging::toJs(rt, value.size, jsInvoker)); + if (value.displaySize) { + result.setProperty(rt, "displaySize", bridging::toJs(rt, value.displaySize.value(), jsInvoker)); + } + if (value.resizeMode) { + result.setProperty(rt, "resizeMode", bridging::toJs(rt, value.resizeMode.value(), jsInvoker)); + } + if (value.allowExternalStorage) { + result.setProperty(rt, "allowExternalStorage", bridging::toJs(rt, value.allowExternalStorage.value(), jsInvoker)); + } + return result; + } +}; + class JSI_EXPORT NativeImageEditorCxxSpecJSI : public TurboModule { protected: NativeImageEditorCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2153,7 +3038,7 @@ class JSI_EXPORT NativeImageEditorCxxSpec : public TurboModule { #pragma mark - ImageLoaderBaseImageSize template -struct ImageLoaderBaseImageSize { +struct [[deprecated("Use ImageLoaderImageSize instead.")]] ImageLoaderBaseImageSize { P0 width; P1 height; bool operator==(const ImageLoaderBaseImageSize &other) const { @@ -2162,7 +3047,7 @@ struct ImageLoaderBaseImageSize { }; template -struct ImageLoaderBaseImageSizeBridging { +struct [[deprecated("Use ImageLoaderImageSizeBridging instead.")]] ImageLoaderBaseImageSizeBridging { static ImageLoaderBaseImageSize fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -2194,6 +3079,53 @@ struct ImageLoaderBaseImageSizeBridging { } }; + +#pragma mark - ImageLoaderImageSize + +template +struct ImageLoaderImageSize { + P0 width; + P1 height; + bool operator==(const ImageLoaderImageSize &other) const { + return width == other.width && height == other.height; + } +}; + +template +struct ImageLoaderImageSizeBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "width"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "height"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double widthToJs(jsi::Runtime &rt, decltype(types.width) value) { + return bridging::toJs(rt, value); + } + + static double heightToJs(jsi::Runtime &rt, decltype(types.height) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "width", bridging::toJs(rt, value.width, jsInvoker)); + result.setProperty(rt, "height", bridging::toJs(rt, value.height, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeImageLoaderAndroidCxxSpecJSI : public TurboModule { protected: NativeImageLoaderAndroidCxxSpecJSI(std::shared_ptr jsInvoker); @@ -2590,7 +3522,7 @@ class JSI_EXPORT NativeFrameRateLoggerCxxSpec : public TurboModule { #pragma mark - NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptions template -struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptions { +struct [[deprecated("Use NativeIntersectionObserverCxxNativeIntersectionObserverObserveOptions instead.")]] NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptions { P0 intersectionObserverId; P1 targetShadowNode; P2 thresholds; @@ -2600,7 +3532,7 @@ struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptions }; template -struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptionsBridging { +struct [[deprecated("Use NativeIntersectionObserverCxxNativeIntersectionObserverObserveOptionsBridging instead.")]] NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptionsBridging { static NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptions fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -2643,7 +3575,7 @@ struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverObserveOptions #pragma mark - NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntry template -struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntry { +struct [[deprecated("Use NativeIntersectionObserverCxxNativeIntersectionObserverEntry instead.")]] NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntry { P0 intersectionObserverId; P1 targetInstanceHandle; P2 targetRect; @@ -2657,7 +3589,7 @@ struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntry { }; template -struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntryBridging { +struct [[deprecated("Use NativeIntersectionObserverCxxNativeIntersectionObserverEntryBridging instead.")]] NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntryBridging { static NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntry fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -2719,38 +3651,175 @@ struct NativeIntersectionObserverCxxBaseNativeIntersectionObserverEntryBridging } }; -class JSI_EXPORT NativeIntersectionObserverCxxSpecJSI : public TurboModule { -protected: - NativeIntersectionObserverCxxSpecJSI(std::shared_ptr jsInvoker); -public: - virtual void observe(jsi::Runtime &rt, jsi::Object options) = 0; - virtual void unobserve(jsi::Runtime &rt, double intersectionObserverId, jsi::Value targetShadowNode) = 0; - virtual void connect(jsi::Runtime &rt, jsi::Function notifyIntersectionObserversCallback) = 0; - virtual void disconnect(jsi::Runtime &rt) = 0; - virtual jsi::Array takeRecords(jsi::Runtime &rt) = 0; +#pragma mark - NativeIntersectionObserverCxxNativeIntersectionObserverObserveOptions +template +struct NativeIntersectionObserverCxxNativeIntersectionObserverObserveOptions { + P0 intersectionObserverId; + P1 targetShadowNode; + P2 thresholds; + bool operator==(const NativeIntersectionObserverCxxNativeIntersectionObserverObserveOptions &other) const { + return intersectionObserverId == other.intersectionObserverId && targetShadowNode == other.targetShadowNode && thresholds == other.thresholds; + } }; template -class JSI_EXPORT NativeIntersectionObserverCxxSpec : public TurboModule { -public: - jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { - return delegate_.get(rt, propName); - } +struct NativeIntersectionObserverCxxNativeIntersectionObserverObserveOptionsBridging { + static T types; - static constexpr std::string_view kModuleName = "NativeIntersectionObserverCxx"; + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "intersectionObserverId"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "targetShadowNode"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "thresholds"), jsInvoker)}; + return result; + } -protected: - NativeIntersectionObserverCxxSpec(std::shared_ptr jsInvoker) - : TurboModule(std::string{NativeIntersectionObserverCxxSpec::kModuleName}, jsInvoker), - delegate_(reinterpret_cast(this), jsInvoker) {} +#ifdef DEBUG + static double intersectionObserverIdToJs(jsi::Runtime &rt, decltype(types.intersectionObserverId) value) { + return bridging::toJs(rt, value); + } -private: - class Delegate : public NativeIntersectionObserverCxxSpecJSI { - public: - Delegate(T *instance, std::shared_ptr jsInvoker) : - NativeIntersectionObserverCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + static jsi::Value targetShadowNodeToJs(jsi::Runtime &rt, decltype(types.targetShadowNode) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array thresholdsToJs(jsi::Runtime &rt, decltype(types.thresholds) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "intersectionObserverId", bridging::toJs(rt, value.intersectionObserverId, jsInvoker)); + result.setProperty(rt, "targetShadowNode", bridging::toJs(rt, value.targetShadowNode, jsInvoker)); + result.setProperty(rt, "thresholds", bridging::toJs(rt, value.thresholds, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeIntersectionObserverCxxNativeIntersectionObserverEntry + +template +struct NativeIntersectionObserverCxxNativeIntersectionObserverEntry { + P0 intersectionObserverId; + P1 targetInstanceHandle; + P2 targetRect; + P3 rootRect; + P4 intersectionRect; + P5 isIntersectingAboveThresholds; + P6 time; + bool operator==(const NativeIntersectionObserverCxxNativeIntersectionObserverEntry &other) const { + return intersectionObserverId == other.intersectionObserverId && targetInstanceHandle == other.targetInstanceHandle && targetRect == other.targetRect && rootRect == other.rootRect && intersectionRect == other.intersectionRect && isIntersectingAboveThresholds == other.isIntersectingAboveThresholds && time == other.time; + } +}; + +template +struct NativeIntersectionObserverCxxNativeIntersectionObserverEntryBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "intersectionObserverId"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "targetInstanceHandle"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "targetRect"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "rootRect"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "intersectionRect"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isIntersectingAboveThresholds"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "time"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double intersectionObserverIdToJs(jsi::Runtime &rt, decltype(types.intersectionObserverId) value) { + return bridging::toJs(rt, value); + } + + static jsi::Value targetInstanceHandleToJs(jsi::Runtime &rt, decltype(types.targetInstanceHandle) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array targetRectToJs(jsi::Runtime &rt, decltype(types.targetRect) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array rootRectToJs(jsi::Runtime &rt, decltype(types.rootRect) value) { + return bridging::toJs(rt, value); + } + + static std::optional intersectionRectToJs(jsi::Runtime &rt, decltype(types.intersectionRect) value) { + return bridging::toJs(rt, value); + } + + static bool isIntersectingAboveThresholdsToJs(jsi::Runtime &rt, decltype(types.isIntersectingAboveThresholds) value) { + return bridging::toJs(rt, value); + } + + static double timeToJs(jsi::Runtime &rt, decltype(types.time) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "intersectionObserverId", bridging::toJs(rt, value.intersectionObserverId, jsInvoker)); + result.setProperty(rt, "targetInstanceHandle", bridging::toJs(rt, value.targetInstanceHandle, jsInvoker)); + result.setProperty(rt, "targetRect", bridging::toJs(rt, value.targetRect, jsInvoker)); + result.setProperty(rt, "rootRect", bridging::toJs(rt, value.rootRect, jsInvoker)); + result.setProperty(rt, "intersectionRect", bridging::toJs(rt, value.intersectionRect, jsInvoker)); + result.setProperty(rt, "isIntersectingAboveThresholds", bridging::toJs(rt, value.isIntersectingAboveThresholds, jsInvoker)); + result.setProperty(rt, "time", bridging::toJs(rt, value.time, jsInvoker)); + return result; + } +}; + +class JSI_EXPORT NativeIntersectionObserverCxxSpecJSI : public TurboModule { +protected: + NativeIntersectionObserverCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual void observe(jsi::Runtime &rt, jsi::Object options) = 0; + virtual void unobserve(jsi::Runtime &rt, double intersectionObserverId, jsi::Value targetShadowNode) = 0; + virtual void connect(jsi::Runtime &rt, jsi::Function notifyIntersectionObserversCallback) = 0; + virtual void disconnect(jsi::Runtime &rt) = 0; + virtual jsi::Array takeRecords(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeIntersectionObserverCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + + static constexpr std::string_view kModuleName = "NativeIntersectionObserverCxx"; + +protected: + NativeIntersectionObserverCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeIntersectionObserverCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + +private: + class Delegate : public NativeIntersectionObserverCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeIntersectionObserverCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} void observe(jsi::Runtime &rt, jsi::Object options) override { static_assert( @@ -3033,7 +4102,7 @@ class JSI_EXPORT NativeModalManagerCxxSpec : public TurboModule { #pragma mark - NativeMutationObserverCxxBaseNativeMutationObserverObserveOptions template -struct NativeMutationObserverCxxBaseNativeMutationObserverObserveOptions { +struct [[deprecated("Use NativeMutationObserverCxxNativeMutationObserverObserveOptions instead.")]] NativeMutationObserverCxxBaseNativeMutationObserverObserveOptions { P0 mutationObserverId; P1 targetShadowNode; P2 subtree; @@ -3043,7 +4112,7 @@ struct NativeMutationObserverCxxBaseNativeMutationObserverObserveOptions { }; template -struct NativeMutationObserverCxxBaseNativeMutationObserverObserveOptionsBridging { +struct [[deprecated("Use NativeMutationObserverCxxNativeMutationObserverObserveOptionsBridging instead.")]] NativeMutationObserverCxxBaseNativeMutationObserverObserveOptionsBridging { static NativeMutationObserverCxxBaseNativeMutationObserverObserveOptions fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -3086,7 +4155,7 @@ struct NativeMutationObserverCxxBaseNativeMutationObserverObserveOptionsBridging #pragma mark - NativeMutationObserverCxxBaseNativeMutationRecord template -struct NativeMutationObserverCxxBaseNativeMutationRecord { +struct [[deprecated("Use NativeMutationObserverCxxNativeMutationRecord instead.")]] NativeMutationObserverCxxBaseNativeMutationRecord { P0 mutationObserverId; P1 target; P2 addedNodes; @@ -3097,7 +4166,7 @@ struct NativeMutationObserverCxxBaseNativeMutationRecord { }; template -struct NativeMutationObserverCxxBaseNativeMutationRecordBridging { +struct [[deprecated("Use NativeMutationObserverCxxNativeMutationRecordBridging instead.")]] NativeMutationObserverCxxBaseNativeMutationRecordBridging { static NativeMutationObserverCxxBaseNativeMutationRecord fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -3141,6 +4210,122 @@ struct NativeMutationObserverCxxBaseNativeMutationRecordBridging { } }; + +#pragma mark - NativeMutationObserverCxxNativeMutationObserverObserveOptions + +template +struct NativeMutationObserverCxxNativeMutationObserverObserveOptions { + P0 mutationObserverId; + P1 targetShadowNode; + P2 subtree; + bool operator==(const NativeMutationObserverCxxNativeMutationObserverObserveOptions &other) const { + return mutationObserverId == other.mutationObserverId && targetShadowNode == other.targetShadowNode && subtree == other.subtree; + } +}; + +template +struct NativeMutationObserverCxxNativeMutationObserverObserveOptionsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "mutationObserverId"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "targetShadowNode"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "subtree"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double mutationObserverIdToJs(jsi::Runtime &rt, decltype(types.mutationObserverId) value) { + return bridging::toJs(rt, value); + } + + static jsi::Value targetShadowNodeToJs(jsi::Runtime &rt, decltype(types.targetShadowNode) value) { + return bridging::toJs(rt, value); + } + + static bool subtreeToJs(jsi::Runtime &rt, decltype(types.subtree) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "mutationObserverId", bridging::toJs(rt, value.mutationObserverId, jsInvoker)); + result.setProperty(rt, "targetShadowNode", bridging::toJs(rt, value.targetShadowNode, jsInvoker)); + result.setProperty(rt, "subtree", bridging::toJs(rt, value.subtree, jsInvoker)); + return result; + } +}; + + + +#pragma mark - NativeMutationObserverCxxNativeMutationRecord + +template +struct NativeMutationObserverCxxNativeMutationRecord { + P0 mutationObserverId; + P1 target; + P2 addedNodes; + P3 removedNodes; + bool operator==(const NativeMutationObserverCxxNativeMutationRecord &other) const { + return mutationObserverId == other.mutationObserverId && target == other.target && addedNodes == other.addedNodes && removedNodes == other.removedNodes; + } +}; + +template +struct NativeMutationObserverCxxNativeMutationRecordBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "mutationObserverId"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "target"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "addedNodes"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "removedNodes"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double mutationObserverIdToJs(jsi::Runtime &rt, decltype(types.mutationObserverId) value) { + return bridging::toJs(rt, value); + } + + static jsi::Value targetToJs(jsi::Runtime &rt, decltype(types.target) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array addedNodesToJs(jsi::Runtime &rt, decltype(types.addedNodes) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array removedNodesToJs(jsi::Runtime &rt, decltype(types.removedNodes) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "mutationObserverId", bridging::toJs(rt, value.mutationObserverId, jsInvoker)); + result.setProperty(rt, "target", bridging::toJs(rt, value.target, jsInvoker)); + result.setProperty(rt, "addedNodes", bridging::toJs(rt, value.addedNodes, jsInvoker)); + result.setProperty(rt, "removedNodes", bridging::toJs(rt, value.removedNodes, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeMutationObserverCxxSpecJSI : public TurboModule { protected: NativeMutationObserverCxxSpecJSI(std::shared_ptr jsInvoker); @@ -3510,7 +4695,7 @@ class JSI_EXPORT NativePermissionsAndroidCxxSpec : public TurboModule { #pragma mark - PushNotificationManagerBasePermissions template -struct PushNotificationManagerBasePermissions { +struct [[deprecated("Use PushNotificationManagerPermissions instead.")]] PushNotificationManagerBasePermissions { P0 alert; P1 badge; P2 sound; @@ -3520,7 +4705,7 @@ struct PushNotificationManagerBasePermissions { }; template -struct PushNotificationManagerBasePermissionsBridging { +struct [[deprecated("Use PushNotificationManagerPermissionsBridging instead.")]] PushNotificationManagerBasePermissionsBridging { static PushNotificationManagerBasePermissions fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -3563,7 +4748,7 @@ struct PushNotificationManagerBasePermissionsBridging { #pragma mark - PushNotificationManagerBaseNotification template -struct PushNotificationManagerBaseNotification { +struct [[deprecated("Use PushNotificationManagerNotification instead.")]] PushNotificationManagerBaseNotification { P0 alertTitle; P1 alertBody; P2 userInfo; @@ -3581,7 +4766,7 @@ struct PushNotificationManagerBaseNotification { }; template -struct PushNotificationManagerBaseNotificationBridging { +struct [[deprecated("Use PushNotificationManagerNotificationBridging instead.")]] PushNotificationManagerBaseNotificationBridging { static PushNotificationManagerBaseNotification fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -3689,57 +4874,244 @@ struct PushNotificationManagerBaseNotificationBridging { } }; -class JSI_EXPORT NativePushNotificationManagerIOSCxxSpecJSI : public TurboModule { -protected: - NativePushNotificationManagerIOSCxxSpecJSI(std::shared_ptr jsInvoker); -public: - virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; - virtual void onFinishRemoteNotification(jsi::Runtime &rt, jsi::String notificationId, jsi::String fetchResult) = 0; - virtual void setApplicationIconBadgeNumber(jsi::Runtime &rt, double num) = 0; - virtual void getApplicationIconBadgeNumber(jsi::Runtime &rt, jsi::Function callback) = 0; - virtual jsi::Value requestPermissions(jsi::Runtime &rt, jsi::Object permission) = 0; - virtual void abandonPermissions(jsi::Runtime &rt) = 0; - virtual void checkPermissions(jsi::Runtime &rt, jsi::Function callback) = 0; - virtual void presentLocalNotification(jsi::Runtime &rt, jsi::Object notification) = 0; - virtual void scheduleLocalNotification(jsi::Runtime &rt, jsi::Object notification) = 0; - virtual void cancelAllLocalNotifications(jsi::Runtime &rt) = 0; - virtual void cancelLocalNotifications(jsi::Runtime &rt, jsi::Object userInfo) = 0; - virtual jsi::Value getInitialNotification(jsi::Runtime &rt) = 0; - virtual void getScheduledLocalNotifications(jsi::Runtime &rt, jsi::Function callback) = 0; - virtual void removeAllDeliveredNotifications(jsi::Runtime &rt) = 0; - virtual void removeDeliveredNotifications(jsi::Runtime &rt, jsi::Array identifiers) = 0; - virtual void getDeliveredNotifications(jsi::Runtime &rt, jsi::Function callback) = 0; - virtual void getAuthorizationStatus(jsi::Runtime &rt, jsi::Function callback) = 0; - virtual void addListener(jsi::Runtime &rt, jsi::String eventType) = 0; - virtual void removeListeners(jsi::Runtime &rt, double count) = 0; +#pragma mark - PushNotificationManagerPermissions +template +struct PushNotificationManagerPermissions { + P0 alert; + P1 badge; + P2 sound; + bool operator==(const PushNotificationManagerPermissions &other) const { + return alert == other.alert && badge == other.badge && sound == other.sound; + } }; template -class JSI_EXPORT NativePushNotificationManagerIOSCxxSpec : public TurboModule { -public: - jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { - return delegate_.get(rt, propName); - } +struct PushNotificationManagerPermissionsBridging { + static T types; - static constexpr std::string_view kModuleName = "PushNotificationManager"; + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "alert"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "badge"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "sound"), jsInvoker)}; + return result; + } -protected: - NativePushNotificationManagerIOSCxxSpec(std::shared_ptr jsInvoker) - : TurboModule(std::string{NativePushNotificationManagerIOSCxxSpec::kModuleName}, jsInvoker), - delegate_(reinterpret_cast(this), jsInvoker) {} +#ifdef DEBUG + static bool alertToJs(jsi::Runtime &rt, decltype(types.alert) value) { + return bridging::toJs(rt, value); + } -private: - class Delegate : public NativePushNotificationManagerIOSCxxSpecJSI { - public: - Delegate(T *instance, std::shared_ptr jsInvoker) : - NativePushNotificationManagerIOSCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + static bool badgeToJs(jsi::Runtime &rt, decltype(types.badge) value) { + return bridging::toJs(rt, value); + } - jsi::Object getConstants(jsi::Runtime &rt) override { - static_assert( - bridging::getParameterCount(&T::getConstants) == 1, - "Expected getConstants(...) to have 1 parameters"); + static bool soundToJs(jsi::Runtime &rt, decltype(types.sound) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "alert", bridging::toJs(rt, value.alert, jsInvoker)); + result.setProperty(rt, "badge", bridging::toJs(rt, value.badge, jsInvoker)); + result.setProperty(rt, "sound", bridging::toJs(rt, value.sound, jsInvoker)); + return result; + } +}; + + + +#pragma mark - PushNotificationManagerNotification + +template +struct PushNotificationManagerNotification { + P0 alertTitle; + P1 alertBody; + P2 userInfo; + P3 category; + P4 fireDate; + P5 fireIntervalSeconds; + P6 applicationIconBadgeNumber; + P7 isSilent; + P8 soundName; + P9 alertAction; + P10 repeatInterval; + bool operator==(const PushNotificationManagerNotification &other) const { + return alertTitle == other.alertTitle && alertBody == other.alertBody && userInfo == other.userInfo && category == other.category && fireDate == other.fireDate && fireIntervalSeconds == other.fireIntervalSeconds && applicationIconBadgeNumber == other.applicationIconBadgeNumber && isSilent == other.isSilent && soundName == other.soundName && alertAction == other.alertAction && repeatInterval == other.repeatInterval; + } +}; + +template +struct PushNotificationManagerNotificationBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "alertTitle"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "alertBody"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "userInfo"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "category"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fireDate"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fireIntervalSeconds"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "applicationIconBadgeNumber"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isSilent"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "soundName"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "alertAction"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "repeatInterval"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static std::optional alertTitleToJs(jsi::Runtime &rt, decltype(types.alertTitle) value) { + return bridging::toJs(rt, value); + } + + static std::optional alertBodyToJs(jsi::Runtime &rt, decltype(types.alertBody) value) { + return bridging::toJs(rt, value); + } + + static std::optional userInfoToJs(jsi::Runtime &rt, decltype(types.userInfo) value) { + return bridging::toJs(rt, value); + } + + static std::optional categoryToJs(jsi::Runtime &rt, decltype(types.category) value) { + return bridging::toJs(rt, value); + } + + static std::optional fireDateToJs(jsi::Runtime &rt, decltype(types.fireDate) value) { + return bridging::toJs(rt, value); + } + + static std::optional fireIntervalSecondsToJs(jsi::Runtime &rt, decltype(types.fireIntervalSeconds) value) { + return bridging::toJs(rt, value); + } + + static std::optional applicationIconBadgeNumberToJs(jsi::Runtime &rt, decltype(types.applicationIconBadgeNumber) value) { + return bridging::toJs(rt, value); + } + + static std::optional isSilentToJs(jsi::Runtime &rt, decltype(types.isSilent) value) { + return bridging::toJs(rt, value); + } + + static std::optional soundNameToJs(jsi::Runtime &rt, decltype(types.soundName) value) { + return bridging::toJs(rt, value); + } + + static std::optional alertActionToJs(jsi::Runtime &rt, decltype(types.alertAction) value) { + return bridging::toJs(rt, value); + } + + static std::optional repeatIntervalToJs(jsi::Runtime &rt, decltype(types.repeatInterval) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.alertTitle) { + result.setProperty(rt, "alertTitle", bridging::toJs(rt, value.alertTitle.value(), jsInvoker)); + } + if (value.alertBody) { + result.setProperty(rt, "alertBody", bridging::toJs(rt, value.alertBody.value(), jsInvoker)); + } + if (value.userInfo) { + result.setProperty(rt, "userInfo", bridging::toJs(rt, value.userInfo.value(), jsInvoker)); + } + if (value.category) { + result.setProperty(rt, "category", bridging::toJs(rt, value.category.value(), jsInvoker)); + } + if (value.fireDate) { + result.setProperty(rt, "fireDate", bridging::toJs(rt, value.fireDate.value(), jsInvoker)); + } + if (value.fireIntervalSeconds) { + result.setProperty(rt, "fireIntervalSeconds", bridging::toJs(rt, value.fireIntervalSeconds.value(), jsInvoker)); + } + if (value.applicationIconBadgeNumber) { + result.setProperty(rt, "applicationIconBadgeNumber", bridging::toJs(rt, value.applicationIconBadgeNumber.value(), jsInvoker)); + } + if (value.isSilent) { + result.setProperty(rt, "isSilent", bridging::toJs(rt, value.isSilent.value(), jsInvoker)); + } + if (value.soundName) { + result.setProperty(rt, "soundName", bridging::toJs(rt, value.soundName.value(), jsInvoker)); + } + if (value.alertAction) { + result.setProperty(rt, "alertAction", bridging::toJs(rt, value.alertAction.value(), jsInvoker)); + } + if (value.repeatInterval) { + result.setProperty(rt, "repeatInterval", bridging::toJs(rt, value.repeatInterval.value(), jsInvoker)); + } + return result; + } +}; + +class JSI_EXPORT NativePushNotificationManagerIOSCxxSpecJSI : public TurboModule { +protected: + NativePushNotificationManagerIOSCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; + virtual void onFinishRemoteNotification(jsi::Runtime &rt, jsi::String notificationId, jsi::String fetchResult) = 0; + virtual void setApplicationIconBadgeNumber(jsi::Runtime &rt, double num) = 0; + virtual void getApplicationIconBadgeNumber(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual jsi::Value requestPermissions(jsi::Runtime &rt, jsi::Object permission) = 0; + virtual void abandonPermissions(jsi::Runtime &rt) = 0; + virtual void checkPermissions(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual void presentLocalNotification(jsi::Runtime &rt, jsi::Object notification) = 0; + virtual void scheduleLocalNotification(jsi::Runtime &rt, jsi::Object notification) = 0; + virtual void cancelAllLocalNotifications(jsi::Runtime &rt) = 0; + virtual void cancelLocalNotifications(jsi::Runtime &rt, jsi::Object userInfo) = 0; + virtual jsi::Value getInitialNotification(jsi::Runtime &rt) = 0; + virtual void getScheduledLocalNotifications(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual void removeAllDeliveredNotifications(jsi::Runtime &rt) = 0; + virtual void removeDeliveredNotifications(jsi::Runtime &rt, jsi::Array identifiers) = 0; + virtual void getDeliveredNotifications(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual void getAuthorizationStatus(jsi::Runtime &rt, jsi::Function callback) = 0; + virtual void addListener(jsi::Runtime &rt, jsi::String eventType) = 0; + virtual void removeListeners(jsi::Runtime &rt, double count) = 0; + +}; + +template +class JSI_EXPORT NativePushNotificationManagerIOSCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + + static constexpr std::string_view kModuleName = "PushNotificationManager"; + +protected: + NativePushNotificationManagerIOSCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativePushNotificationManagerIOSCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + +private: + class Delegate : public NativePushNotificationManagerIOSCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativePushNotificationManagerIOSCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + + jsi::Object getConstants(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getConstants) == 1, + "Expected getConstants(...) to have 1 parameters"); return bridging::callFromJs( rt, &T::getConstants, jsInvoker_, instance_); @@ -3956,7 +5328,7 @@ class JSI_EXPORT NativeHeadlessJsTaskSupportCxxSpec : public TurboModule { #pragma mark - I18nManagerBaseI18nManagerConstants template -struct I18nManagerBaseI18nManagerConstants { +struct [[deprecated("Use I18nManagerI18nManagerConstants instead.")]] I18nManagerBaseI18nManagerConstants { P0 doLeftAndRightSwapInRTL; P1 isRTL; P2 localeIdentifier; @@ -3966,7 +5338,7 @@ struct I18nManagerBaseI18nManagerConstants { }; template -struct I18nManagerBaseI18nManagerConstantsBridging { +struct [[deprecated("Use I18nManagerI18nManagerConstantsBridging instead.")]] I18nManagerBaseI18nManagerConstantsBridging { static I18nManagerBaseI18nManagerConstants fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -4006,6 +5378,62 @@ struct I18nManagerBaseI18nManagerConstantsBridging { } }; + +#pragma mark - I18nManagerI18nManagerConstants + +template +struct I18nManagerI18nManagerConstants { + P0 doLeftAndRightSwapInRTL; + P1 isRTL; + P2 localeIdentifier; + bool operator==(const I18nManagerI18nManagerConstants &other) const { + return doLeftAndRightSwapInRTL == other.doLeftAndRightSwapInRTL && isRTL == other.isRTL && localeIdentifier == other.localeIdentifier; + } +}; + +template +struct I18nManagerI18nManagerConstantsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "doLeftAndRightSwapInRTL"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isRTL"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "localeIdentifier"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool doLeftAndRightSwapInRTLToJs(jsi::Runtime &rt, decltype(types.doLeftAndRightSwapInRTL) value) { + return bridging::toJs(rt, value); + } + + static bool isRTLToJs(jsi::Runtime &rt, decltype(types.isRTL) value) { + return bridging::toJs(rt, value); + } + + static std::optional localeIdentifierToJs(jsi::Runtime &rt, decltype(types.localeIdentifier) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "doLeftAndRightSwapInRTL", bridging::toJs(rt, value.doLeftAndRightSwapInRTL, jsInvoker)); + result.setProperty(rt, "isRTL", bridging::toJs(rt, value.isRTL, jsInvoker)); + if (value.localeIdentifier) { + result.setProperty(rt, "localeIdentifier", bridging::toJs(rt, value.localeIdentifier.value(), jsInvoker)); + } + return result; + } +}; + class JSI_EXPORT NativeI18nManagerCxxSpecJSI : public TurboModule { protected: NativeI18nManagerCxxSpecJSI(std::shared_ptr jsInvoker); @@ -4546,7 +5974,7 @@ class JSI_EXPORT NativeAppearanceCxxSpec : public TurboModule { #pragma mark - DeviceInfoBaseDisplayMetrics template -struct DeviceInfoBaseDisplayMetrics { +struct [[deprecated("Use DeviceInfoDisplayMetrics instead.")]] DeviceInfoBaseDisplayMetrics { P0 width; P1 height; P2 scale; @@ -4557,7 +5985,7 @@ struct DeviceInfoBaseDisplayMetrics { }; template -struct DeviceInfoBaseDisplayMetricsBridging { +struct [[deprecated("Use DeviceInfoDisplayMetricsBridging instead.")]] DeviceInfoBaseDisplayMetricsBridging { static DeviceInfoBaseDisplayMetrics fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -4606,7 +6034,7 @@ struct DeviceInfoBaseDisplayMetricsBridging { #pragma mark - DeviceInfoBaseDisplayMetricsAndroid template -struct DeviceInfoBaseDisplayMetricsAndroid { +struct [[deprecated("Use DeviceInfoDisplayMetricsAndroid instead.")]] DeviceInfoBaseDisplayMetricsAndroid { P0 width; P1 height; P2 scale; @@ -4618,7 +6046,7 @@ struct DeviceInfoBaseDisplayMetricsAndroid { }; template -struct DeviceInfoBaseDisplayMetricsAndroidBridging { +struct [[deprecated("Use DeviceInfoDisplayMetricsAndroidBridging instead.")]] DeviceInfoBaseDisplayMetricsAndroidBridging { static DeviceInfoBaseDisplayMetricsAndroid fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -4673,7 +6101,7 @@ struct DeviceInfoBaseDisplayMetricsAndroidBridging { #pragma mark - DeviceInfoBaseDimensionsPayload template -struct DeviceInfoBaseDimensionsPayload { +struct [[deprecated("Use DeviceInfoDimensionsPayload instead.")]] DeviceInfoBaseDimensionsPayload { P0 window; P1 screen; P2 windowPhysicalPixels; @@ -4684,7 +6112,7 @@ struct DeviceInfoBaseDimensionsPayload { }; template -struct DeviceInfoBaseDimensionsPayloadBridging { +struct [[deprecated("Use DeviceInfoDimensionsPayloadBridging instead.")]] DeviceInfoBaseDimensionsPayloadBridging { static DeviceInfoBaseDimensionsPayload fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -4741,7 +6169,7 @@ struct DeviceInfoBaseDimensionsPayloadBridging { #pragma mark - DeviceInfoBaseDeviceInfoConstants template -struct DeviceInfoBaseDeviceInfoConstants { +struct [[deprecated("Use DeviceInfoDeviceInfoConstants instead.")]] DeviceInfoBaseDeviceInfoConstants { P0 Dimensions; P1 isIPhoneX_deprecated; bool operator==(const DeviceInfoBaseDeviceInfoConstants &other) const { @@ -4750,7 +6178,7 @@ struct DeviceInfoBaseDeviceInfoConstants { }; template -struct DeviceInfoBaseDeviceInfoConstantsBridging { +struct [[deprecated("Use DeviceInfoDeviceInfoConstantsBridging instead.")]] DeviceInfoBaseDeviceInfoConstantsBridging { static DeviceInfoBaseDeviceInfoConstants fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -4784,43 +6212,293 @@ struct DeviceInfoBaseDeviceInfoConstantsBridging { } }; -class JSI_EXPORT NativeDeviceInfoCxxSpecJSI : public TurboModule { -protected: - NativeDeviceInfoCxxSpecJSI(std::shared_ptr jsInvoker); -public: - virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; +#pragma mark - DeviceInfoDisplayMetrics +template +struct DeviceInfoDisplayMetrics { + P0 width; + P1 height; + P2 scale; + P3 fontScale; + bool operator==(const DeviceInfoDisplayMetrics &other) const { + return width == other.width && height == other.height && scale == other.scale && fontScale == other.fontScale; + } }; template -class JSI_EXPORT NativeDeviceInfoCxxSpec : public TurboModule { -public: - jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { - return delegate_.get(rt, propName); +struct DeviceInfoDisplayMetricsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "width"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "height"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "scale"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fontScale"), jsInvoker)}; + return result; } - static constexpr std::string_view kModuleName = "DeviceInfo"; +#ifdef DEBUG + static double widthToJs(jsi::Runtime &rt, decltype(types.width) value) { + return bridging::toJs(rt, value); + } -protected: - NativeDeviceInfoCxxSpec(std::shared_ptr jsInvoker) - : TurboModule(std::string{NativeDeviceInfoCxxSpec::kModuleName}, jsInvoker), - delegate_(reinterpret_cast(this), jsInvoker) {} + static double heightToJs(jsi::Runtime &rt, decltype(types.height) value) { + return bridging::toJs(rt, value); + } -private: - class Delegate : public NativeDeviceInfoCxxSpecJSI { - public: - Delegate(T *instance, std::shared_ptr jsInvoker) : - NativeDeviceInfoCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + static double scaleToJs(jsi::Runtime &rt, decltype(types.scale) value) { + return bridging::toJs(rt, value); + } - jsi::Object getConstants(jsi::Runtime &rt) override { - static_assert( - bridging::getParameterCount(&T::getConstants) == 1, - "Expected getConstants(...) to have 1 parameters"); + static double fontScaleToJs(jsi::Runtime &rt, decltype(types.fontScale) value) { + return bridging::toJs(rt, value); + } +#endif - return bridging::callFromJs( - rt, &T::getConstants, jsInvoker_, instance_); - } + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "width", bridging::toJs(rt, value.width, jsInvoker)); + result.setProperty(rt, "height", bridging::toJs(rt, value.height, jsInvoker)); + result.setProperty(rt, "scale", bridging::toJs(rt, value.scale, jsInvoker)); + result.setProperty(rt, "fontScale", bridging::toJs(rt, value.fontScale, jsInvoker)); + return result; + } +}; + + + +#pragma mark - DeviceInfoDisplayMetricsAndroid + +template +struct DeviceInfoDisplayMetricsAndroid { + P0 width; + P1 height; + P2 scale; + P3 fontScale; + P4 densityDpi; + bool operator==(const DeviceInfoDisplayMetricsAndroid &other) const { + return width == other.width && height == other.height && scale == other.scale && fontScale == other.fontScale && densityDpi == other.densityDpi; + } +}; + +template +struct DeviceInfoDisplayMetricsAndroidBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "width"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "height"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "scale"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "fontScale"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "densityDpi"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double widthToJs(jsi::Runtime &rt, decltype(types.width) value) { + return bridging::toJs(rt, value); + } + + static double heightToJs(jsi::Runtime &rt, decltype(types.height) value) { + return bridging::toJs(rt, value); + } + + static double scaleToJs(jsi::Runtime &rt, decltype(types.scale) value) { + return bridging::toJs(rt, value); + } + + static double fontScaleToJs(jsi::Runtime &rt, decltype(types.fontScale) value) { + return bridging::toJs(rt, value); + } + + static double densityDpiToJs(jsi::Runtime &rt, decltype(types.densityDpi) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "width", bridging::toJs(rt, value.width, jsInvoker)); + result.setProperty(rt, "height", bridging::toJs(rt, value.height, jsInvoker)); + result.setProperty(rt, "scale", bridging::toJs(rt, value.scale, jsInvoker)); + result.setProperty(rt, "fontScale", bridging::toJs(rt, value.fontScale, jsInvoker)); + result.setProperty(rt, "densityDpi", bridging::toJs(rt, value.densityDpi, jsInvoker)); + return result; + } +}; + + + +#pragma mark - DeviceInfoDimensionsPayload + +template +struct DeviceInfoDimensionsPayload { + P0 window; + P1 screen; + P2 windowPhysicalPixels; + P3 screenPhysicalPixels; + bool operator==(const DeviceInfoDimensionsPayload &other) const { + return window == other.window && screen == other.screen && windowPhysicalPixels == other.windowPhysicalPixels && screenPhysicalPixels == other.screenPhysicalPixels; + } +}; + +template +struct DeviceInfoDimensionsPayloadBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "window"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "screen"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "windowPhysicalPixels"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "screenPhysicalPixels"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object windowToJs(jsi::Runtime &rt, decltype(types.window) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object screenToJs(jsi::Runtime &rt, decltype(types.screen) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object windowPhysicalPixelsToJs(jsi::Runtime &rt, decltype(types.windowPhysicalPixels) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object screenPhysicalPixelsToJs(jsi::Runtime &rt, decltype(types.screenPhysicalPixels) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.window) { + result.setProperty(rt, "window", bridging::toJs(rt, value.window.value(), jsInvoker)); + } + if (value.screen) { + result.setProperty(rt, "screen", bridging::toJs(rt, value.screen.value(), jsInvoker)); + } + if (value.windowPhysicalPixels) { + result.setProperty(rt, "windowPhysicalPixels", bridging::toJs(rt, value.windowPhysicalPixels.value(), jsInvoker)); + } + if (value.screenPhysicalPixels) { + result.setProperty(rt, "screenPhysicalPixels", bridging::toJs(rt, value.screenPhysicalPixels.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - DeviceInfoDeviceInfoConstants + +template +struct DeviceInfoDeviceInfoConstants { + P0 Dimensions; + P1 isIPhoneX_deprecated; + bool operator==(const DeviceInfoDeviceInfoConstants &other) const { + return Dimensions == other.Dimensions && isIPhoneX_deprecated == other.isIPhoneX_deprecated; + } +}; + +template +struct DeviceInfoDeviceInfoConstantsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "Dimensions"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isIPhoneX_deprecated"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Object DimensionsToJs(jsi::Runtime &rt, decltype(types.Dimensions) value) { + return bridging::toJs(rt, value); + } + + static bool isIPhoneX_deprecatedToJs(jsi::Runtime &rt, decltype(types.isIPhoneX_deprecated) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "Dimensions", bridging::toJs(rt, value.Dimensions, jsInvoker)); + if (value.isIPhoneX_deprecated) { + result.setProperty(rt, "isIPhoneX_deprecated", bridging::toJs(rt, value.isIPhoneX_deprecated.value(), jsInvoker)); + } + return result; + } +}; + +class JSI_EXPORT NativeDeviceInfoCxxSpecJSI : public TurboModule { +protected: + NativeDeviceInfoCxxSpecJSI(std::shared_ptr jsInvoker); + +public: + virtual jsi::Object getConstants(jsi::Runtime &rt) = 0; + +}; + +template +class JSI_EXPORT NativeDeviceInfoCxxSpec : public TurboModule { +public: + jsi::Value get(jsi::Runtime &rt, const jsi::PropNameID &propName) override { + return delegate_.get(rt, propName); + } + + static constexpr std::string_view kModuleName = "DeviceInfo"; + +protected: + NativeDeviceInfoCxxSpec(std::shared_ptr jsInvoker) + : TurboModule(std::string{NativeDeviceInfoCxxSpec::kModuleName}, jsInvoker), + delegate_(reinterpret_cast(this), jsInvoker) {} + +private: + class Delegate : public NativeDeviceInfoCxxSpecJSI { + public: + Delegate(T *instance, std::shared_ptr jsInvoker) : + NativeDeviceInfoCxxSpecJSI(std::move(jsInvoker)), instance_(instance) {} + + jsi::Object getConstants(jsi::Runtime &rt) override { + static_assert( + bridging::getParameterCount(&T::getConstants) == 1, + "Expected getConstants(...) to have 1 parameters"); + + return bridging::callFromJs( + rt, &T::getConstants, jsInvoker_, instance_); + } private: T *instance_; @@ -4889,7 +6567,7 @@ class JSI_EXPORT NativeDevLoadingViewCxxSpec : public TurboModule { #pragma mark - PlatformConstantsBaseReactNativeVersionAndroid template -struct PlatformConstantsBaseReactNativeVersionAndroid { +struct [[deprecated("Use PlatformConstantsReactNativeVersionAndroid instead.")]] PlatformConstantsBaseReactNativeVersionAndroid { P0 major; P1 minor; P2 patch; @@ -4900,7 +6578,7 @@ struct PlatformConstantsBaseReactNativeVersionAndroid { }; template -struct PlatformConstantsBaseReactNativeVersionAndroidBridging { +struct [[deprecated("Use PlatformConstantsReactNativeVersionAndroidBridging instead.")]] PlatformConstantsBaseReactNativeVersionAndroidBridging { static PlatformConstantsBaseReactNativeVersionAndroid fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -4949,7 +6627,7 @@ struct PlatformConstantsBaseReactNativeVersionAndroidBridging { #pragma mark - PlatformConstantsBasePlatformConstantsAndroid template -struct PlatformConstantsBasePlatformConstantsAndroid { +struct [[deprecated("Use PlatformConstantsPlatformConstantsAndroid instead.")]] PlatformConstantsBasePlatformConstantsAndroid { P0 isTesting; P1 isDisableAnimations; P2 reactNativeVersion; @@ -4968,7 +6646,7 @@ struct PlatformConstantsBasePlatformConstantsAndroid { }; template -struct PlatformConstantsBasePlatformConstantsAndroidBridging { +struct [[deprecated("Use PlatformConstantsPlatformConstantsAndroidBridging instead.")]] PlatformConstantsBasePlatformConstantsAndroidBridging { static PlatformConstantsBasePlatformConstantsAndroid fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -5064,6 +6742,189 @@ struct PlatformConstantsBasePlatformConstantsAndroidBridging { } }; + +#pragma mark - PlatformConstantsReactNativeVersionAndroid + +template +struct PlatformConstantsReactNativeVersionAndroid { + P0 major; + P1 minor; + P2 patch; + P3 prerelease; + bool operator==(const PlatformConstantsReactNativeVersionAndroid &other) const { + return major == other.major && minor == other.minor && patch == other.patch && prerelease == other.prerelease; + } +}; + +template +struct PlatformConstantsReactNativeVersionAndroidBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "major"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "minor"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "patch"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "prerelease"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static double majorToJs(jsi::Runtime &rt, decltype(types.major) value) { + return bridging::toJs(rt, value); + } + + static double minorToJs(jsi::Runtime &rt, decltype(types.minor) value) { + return bridging::toJs(rt, value); + } + + static double patchToJs(jsi::Runtime &rt, decltype(types.patch) value) { + return bridging::toJs(rt, value); + } + + static std::optional prereleaseToJs(jsi::Runtime &rt, decltype(types.prerelease) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "major", bridging::toJs(rt, value.major, jsInvoker)); + result.setProperty(rt, "minor", bridging::toJs(rt, value.minor, jsInvoker)); + result.setProperty(rt, "patch", bridging::toJs(rt, value.patch, jsInvoker)); + result.setProperty(rt, "prerelease", bridging::toJs(rt, value.prerelease, jsInvoker)); + return result; + } +}; + + + +#pragma mark - PlatformConstantsPlatformConstantsAndroid + +template +struct PlatformConstantsPlatformConstantsAndroid { + P0 isTesting; + P1 isDisableAnimations; + P2 reactNativeVersion; + P3 Version; + P4 Release; + P5 Serial; + P6 Fingerprint; + P7 Model; + P8 ServerHost; + P9 uiMode; + P10 Brand; + P11 Manufacturer; + bool operator==(const PlatformConstantsPlatformConstantsAndroid &other) const { + return isTesting == other.isTesting && isDisableAnimations == other.isDisableAnimations && reactNativeVersion == other.reactNativeVersion && Version == other.Version && Release == other.Release && Serial == other.Serial && Fingerprint == other.Fingerprint && Model == other.Model && ServerHost == other.ServerHost && uiMode == other.uiMode && Brand == other.Brand && Manufacturer == other.Manufacturer; + } +}; + +template +struct PlatformConstantsPlatformConstantsAndroidBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "isTesting"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isDisableAnimations"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "reactNativeVersion"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Version"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Release"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Serial"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Fingerprint"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Model"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "ServerHost"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "uiMode"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Brand"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "Manufacturer"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool isTestingToJs(jsi::Runtime &rt, decltype(types.isTesting) value) { + return bridging::toJs(rt, value); + } + + static bool isDisableAnimationsToJs(jsi::Runtime &rt, decltype(types.isDisableAnimations) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object reactNativeVersionToJs(jsi::Runtime &rt, decltype(types.reactNativeVersion) value) { + return bridging::toJs(rt, value); + } + + static double VersionToJs(jsi::Runtime &rt, decltype(types.Version) value) { + return bridging::toJs(rt, value); + } + + static jsi::String ReleaseToJs(jsi::Runtime &rt, decltype(types.Release) value) { + return bridging::toJs(rt, value); + } + + static jsi::String SerialToJs(jsi::Runtime &rt, decltype(types.Serial) value) { + return bridging::toJs(rt, value); + } + + static jsi::String FingerprintToJs(jsi::Runtime &rt, decltype(types.Fingerprint) value) { + return bridging::toJs(rt, value); + } + + static jsi::String ModelToJs(jsi::Runtime &rt, decltype(types.Model) value) { + return bridging::toJs(rt, value); + } + + static jsi::String ServerHostToJs(jsi::Runtime &rt, decltype(types.ServerHost) value) { + return bridging::toJs(rt, value); + } + + static jsi::String uiModeToJs(jsi::Runtime &rt, decltype(types.uiMode) value) { + return bridging::toJs(rt, value); + } + + static jsi::String BrandToJs(jsi::Runtime &rt, decltype(types.Brand) value) { + return bridging::toJs(rt, value); + } + + static jsi::String ManufacturerToJs(jsi::Runtime &rt, decltype(types.Manufacturer) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "isTesting", bridging::toJs(rt, value.isTesting, jsInvoker)); + if (value.isDisableAnimations) { + result.setProperty(rt, "isDisableAnimations", bridging::toJs(rt, value.isDisableAnimations.value(), jsInvoker)); + } + result.setProperty(rt, "reactNativeVersion", bridging::toJs(rt, value.reactNativeVersion, jsInvoker)); + result.setProperty(rt, "Version", bridging::toJs(rt, value.Version, jsInvoker)); + result.setProperty(rt, "Release", bridging::toJs(rt, value.Release, jsInvoker)); + result.setProperty(rt, "Serial", bridging::toJs(rt, value.Serial, jsInvoker)); + result.setProperty(rt, "Fingerprint", bridging::toJs(rt, value.Fingerprint, jsInvoker)); + result.setProperty(rt, "Model", bridging::toJs(rt, value.Model, jsInvoker)); + if (value.ServerHost) { + result.setProperty(rt, "ServerHost", bridging::toJs(rt, value.ServerHost.value(), jsInvoker)); + } + result.setProperty(rt, "uiMode", bridging::toJs(rt, value.uiMode, jsInvoker)); + result.setProperty(rt, "Brand", bridging::toJs(rt, value.Brand, jsInvoker)); + result.setProperty(rt, "Manufacturer", bridging::toJs(rt, value.Manufacturer, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativePlatformConstantsAndroidCxxSpecJSI : public TurboModule { protected: NativePlatformConstantsAndroidCxxSpecJSI(std::shared_ptr jsInvoker); @@ -5123,7 +6984,7 @@ class JSI_EXPORT NativePlatformConstantsAndroidCxxSpec : public TurboModule { #pragma mark - PlatformConstantsBasePlatformConstantsIOS template -struct PlatformConstantsBasePlatformConstantsIOS { +struct [[deprecated("Use PlatformConstantsPlatformConstantsIOS instead.")]] PlatformConstantsBasePlatformConstantsIOS { P0 isTesting; P1 isDisableAnimations; P2 reactNativeVersion; @@ -5138,7 +6999,7 @@ struct PlatformConstantsBasePlatformConstantsIOS { }; template -struct PlatformConstantsBasePlatformConstantsIOSBridging { +struct [[deprecated("Use PlatformConstantsPlatformConstantsIOSBridging instead.")]] PlatformConstantsBasePlatformConstantsIOSBridging { static PlatformConstantsBasePlatformConstantsIOS fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -5180,18 +7041,111 @@ struct PlatformConstantsBasePlatformConstantsIOSBridging { return bridging::toJs(rt, value); } - static jsi::String interfaceIdiomToJs(jsi::Runtime &rt, P6 value) { + static jsi::String interfaceIdiomToJs(jsi::Runtime &rt, P6 value) { + return bridging::toJs(rt, value); + } + + static bool isMacCatalystToJs(jsi::Runtime &rt, P7 value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const PlatformConstantsBasePlatformConstantsIOS &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "isTesting", bridging::toJs(rt, value.isTesting, jsInvoker)); + if (value.isDisableAnimations) { + result.setProperty(rt, "isDisableAnimations", bridging::toJs(rt, value.isDisableAnimations.value(), jsInvoker)); + } + result.setProperty(rt, "reactNativeVersion", bridging::toJs(rt, value.reactNativeVersion, jsInvoker)); + result.setProperty(rt, "forceTouchAvailable", bridging::toJs(rt, value.forceTouchAvailable, jsInvoker)); + result.setProperty(rt, "osVersion", bridging::toJs(rt, value.osVersion, jsInvoker)); + result.setProperty(rt, "systemName", bridging::toJs(rt, value.systemName, jsInvoker)); + result.setProperty(rt, "interfaceIdiom", bridging::toJs(rt, value.interfaceIdiom, jsInvoker)); + if (value.isMacCatalyst) { + result.setProperty(rt, "isMacCatalyst", bridging::toJs(rt, value.isMacCatalyst.value(), jsInvoker)); + } + return result; + } +}; + + +#pragma mark - PlatformConstantsPlatformConstantsIOS + +template +struct PlatformConstantsPlatformConstantsIOS { + P0 isTesting; + P1 isDisableAnimations; + P2 reactNativeVersion; + P3 forceTouchAvailable; + P4 osVersion; + P5 systemName; + P6 interfaceIdiom; + P7 isMacCatalyst; + bool operator==(const PlatformConstantsPlatformConstantsIOS &other) const { + return isTesting == other.isTesting && isDisableAnimations == other.isDisableAnimations && reactNativeVersion == other.reactNativeVersion && forceTouchAvailable == other.forceTouchAvailable && osVersion == other.osVersion && systemName == other.systemName && interfaceIdiom == other.interfaceIdiom && isMacCatalyst == other.isMacCatalyst; + } +}; + +template +struct PlatformConstantsPlatformConstantsIOSBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "isTesting"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isDisableAnimations"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "reactNativeVersion"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "forceTouchAvailable"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "osVersion"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "systemName"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "interfaceIdiom"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isMacCatalyst"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool isTestingToJs(jsi::Runtime &rt, decltype(types.isTesting) value) { + return bridging::toJs(rt, value); + } + + static bool isDisableAnimationsToJs(jsi::Runtime &rt, decltype(types.isDisableAnimations) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object reactNativeVersionToJs(jsi::Runtime &rt, decltype(types.reactNativeVersion) value) { + return bridging::toJs(rt, value); + } + + static bool forceTouchAvailableToJs(jsi::Runtime &rt, decltype(types.forceTouchAvailable) value) { + return bridging::toJs(rt, value); + } + + static jsi::String osVersionToJs(jsi::Runtime &rt, decltype(types.osVersion) value) { + return bridging::toJs(rt, value); + } + + static jsi::String systemNameToJs(jsi::Runtime &rt, decltype(types.systemName) value) { + return bridging::toJs(rt, value); + } + + static jsi::String interfaceIdiomToJs(jsi::Runtime &rt, decltype(types.interfaceIdiom) value) { return bridging::toJs(rt, value); } - static bool isMacCatalystToJs(jsi::Runtime &rt, P7 value) { + static bool isMacCatalystToJs(jsi::Runtime &rt, decltype(types.isMacCatalyst) value) { return bridging::toJs(rt, value); } #endif static jsi::Object toJs( jsi::Runtime &rt, - const PlatformConstantsBasePlatformConstantsIOS &value, + const T &value, const std::shared_ptr &jsInvoker) { auto result = facebook::jsi::Object(rt); result.setProperty(rt, "isTesting", bridging::toJs(rt, value.isTesting, jsInvoker)); @@ -5260,7 +7214,7 @@ class JSI_EXPORT NativePlatformConstantsIOSCxxSpec : public TurboModule { #pragma mark - PlatformConstantsBasePlatformConstantsWindows template -struct PlatformConstantsBasePlatformConstantsWindows { +struct [[deprecated("Use PlatformConstantsPlatformConstantsWindows instead.")]] PlatformConstantsBasePlatformConstantsWindows { P0 isTesting; P1 isDisableAnimations; P2 reactNativeVersion; @@ -5271,7 +7225,7 @@ struct PlatformConstantsBasePlatformConstantsWindows { }; template -struct PlatformConstantsBasePlatformConstantsWindowsBridging { +struct [[deprecated("Use PlatformConstantsPlatformConstantsWindowsBridging instead.")]] PlatformConstantsBasePlatformConstantsWindowsBridging { static PlatformConstantsBasePlatformConstantsWindows fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -5317,6 +7271,69 @@ struct PlatformConstantsBasePlatformConstantsWindowsBridging { } }; + +#pragma mark - PlatformConstantsPlatformConstantsWindows + +template +struct PlatformConstantsPlatformConstantsWindows { + P0 isTesting; + P1 isDisableAnimations; + P2 reactNativeVersion; + P3 osVersion; + bool operator==(const PlatformConstantsPlatformConstantsWindows &other) const { + return isTesting == other.isTesting && isDisableAnimations == other.isDisableAnimations && reactNativeVersion == other.reactNativeVersion && osVersion == other.osVersion; + } +}; + +template +struct PlatformConstantsPlatformConstantsWindowsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "isTesting"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "isDisableAnimations"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "reactNativeVersion"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "osVersion"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static bool isTestingToJs(jsi::Runtime &rt, decltype(types.isTesting) value) { + return bridging::toJs(rt, value); + } + + static bool isDisableAnimationsToJs(jsi::Runtime &rt, decltype(types.isDisableAnimations) value) { + return bridging::toJs(rt, value); + } + + static jsi::Object reactNativeVersionToJs(jsi::Runtime &rt, decltype(types.reactNativeVersion) value) { + return bridging::toJs(rt, value); + } + + static double osVersionToJs(jsi::Runtime &rt, decltype(types.osVersion) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "isTesting", bridging::toJs(rt, value.isTesting, jsInvoker)); + if (value.isDisableAnimations) { + result.setProperty(rt, "isDisableAnimations", bridging::toJs(rt, value.isDisableAnimations.value(), jsInvoker)); + } + result.setProperty(rt, "reactNativeVersion", bridging::toJs(rt, value.reactNativeVersion, jsInvoker)); + result.setProperty(rt, "osVersion", bridging::toJs(rt, value.osVersion, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativePlatformConstantsWinCxxSpecJSI : public TurboModule { protected: NativePlatformConstantsWinCxxSpecJSI(std::shared_ptr jsInvoker); @@ -5513,7 +7530,7 @@ class JSI_EXPORT NativePerformanceCxxSpec : public TurboModule { #pragma mark - NativePerformanceObserverCxxBaseRawPerformanceEntry template -struct NativePerformanceObserverCxxBaseRawPerformanceEntry { +struct [[deprecated("Use NativePerformanceObserverCxxRawPerformanceEntry instead.")]] NativePerformanceObserverCxxBaseRawPerformanceEntry { P0 name; P1 entryType; P2 startTime; @@ -5527,7 +7544,7 @@ struct NativePerformanceObserverCxxBaseRawPerformanceEntry { }; template -struct NativePerformanceObserverCxxBaseRawPerformanceEntryBridging { +struct [[deprecated("Use NativePerformanceObserverCxxRawPerformanceEntryBridging instead.")]] NativePerformanceObserverCxxBaseRawPerformanceEntryBridging { static NativePerformanceObserverCxxBaseRawPerformanceEntry fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -5600,7 +7617,7 @@ struct NativePerformanceObserverCxxBaseRawPerformanceEntryBridging { #pragma mark - NativePerformanceObserverCxxBaseGetPendingEntriesResult template -struct NativePerformanceObserverCxxBaseGetPendingEntriesResult { +struct [[deprecated("Use NativePerformanceObserverCxxGetPendingEntriesResult instead.")]] NativePerformanceObserverCxxBaseGetPendingEntriesResult { P0 entries; P1 droppedEntriesCount; bool operator==(const NativePerformanceObserverCxxBaseGetPendingEntriesResult &other) const { @@ -5609,7 +7626,7 @@ struct NativePerformanceObserverCxxBaseGetPendingEntriesResult { }; template -struct NativePerformanceObserverCxxBaseGetPendingEntriesResultBridging { +struct [[deprecated("Use NativePerformanceObserverCxxGetPendingEntriesResultBridging instead.")]] NativePerformanceObserverCxxBaseGetPendingEntriesResultBridging { static NativePerformanceObserverCxxBaseGetPendingEntriesResult fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -5641,6 +7658,142 @@ struct NativePerformanceObserverCxxBaseGetPendingEntriesResultBridging { } }; + +#pragma mark - NativePerformanceObserverCxxRawPerformanceEntry + +template +struct NativePerformanceObserverCxxRawPerformanceEntry { + P0 name; + P1 entryType; + P2 startTime; + P3 duration; + P4 processingStart; + P5 processingEnd; + P6 interactionId; + bool operator==(const NativePerformanceObserverCxxRawPerformanceEntry &other) const { + return name == other.name && entryType == other.entryType && startTime == other.startTime && duration == other.duration && processingStart == other.processingStart && processingEnd == other.processingEnd && interactionId == other.interactionId; + } +}; + +template +struct NativePerformanceObserverCxxRawPerformanceEntryBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "name"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "entryType"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "startTime"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "duration"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "processingStart"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "processingEnd"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "interactionId"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String nameToJs(jsi::Runtime &rt, decltype(types.name) value) { + return bridging::toJs(rt, value); + } + + static double entryTypeToJs(jsi::Runtime &rt, decltype(types.entryType) value) { + return bridging::toJs(rt, value); + } + + static double startTimeToJs(jsi::Runtime &rt, decltype(types.startTime) value) { + return bridging::toJs(rt, value); + } + + static double durationToJs(jsi::Runtime &rt, decltype(types.duration) value) { + return bridging::toJs(rt, value); + } + + static double processingStartToJs(jsi::Runtime &rt, decltype(types.processingStart) value) { + return bridging::toJs(rt, value); + } + + static double processingEndToJs(jsi::Runtime &rt, decltype(types.processingEnd) value) { + return bridging::toJs(rt, value); + } + + static double interactionIdToJs(jsi::Runtime &rt, decltype(types.interactionId) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "name", bridging::toJs(rt, value.name, jsInvoker)); + result.setProperty(rt, "entryType", bridging::toJs(rt, value.entryType, jsInvoker)); + result.setProperty(rt, "startTime", bridging::toJs(rt, value.startTime, jsInvoker)); + result.setProperty(rt, "duration", bridging::toJs(rt, value.duration, jsInvoker)); + if (value.processingStart) { + result.setProperty(rt, "processingStart", bridging::toJs(rt, value.processingStart.value(), jsInvoker)); + } + if (value.processingEnd) { + result.setProperty(rt, "processingEnd", bridging::toJs(rt, value.processingEnd.value(), jsInvoker)); + } + if (value.interactionId) { + result.setProperty(rt, "interactionId", bridging::toJs(rt, value.interactionId.value(), jsInvoker)); + } + return result; + } +}; + + + +#pragma mark - NativePerformanceObserverCxxGetPendingEntriesResult + +template +struct NativePerformanceObserverCxxGetPendingEntriesResult { + P0 entries; + P1 droppedEntriesCount; + bool operator==(const NativePerformanceObserverCxxGetPendingEntriesResult &other) const { + return entries == other.entries && droppedEntriesCount == other.droppedEntriesCount; + } +}; + +template +struct NativePerformanceObserverCxxGetPendingEntriesResultBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "entries"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "droppedEntriesCount"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::Array entriesToJs(jsi::Runtime &rt, decltype(types.entries) value) { + return bridging::toJs(rt, value); + } + + static double droppedEntriesCountToJs(jsi::Runtime &rt, decltype(types.droppedEntriesCount) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "entries", bridging::toJs(rt, value.entries, jsInvoker)); + result.setProperty(rt, "droppedEntriesCount", bridging::toJs(rt, value.droppedEntriesCount, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativePerformanceObserverCxxSpecJSI : public TurboModule { protected: NativePerformanceObserverCxxSpecJSI(std::shared_ptr jsInvoker); @@ -6966,7 +9119,7 @@ class JSI_EXPORT NativeDevSettingsCxxSpec : public TurboModule { #pragma mark - DialogManagerAndroidBaseDialogOptions template -struct DialogManagerAndroidBaseDialogOptions { +struct [[deprecated("Use DialogManagerAndroidDialogOptions instead.")]] DialogManagerAndroidBaseDialogOptions { P0 title; P1 message; P2 buttonPositive; @@ -6980,7 +9133,7 @@ struct DialogManagerAndroidBaseDialogOptions { }; template -struct DialogManagerAndroidBaseDialogOptionsBridging { +struct [[deprecated("Use DialogManagerAndroidDialogOptionsBridging instead.")]] DialogManagerAndroidBaseDialogOptionsBridging { static DialogManagerAndroidBaseDialogOptions fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -7056,6 +9209,102 @@ struct DialogManagerAndroidBaseDialogOptionsBridging { } }; + +#pragma mark - DialogManagerAndroidDialogOptions + +template +struct DialogManagerAndroidDialogOptions { + P0 title; + P1 message; + P2 buttonPositive; + P3 buttonNegative; + P4 buttonNeutral; + P5 items; + P6 cancelable; + bool operator==(const DialogManagerAndroidDialogOptions &other) const { + return title == other.title && message == other.message && buttonPositive == other.buttonPositive && buttonNegative == other.buttonNegative && buttonNeutral == other.buttonNeutral && items == other.items && cancelable == other.cancelable; + } +}; + +template +struct DialogManagerAndroidDialogOptionsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "title"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "message"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttonPositive"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttonNegative"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "buttonNeutral"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "items"), jsInvoker), + bridging::fromJs(rt, value.getProperty(rt, "cancelable"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String titleToJs(jsi::Runtime &rt, decltype(types.title) value) { + return bridging::toJs(rt, value); + } + + static jsi::String messageToJs(jsi::Runtime &rt, decltype(types.message) value) { + return bridging::toJs(rt, value); + } + + static jsi::String buttonPositiveToJs(jsi::Runtime &rt, decltype(types.buttonPositive) value) { + return bridging::toJs(rt, value); + } + + static jsi::String buttonNegativeToJs(jsi::Runtime &rt, decltype(types.buttonNegative) value) { + return bridging::toJs(rt, value); + } + + static jsi::String buttonNeutralToJs(jsi::Runtime &rt, decltype(types.buttonNeutral) value) { + return bridging::toJs(rt, value); + } + + static jsi::Array itemsToJs(jsi::Runtime &rt, decltype(types.items) value) { + return bridging::toJs(rt, value); + } + + static bool cancelableToJs(jsi::Runtime &rt, decltype(types.cancelable) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + if (value.title) { + result.setProperty(rt, "title", bridging::toJs(rt, value.title.value(), jsInvoker)); + } + if (value.message) { + result.setProperty(rt, "message", bridging::toJs(rt, value.message.value(), jsInvoker)); + } + if (value.buttonPositive) { + result.setProperty(rt, "buttonPositive", bridging::toJs(rt, value.buttonPositive.value(), jsInvoker)); + } + if (value.buttonNegative) { + result.setProperty(rt, "buttonNegative", bridging::toJs(rt, value.buttonNegative.value(), jsInvoker)); + } + if (value.buttonNeutral) { + result.setProperty(rt, "buttonNeutral", bridging::toJs(rt, value.buttonNeutral.value(), jsInvoker)); + } + if (value.items) { + result.setProperty(rt, "items", bridging::toJs(rt, value.items.value(), jsInvoker)); + } + if (value.cancelable) { + result.setProperty(rt, "cancelable", bridging::toJs(rt, value.cancelable.value(), jsInvoker)); + } + return result; + } +}; + class JSI_EXPORT NativeDialogManagerAndroidCxxSpecJSI : public TurboModule { protected: NativeDialogManagerAndroidCxxSpecJSI(std::shared_ptr jsInvoker); @@ -7225,7 +9474,7 @@ class JSI_EXPORT NativeRedBoxCxxSpec : public TurboModule { #pragma mark - SourceCodeBaseSourceCodeConstants template -struct SourceCodeBaseSourceCodeConstants { +struct [[deprecated("Use SourceCodeSourceCodeConstants instead.")]] SourceCodeBaseSourceCodeConstants { P0 scriptURL; bool operator==(const SourceCodeBaseSourceCodeConstants &other) const { return scriptURL == other.scriptURL; @@ -7233,7 +9482,7 @@ struct SourceCodeBaseSourceCodeConstants { }; template -struct SourceCodeBaseSourceCodeConstantsBridging { +struct [[deprecated("Use SourceCodeSourceCodeConstantsBridging instead.")]] SourceCodeBaseSourceCodeConstantsBridging { static SourceCodeBaseSourceCodeConstants fromJs( jsi::Runtime &rt, const jsi::Object &value, @@ -7259,6 +9508,46 @@ struct SourceCodeBaseSourceCodeConstantsBridging { } }; + +#pragma mark - SourceCodeSourceCodeConstants + +template +struct SourceCodeSourceCodeConstants { + P0 scriptURL; + bool operator==(const SourceCodeSourceCodeConstants &other) const { + return scriptURL == other.scriptURL; + } +}; + +template +struct SourceCodeSourceCodeConstantsBridging { + static T types; + + static T fromJs( + jsi::Runtime &rt, + const jsi::Object &value, + const std::shared_ptr &jsInvoker) { + T result{ + bridging::fromJs(rt, value.getProperty(rt, "scriptURL"), jsInvoker)}; + return result; + } + +#ifdef DEBUG + static jsi::String scriptURLToJs(jsi::Runtime &rt, decltype(types.scriptURL) value) { + return bridging::toJs(rt, value); + } +#endif + + static jsi::Object toJs( + jsi::Runtime &rt, + const T &value, + const std::shared_ptr &jsInvoker) { + auto result = facebook::jsi::Object(rt); + result.setProperty(rt, "scriptURL", bridging::toJs(rt, value.scriptURL, jsInvoker)); + return result; + } +}; + class JSI_EXPORT NativeSourceCodeCxxSpecJSI : public TurboModule { protected: NativeSourceCodeCxxSpecJSI(std::shared_ptr jsInvoker); diff --git a/vnext/overrides.json b/vnext/overrides.json index c027aeb0dd7..0a957f257f1 100644 --- a/vnext/overrides.json +++ b/vnext/overrides.json @@ -8,42 +8,42 @@ "**/__snapshots__/**", "src/rntypes/**" ], - "baseVersion": "0.74.0-nightly-20231124-c464b215e", + "baseVersion": "0.74.0-nightly-20231201-c30f2b620", "overrides": [ { "type": "derived", "file": ".flowconfig", "baseFile": ".flowconfig", - "baseHash": "397a9d59e4415e8758adc635d5e016070e6d85d7" + "baseHash": "172a4663d9243a77e3b35a2d8a5e403fd62062cf" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputComponentDescriptor.h", - "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputComponentDescriptor.h", - "baseHash": "09b2d135a48cde87cd3a7da28cbf1648ce840fc4" + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputComponentDescriptor.h", + "baseHash": "59a160335ced7e8d4159d5bde94b113bf533e1ab" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.cpp", - "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.cpp", "baseHash": "e43e6cb2df75b8f51422bdbef42e99f2c4f2018d" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputShadowNode.h", - "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.h", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputShadowNode.h", "baseHash": "10cd4b533faa9503f7957fca6c9d282e1d432d48" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.cpp", - "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.cpp", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputState.cpp", "baseHash": "e5fe1ab887bc6fdd353548276ccf414b11f35c61" }, { "type": "derived", "file": "Microsoft.ReactNative/Fabric/Composition/TextInput/WindowsTextInputState.h", - "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/androidtextinput/react/renderer/components/androidtextinput/AndroidTextInputState.h", + "baseFile": "packages/react-native/ReactCommon/react/renderer/components/textinput/platform/android/react/renderer/components/androidtextinput/AndroidTextInputState.h", "baseHash": "e0cb62818f80a458ef28430a08a6a685805d3a91" }, { @@ -59,11 +59,25 @@ "baseHash": "4a707c9cab0c6534094cd303e000265b664f05b4", "issue": 7821 }, + { + "type": "copy", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp", + "baseFile": "packages/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp", + "baseHash": "989722b8812d05adfc0f5e4c8dcbf42ab6026a7f", + "issue": 12210 + }, + { + "type": "copy", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h", + "baseFile": "packages/react-native/ReactCommon/jsi/jsi/JSIDynamic.h", + "baseHash": "b3df8b8ce255b2d11184ba705407cb399c121a87", + "issue": 12210 + }, { "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/test/testlib.cpp", "baseFile": "packages/react-native/ReactCommon/jsi/jsi/test/testlib.cpp", - "baseHash": "224ddd5bc92672790e8875bf3078f0529aca05d0", + "baseHash": "daa77a3a77ebd409fde7133d9ab40a2efe5ab31b", "issue": 12210 }, { @@ -161,14 +175,14 @@ "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h", "baseFile": "packages/react-native/ReactCommon/yoga/yoga/node/LayoutResults.h", - "baseHash": "052aadf02af395a25cea6703538e730e2c714cd6", + "baseHash": "f0a011a4eb145be9d85a01746d70ca2a6bfe66d1", "issue": 12195 }, { "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/Node.h", "baseFile": "packages/react-native/ReactCommon/yoga/yoga/node/Node.h", - "baseHash": "c40a83f59704ffd6783cba257421aee668b681ad", + "baseHash": "aaf16b9303a01ca3dc4955061d97ef9577d8b5e7", "issue": 12195 }, { @@ -345,13 +359,13 @@ "type": "derived", "file": "src/Libraries/Components/Switch/Switch.windows.js", "baseFile": "packages/react-native/Libraries/Components/Switch/Switch.js", - "baseHash": "e34649d5441548e6c8c55ebefb472048480ecc4c" + "baseHash": "31b8cd62b5acb1a237f5373d1618869f5afebdd3" }, { "type": "patch", "file": "src/Libraries/Components/TextInput/TextInput.windows.js", "baseFile": "packages/react-native/Libraries/Components/TextInput/TextInput.js", - "baseHash": "fa10fcf147f79ede6f3a49fac45faefed48e1693" + "baseHash": "f6742637eda13080bd175a45eb0edbc83fa260c5" }, { "type": "patch", diff --git a/vnext/package.json b/vnext/package.json index a9eca1ebb2e..30d69b636f4 100644 --- a/vnext/package.json +++ b/vnext/package.json @@ -28,13 +28,13 @@ "@react-native-community/cli-platform-ios": "12.0.0", "@react-native-windows/cli": "0.0.0-canary.194", "@react-native/assets": "1.0.0", - "@react-native/assets-registry": "0.74.0-nightly-20231124-c464b215e", - "@react-native/codegen": "0.74.0-nightly-20231124-c464b215e", - "@react-native/community-cli-plugin": "0.74.0-nightly-20231124-c464b215e", - "@react-native/gradle-plugin": "0.74.0-nightly-20231124-c464b215e", - "@react-native/js-polyfills": "0.74.0-nightly-20231124-c464b215e", - "@react-native/normalize-colors": "0.74.0-nightly-20231124-c464b215e", - "@react-native/virtualized-lists": "0.74.0-nightly-20231124-c464b215e", + "@react-native/assets-registry": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/codegen": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/community-cli-plugin": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/gradle-plugin": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/js-polyfills": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/normalize-colors": "0.74.0-nightly-20231201-c30f2b620", + "@react-native/virtualized-lists": "0.74.0-nightly-20231201-c30f2b620", "abort-controller": "^3.0.0", "anser": "^1.4.9", "ansi-regex": "^5.0.0", @@ -81,14 +81,14 @@ "just-scripts": "^1.3.3", "prettier": "^2.4.1", "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e", + "react-native": "0.74.0-nightly-20231201-c30f2b620", "react-native-platform-override": "^1.9.17", "react-refresh": "^0.4.0", "typescript": "^4.9.5" }, "peerDependencies": { "react": "18.2.0", - "react-native": "0.74.0-nightly-20231124-c464b215e" + "react-native": "0.74.0-nightly-20231201-c30f2b620" }, "beachball": { "defaultNpmTag": "canary", diff --git a/vnext/src/Libraries/Components/Switch/Switch.windows.js b/vnext/src/Libraries/Components/Switch/Switch.windows.js index a516819513c..d1c83cf33b0 100644 --- a/vnext/src/Libraries/Components/Switch/Switch.windows.js +++ b/vnext/src/Libraries/Components/Switch/Switch.windows.js @@ -156,7 +156,6 @@ const SwitchWithForwardedRef: React.AbstractComponent< typeof SwitchNativeComponent | typeof AndroidSwitchNativeComponent, > | null>(null); - // $FlowFixMe[incompatible-call] const ref = useMergeRefs(nativeSwitchRef, forwardedRef); const [native, setNative] = React.useState({value: (null: ?boolean)}); diff --git a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js index bc24b1b97fe..114b087f2d0 100644 --- a/vnext/src/Libraries/Components/TextInput/TextInput.windows.js +++ b/vnext/src/Libraries/Components/TextInput/TextInput.windows.js @@ -1370,10 +1370,7 @@ function InternalTextInput(props: Props): React.Node { [mostRecentEventCount, viewCommands], ); - const ref = useMergeRefs( - setLocalRef, - props.forwardedRef, - ); + const ref = useMergeRefs(setLocalRef, props.forwardedRef); const _onChange = (event: ChangeEvent) => { const currentText = event.nativeEvent.text; diff --git a/yarn.lock b/yarn.lock index 4e9fb9dbcdc..9ae7671e4de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2404,10 +2404,10 @@ resolved "https://registry.yarnpkg.com/@react-native-picker/picker/-/picker-2.6.1.tgz#3b20ddd1385fab0487db103dc6519570f8892e6d" integrity sha512-oJftvmLOj6Y6/bF4kPcK6L83yNBALGmqNYugf94BzP0FQGpHBwimVN2ygqkQ2Sn2ZU3pGUZMs0jV6+Gku2GyYg== -"@react-native/assets-registry@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.0-nightly-20231124-c464b215e.tgz#13e3ea91d218ab11fc7b76a05bbad5db407f0cfc" - integrity sha512-S6bBzs8fKR0SH87SAIAqGvWhh1//VukTSqQRdEOcHr1qYrspECNGZ4zA0Y9DpTzCUhZK36W6YaDjWZTPS+XZAw== +"@react-native/assets-registry@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/assets-registry/-/assets-registry-0.74.0-nightly-20231201-c30f2b620.tgz#0497d39350236615ca81069b096c173a53b5bed2" + integrity sha512-ZeTg2R7KqaJwnWEcW0zF9zfb/ryFbl57CDBgvcqsYVACrBD2vt4S5VTOz0YDiECUicN7Iha8PY3/28/oxJJ5Yw== "@react-native/assets@1.0.0": version "1.0.0" @@ -2421,12 +2421,12 @@ dependencies: "@react-native/codegen" "*" -"@react-native/babel-plugin-codegen@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.0-nightly-20231124-c464b215e.tgz#71e0c3b58aaee75d4d18978a381deabcf1f2152e" - integrity sha512-VogsexG5kpx1SYSiGITBI9Gcd9Wcc9p7JTsKnW4peFZrxqabCvmuTeiCk47vsp2Go4DuN2ljWU23GVPTTnGQIQ== +"@react-native/babel-plugin-codegen@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/babel-plugin-codegen/-/babel-plugin-codegen-0.74.0-nightly-20231201-c30f2b620.tgz#323340c0c115dbfed55b62ed31c8f53cd243e17c" + integrity sha512-vHYC4nXelVCYo88SwZbApFICuXCiPKcz/h1cO0BE93x7N7ZhoPSaAZl8mmR/P2dcHzTI5plQth8SFhAEgFn+vA== dependencies: - "@react-native/codegen" "0.74.0-nightly-20231124-c464b215e" + "@react-native/codegen" "0.74.0-nightly-20231201-c30f2b620" "@react-native/babel-preset@*", "@react-native/babel-preset@0.73.16": version "0.73.16" @@ -2474,10 +2474,10 @@ babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.4.0" -"@react-native/babel-preset@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.0-nightly-20231124-c464b215e.tgz#06d7719e774dfcb10accf246be9ef9a72a17c6f8" - integrity sha512-4j6Vp6rfT8lr8w9pyAZOGGVcsaPzc6HWK8a1Nc97TzZj+tv4JlqnhGnAvi6uDcfz6pTwWe6Wr/OK0a+a40+N+Q== +"@react-native/babel-preset@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/babel-preset/-/babel-preset-0.74.0-nightly-20231201-c30f2b620.tgz#f42ea01543823c2e01fcf10644a824bb95e1128f" + integrity sha512-e3WejQU3gclijGh2qU0NvqG92T/LrSe7m/+t5Wa4HmUxlrgaBsmHHmPQk3O6EKfv1BFw6T/4PuPfDi+NfQvufw== dependencies: "@babel/core" "^7.20.0" "@babel/plugin-proposal-async-generator-functions" "^7.0.0" @@ -2519,7 +2519,7 @@ "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" - "@react-native/babel-plugin-codegen" "0.74.0-nightly-20231124-c464b215e" + "@react-native/babel-plugin-codegen" "0.74.0-nightly-20231201-c30f2b620" babel-plugin-transform-flow-enums "^0.0.2" react-refresh "^0.14.0" @@ -2533,28 +2533,28 @@ jscodeshift "^0.14.0" nullthrows "^1.1.1" -"@react-native/codegen@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.0-nightly-20231124-c464b215e.tgz#ff66cbb30873c6db0ce07a48a2f07458d4f0f3b4" - integrity sha512-tIEawYmhXbL3UWpp2dw/XY/fQJvZxZh3ea6vfrsXfGhm0zkGjVIZNdAMhzXWF+60NfJuSMmydROB9+NtbrbzrA== +"@react-native/codegen@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/codegen/-/codegen-0.74.0-nightly-20231201-c30f2b620.tgz#0dc12b935544a65aec3deec8cf7af0da11fa5e73" + integrity sha512-TWnOQIs0tsO/8BSbpzYKK2laQm53BiMdVZMUc12WEu3l82BPNuK4zJt96zGmirwxI8MoSsYdsPu7R8sJFucG8Q== dependencies: "@babel/parser" "^7.20.0" glob "^7.1.1" - hermes-parser "0.17.1" + hermes-parser "0.18.0" invariant "^2.2.4" jscodeshift "^0.14.0" mkdirp "^0.5.1" nullthrows "^1.1.1" -"@react-native/community-cli-plugin@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.0-nightly-20231124-c464b215e.tgz#7ba1c95fead49ee4c36cf7902da75a4eb0ef9211" - integrity sha512-SUIZ2qizuWWZAJmy/t9VW2vTLFzVUGMccQt2ppT90yAjNL09Pg/L3mAPIk/CWtaXUVbETaVL4dGHCCPd9si1+A== +"@react-native/community-cli-plugin@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/community-cli-plugin/-/community-cli-plugin-0.74.0-nightly-20231201-c30f2b620.tgz#f5c5d03e46c5f43d4624cd8518b4f6a42c79d540" + integrity sha512-Mm8MEKo7ME6OH3xY4Qsi6QvEkz6kqAwbaDU+x0NRT7Ym7qK+FuaIR8flQkt6rfy5x6GXkjOq7z2Oys30IChm0Q== dependencies: "@react-native-community/cli-server-api" "12.0.0" "@react-native-community/cli-tools" "12.0.0" - "@react-native/dev-middleware" "0.74.0-nightly-20231124-c464b215e" - "@react-native/metro-babel-transformer" "0.74.0-nightly-20231124-c464b215e" + "@react-native/dev-middleware" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/metro-babel-transformer" "0.74.0-nightly-20231201-c30f2b620" chalk "^4.0.0" execa "^5.1.1" metro "^0.80.0" @@ -2563,18 +2563,18 @@ node-fetch "^2.2.0" readline "^1.3.0" -"@react-native/debugger-frontend@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.0-nightly-20231124-c464b215e.tgz#c33ed7968903f9a6b6655cc0d8655ace4ec3fcf2" - integrity sha512-gvYXYrOP4d1tuzp7Uq0xJK4gf8FUACpldevpM17snmIE1NpOu61Z9c0lcafWoki3cH4wfi77AbuChg2a25M0sw== +"@react-native/debugger-frontend@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/debugger-frontend/-/debugger-frontend-0.74.0-nightly-20231201-c30f2b620.tgz#4d78e7d61614671290b0d0ef5e4b31f2f91d0303" + integrity sha512-ipb7ihvftSWXGmBWtuhLdUu+79IoJsBIeCQWZ2LkIT+JlnKPOjT7ySdvdgQIJMrfkRjBWjd6tKh/7V9bp3/zjA== -"@react-native/dev-middleware@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.0-nightly-20231124-c464b215e.tgz#b649eb8da4abe94304d07105179725075f6a03ff" - integrity sha512-wqIcwod4uycBSraaouar0WNPpz4ylHdPIBDNTox6g1b9Bfeb+Igo08nfDhx3H0SBbuq9VGg8rI2prWphGgrcxA== +"@react-native/dev-middleware@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/dev-middleware/-/dev-middleware-0.74.0-nightly-20231201-c30f2b620.tgz#7636fbecd752e5ea4c6bb0952d9f5482033ab5a7" + integrity sha512-Xnc7LGxGyd7J/6T29fFwcCJT7bVL4NXCx5ManOSX6sfehwAgkXWCt/FliMRg+SckjxJ9QdvMjmfxJq23kvKLKQ== dependencies: "@isaacs/ttlcache" "^1.4.1" - "@react-native/debugger-frontend" "0.74.0-nightly-20231124-c464b215e" + "@react-native/debugger-frontend" "0.74.0-nightly-20231201-c30f2b620" "@rnx-kit/chromium-edge-launcher" "^1.0.0" chrome-launcher "^0.15.2" connect "^3.6.5" @@ -2609,15 +2609,15 @@ resolved "https://registry.yarnpkg.com/@react-native/eslint-plugin/-/eslint-plugin-0.73.1.tgz#79d2c4d90c80bfad8900db335bfbaf1ca599abdc" integrity sha512-8BNMFE8CAI7JLWLOs3u33wcwcJ821LYs5g53Xyx9GhSg0h8AygTwDrwmYb/pp04FkCNCPjKPBoaYRthQZmxgwA== -"@react-native/gradle-plugin@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.0-nightly-20231124-c464b215e.tgz#beabaf30eaa62f3d4f7e0c90b3cb7a1265c470ac" - integrity sha512-t7IngZokZ2dYdeFs24bxzz3rG58aaGZzB85rE6jtoFZU8zB4sABWPvj+hMdbntVdjW0TMuORAZ7cEUSdcOZQAQ== +"@react-native/gradle-plugin@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/gradle-plugin/-/gradle-plugin-0.74.0-nightly-20231201-c30f2b620.tgz#bcee2483803c35291cc87dd877c8e240d73e9c1c" + integrity sha512-3zMVGll70XVU9fjsL1zE3GTqw9tUaIJ+wyCVhHHR72Dt7wJTqylFsR5I1l5FbFG5JSEyA2QRCCgNNMZ8fKUWrQ== -"@react-native/js-polyfills@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.0-nightly-20231124-c464b215e.tgz#4fe906bc6a4d228c7ba4825ae29794a73b51b817" - integrity sha512-WbrqA79/8t7Jq/k5CacAC/0ptKw/Cign/NbNIAqWoZoGCPySQ3v6mPW9DgudH6J9dofoxL2If4elj38Wj+ryYA== +"@react-native/js-polyfills@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/js-polyfills/-/js-polyfills-0.74.0-nightly-20231201-c30f2b620.tgz#df30e5a7e1eb5c2b92eaf971f5ac73c8ad64fb46" + integrity sha512-aTNiq0BtsKmfB86gJFEgykHIZxAdwhyj2yZAtdz+hWBJ4DCbQBooTCf8M8TKMKmEYwAIQS9EVnKgBDfTQk9TjQ== "@react-native/js-polyfills@^0.73.1": version "0.73.1" @@ -2635,14 +2635,14 @@ hermes-parser "0.15.0" nullthrows "^1.1.1" -"@react-native/metro-babel-transformer@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.0-nightly-20231124-c464b215e.tgz#9f850d0795b91160889921aa98ec1ed71b6075af" - integrity sha512-5nPB9eaP1gZAtLDhxbpRGAhvOd46JVkFXJ2RtwHqbtSmCzowI8dKLEizVNkTKXGXKTRhiLS63XyStaTDOvfDzw== +"@react-native/metro-babel-transformer@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/metro-babel-transformer/-/metro-babel-transformer-0.74.0-nightly-20231201-c30f2b620.tgz#18ba88a4e627db24f5a8a842a8c87f9b5d02e407" + integrity sha512-vHB/6sQEwmYJm2eUKqmAKJ404hBQH6t1d3pvVy9CX4RjqOUbcQYJL5OSlhsX9/ASArR+cTmsGYDNd2FwZ34Khw== dependencies: "@babel/core" "^7.20.0" - "@react-native/babel-preset" "0.74.0-nightly-20231124-c464b215e" - hermes-parser "0.17.1" + "@react-native/babel-preset" "0.74.0-nightly-20231201-c30f2b620" + hermes-parser "0.18.0" nullthrows "^1.1.1" "@react-native/metro-babel-transformer@^0.74.0": @@ -2665,20 +2665,20 @@ metro-config "0.79.1" metro-runtime "0.79.1" -"@react-native/normalize-colors@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.0-nightly-20231124-c464b215e.tgz#6af8d017ce3347e8fc15b91fe718669110c148f5" - integrity sha512-e3f/FM1eVpig8r2+GqXLJTJ9X7teCEhva3GdwMeYjzZoMkgglix8W6G9uurNz2Iz6t8yH/G5SUcaVmgWtASmnA== +"@react-native/normalize-colors@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.0-nightly-20231201-c30f2b620.tgz#14b85aa78a5d3c6cf78b8f1204600a9cf0c58c0f" + integrity sha512-2+TjQGPP+kKXso8QbtTAnycOI0XXJugC3HYWg1pni9MLJAqqFSg66d7oJ0RPnAm6uqsc+OavoRujIeARxRez7A== "@react-native/normalize-colors@^0.73.0": version "0.73.2" resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.73.2.tgz#cc8e48fbae2bbfff53e12f209369e8d2e4cf34ec" integrity sha512-bRBcb2T+I88aG74LMVHaKms2p/T8aQd8+BZ7LuuzXlRfog1bMWWn/C5i0HVuvW4RPtXQYgIlGiXVDy9Ir1So/w== -"@react-native/virtualized-lists@0.74.0-nightly-20231124-c464b215e": - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.0-nightly-20231124-c464b215e.tgz#2680ae3133ef4ece2e4001a65db70aa5c5de8767" - integrity sha512-f67WObQLElPbjCYCPwlRPMjsZslKjgi+tAKepWhT1WBWv04tiWpLOFy7DUCTHg4JPT41kfBqL6MWLNM98BNVyw== +"@react-native/virtualized-lists@0.74.0-nightly-20231201-c30f2b620": + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/@react-native/virtualized-lists/-/virtualized-lists-0.74.0-nightly-20231201-c30f2b620.tgz#b763ea93aa61da0a2bb93c47e7a6a49f31322c7c" + integrity sha512-lKdP+kWe5ldWJSeth/w12+CoAX1jdGC9OANAx0ZRse6QNXS9fCSm9dp8zNWCmAhcHRjUzStPBQR8eiXnNVoW6A== dependencies: invariant "^2.2.4" nullthrows "^1.1.1" @@ -6649,28 +6649,28 @@ flatted@^3.1.0: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3" integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== -flow-api-translator@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/flow-api-translator/-/flow-api-translator-0.17.1.tgz#fee650b8c975338aea46be9e40464bcab81fbedf" - integrity sha512-TzOWylttBRQ8zco5Nmu7+11c45WpLgO1BPXe9R0nCoUo6x2IU4baC1AjnQEistsrMkG+Imlp2q3TFk6pRcJp0w== +flow-api-translator@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/flow-api-translator/-/flow-api-translator-0.18.0.tgz#c8fe149c3211638bba565d4ebbde10f05424acc2" + integrity sha512-X6LMMTGsYtJWJmaye0W10UOFQoxVQxm5nJkUDcX6nT3O0KpsV/5SNo7uf4KWzNGnb4u60p1IKx7ghBRJbUqV1w== dependencies: "@babel/code-frame" "^7.16.0" "@typescript-eslint/visitor-keys" "^5.42.0" flow-enums-runtime "^0.0.6" - hermes-eslint "0.17.1" - hermes-estree "0.17.1" - hermes-parser "0.17.1" - hermes-transform "0.17.1" + hermes-eslint "0.18.0" + hermes-estree "0.18.0" + hermes-parser "0.18.0" + hermes-transform "0.18.0" flow-bin@^0.217.2: version "0.217.2" resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.217.2.tgz#96affa17f3cb303019f740bffeb28cfab7ce1250" integrity sha512-fk4NcfybYjzlww1sEsfk71nqXvonAYpMRFEjmZxibDWWBiaw8DGmqXWZ7XzSunVB15VkJfOstn/sYP1EYPPyWg== -flow-bin@^0.222.0: - version "0.222.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.222.0.tgz#b4ca588c77fbd79db1edf38615cd04d114c1e933" - integrity sha512-U2047+pOX1EutHGykcjtamAlP8UIHrxbkexB5zPVQ8PH+WcVmD4PtRE6J8Jc3S6odyo0AqVnQsI4rE/2x2fGmQ== +flow-bin@^0.223.0: + version "0.223.3" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.223.3.tgz#351cfce2c685ec92769fcbc0bb906497c7ddc061" + integrity sha512-20jLm49wN6Gfcs+MI/coAeeXK8/Sbb3eSfyEY4KjlusRotLYaYB6Tg1ngh2sCtpbO598oAEawrKDZr0u6jKakQ== flow-enums-runtime@^0.0.5: version "0.0.5" @@ -7332,14 +7332,14 @@ hasown@^2.0.0: dependencies: function-bind "^1.1.2" -hermes-eslint@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/hermes-eslint/-/hermes-eslint-0.17.1.tgz#e5e43091082dc53a060e0b002324e68943104b71" - integrity sha512-g3z4L84pHKrBMRtbfifalpbNbNear0cEygAe+geCmCj1GUrqQu+RDeBZOYERHv0HOq0aDxjTZhj3m4fD/YVUwg== +hermes-eslint@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/hermes-eslint/-/hermes-eslint-0.18.0.tgz#16e7d5c7742f709d814d6a5a5d955803e81b328d" + integrity sha512-NIh8Utqk32+voL1b4ngCRnMQ0XCRzFbon7IG25lhnSYCTezX5besIK+79pUHw1YEDZVGrVrMxeIYxXiamLzcUQ== dependencies: esrecurse "^4.3.0" - hermes-estree "0.17.1" - hermes-parser "0.17.1" + hermes-estree "0.18.0" + hermes-parser "0.18.0" hermes-estree@0.15.0: version "0.15.0" @@ -7356,6 +7356,11 @@ hermes-estree@0.17.1: resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.17.1.tgz#902806a900c185720424ffcf958027821d23c051" integrity sha512-EdUJms+eRE40OQxysFlPr1mPpvUbbMi7uDAKlScBw8o3tQY22BZ5yx56OYyp1bVaBm+7Cjc3NQz24sJEFXkPxg== +hermes-estree@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/hermes-estree/-/hermes-estree-0.18.0.tgz#6c202d8c78ddefadf3eb595a584dfa55b51a0508" + integrity sha512-WaIudIVKo5QWFqz1ta53HqSDuVxYST/MUuP9X7dqUpbHse3E2gzJq/7hEtgx84hh2XSNWN1AhYho3ThOA85uCA== + hermes-parser@0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.15.0.tgz#f611a297c2a2dbbfbce8af8543242254f604c382" @@ -7377,6 +7382,13 @@ hermes-parser@0.17.1: dependencies: hermes-estree "0.17.1" +hermes-parser@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/hermes-parser/-/hermes-parser-0.18.0.tgz#dd9878f70e9ca2570e7626181ae0465115f7f78d" + integrity sha512-DIIM6vsy30BU5hNkOXh6MR2r4ZAxVhbfyTnmfo/rqUf3KySlNWn9fWiOcpuGAdDN2o5sdPCpu6cep3a23d1Klw== + dependencies: + hermes-estree "0.18.0" + hermes-profile-transformer@^0.0.6: version "0.0.6" resolved "https://registry.yarnpkg.com/hermes-profile-transformer/-/hermes-profile-transformer-0.0.6.tgz#bd0f5ecceda80dd0ddaae443469ab26fb38fc27b" @@ -7384,17 +7396,17 @@ hermes-profile-transformer@^0.0.6: dependencies: source-map "^0.7.3" -hermes-transform@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/hermes-transform/-/hermes-transform-0.17.1.tgz#8dc60f4744137b936c15aac9231a951268450600" - integrity sha512-0QlknKahueDHeswUjruzyvdfqtaw4OC4JuWYNWqAr8HP+1YGx3J2lwsGuQeaJhkC04eh9lhO9cc5/xfJLBr74A== +hermes-transform@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/hermes-transform/-/hermes-transform-0.18.0.tgz#e5718960ddf5c2c938397523085c0ac58159cc20" + integrity sha512-jbzeRDseWlUNhErS0ovt6/IpNcSEtYEytg6LTFox+4qDbrX5Tg6AO5xdNwMLgxPxD/03xAicBZL44/yI+4YXgA== dependencies: "@babel/code-frame" "^7.16.0" esquery "^1.4.0" flow-enums-runtime "^0.0.6" - hermes-eslint "0.17.1" - hermes-estree "0.17.1" - hermes-parser "0.17.1" + hermes-eslint "0.18.0" + hermes-estree "0.18.0" + hermes-parser "0.18.0" homedir-polyfill@^1.0.1: version "1.0.3" @@ -10676,14 +10688,14 @@ prettier-linter-helpers@^1.0.0: dependencies: fast-diff "^1.1.2" -prettier-plugin-hermes-parser@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/prettier-plugin-hermes-parser/-/prettier-plugin-hermes-parser-0.17.1.tgz#f7c461fe875f7a365442fc69a51434b7e3ff88e4" - integrity sha512-ULX366DyQrrFW//a6Zgj0r/CF4a4Ijg+TCaplOtYCPCu4qThUp9XrMRSYWeB0lacD1lmWFqRDFL5R8Oxmhpw3A== +prettier-plugin-hermes-parser@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/prettier-plugin-hermes-parser/-/prettier-plugin-hermes-parser-0.18.0.tgz#00b6d979f8068c4fab72500c1abb5a8dcc107645" + integrity sha512-gU/K9jjJYDzdn1PLJdjhaHk+27POGrSbxVxBUOVm9qOiIpnwW1IeYA3sHg2PpCJLUQyJM7R6jiesQgPgvUHkmA== dependencies: - hermes-estree "0.17.1" - hermes-parser "0.17.1" - prettier-plugin-hermes-parser "0.17.1" + hermes-estree "0.18.0" + hermes-parser "0.18.0" + prettier-plugin-hermes-parser "0.18.0" prettier@2.8.8, prettier@^2.4.1: version "2.8.8" @@ -10896,22 +10908,22 @@ react-native-xaml@^0.0.76: "@types/react-native" "*" typescript "^4.4.3" -react-native@0.74.0-nightly-20231124-c464b215e: - version "0.74.0-nightly-20231124-c464b215e" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.0-nightly-20231124-c464b215e.tgz#f344f12f7f5985bfb5e7283fc1fab6e6ae566d5c" - integrity sha512-86SbzahKF0cwt2eMDDhsd1PZWrI14MdGtwWSBMV8HkrPWkYwgkMdrzbNkx7xOwa3QDZXGw3d0wwhG56AeSnQxA== +react-native@0.74.0-nightly-20231201-c30f2b620: + version "0.74.0-nightly-20231201-c30f2b620" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.74.0-nightly-20231201-c30f2b620.tgz#dcab189264530e499f95738b2feae4d75c733aad" + integrity sha512-6sUQ/5qq9EtHE2zSbmJT7e/iYGjTMRH8ERXnsXGiDWMFOzOqcqjG56b3+ca3StzRohjoopjEMyCZyBtxEx28ZA== dependencies: "@jest/create-cache-key-function" "^29.6.3" "@react-native-community/cli" "12.0.0" "@react-native-community/cli-platform-android" "12.0.0" "@react-native-community/cli-platform-ios" "12.0.0" - "@react-native/assets-registry" "0.74.0-nightly-20231124-c464b215e" - "@react-native/codegen" "0.74.0-nightly-20231124-c464b215e" - "@react-native/community-cli-plugin" "0.74.0-nightly-20231124-c464b215e" - "@react-native/gradle-plugin" "0.74.0-nightly-20231124-c464b215e" - "@react-native/js-polyfills" "0.74.0-nightly-20231124-c464b215e" - "@react-native/normalize-colors" "0.74.0-nightly-20231124-c464b215e" - "@react-native/virtualized-lists" "0.74.0-nightly-20231124-c464b215e" + "@react-native/assets-registry" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/codegen" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/community-cli-plugin" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/gradle-plugin" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/js-polyfills" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/normalize-colors" "0.74.0-nightly-20231201-c30f2b620" + "@react-native/virtualized-lists" "0.74.0-nightly-20231201-c30f2b620" abort-controller "^3.0.0" anser "^1.4.9" ansi-regex "^5.0.0" From 77731433da250f8bca8d358867ecdc14c4941627 Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Tue, 9 Jan 2024 14:36:17 -0800 Subject: [PATCH 05/16] fix lint and snapshot --- .../Libraries/Inspector/Inspector.win32.js | 2 +- .../TextInputComponentTest.test.ts.snap | 34 +++++++-------- .../__snapshots__/snapshotPages.test.js.snap | 43 ++++++++++++++----- 3 files changed, 51 insertions(+), 28 deletions(-) diff --git a/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js b/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js index 1bba357ed25..037d7b5f43a 100644 --- a/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js +++ b/packages/@office-iss/react-native-win32/src/Libraries/Inspector/Inspector.win32.js @@ -114,7 +114,7 @@ function Inspector({ } // [Win32 Avoid Dimensions call - const node = ReactNative.findNodeHandle(inspectedView); + const node = ReactNative.findNodeHandle(inspectedViewRef); // $FlowFixMe[incompatible-call] UIManager.measure(node, (x, y, width, height, left, top) => { setPanelPosition(pointerY > height / 2 ? 'top' : 'bottom'); diff --git a/packages/e2e-test-app-fabric/test/__snapshots__/TextInputComponentTest.test.ts.snap b/packages/e2e-test-app-fabric/test/__snapshots__/TextInputComponentTest.test.ts.snap index 3af12173c3c..85b3548aeb9 100644 --- a/packages/e2e-test-app-fabric/test/__snapshots__/TextInputComponentTest.test.ts.snap +++ b/packages/e2e-test-app-fabric/test/__snapshots__/TextInputComponentTest.test.ts.snap @@ -1352,7 +1352,7 @@ exports[`TextInput Tests TextInputs can autocomplete, address country 1`] = ` "Opacity": 1, "Size": [ 916, - 28, + 29, ], "Visual Type": "SpriteVisual", }, @@ -1503,7 +1503,7 @@ exports[`TextInput Tests TextInputs can autocomplete, country 1`] = ` "Opacity": 1, "Size": [ 916, - 29, + 28, ], "Visual Type": "SpriteVisual", }, @@ -1805,7 +1805,7 @@ exports[`TextInput Tests TextInputs can autocomplete, sms-otp 1`] = ` "Opacity": 1, "Size": [ 916, - 29, + 28, ], "Visual Type": "SpriteVisual", }, @@ -2003,7 +2003,7 @@ exports[`TextInput Tests TextInputs can be editable 1`] = ` "Opacity": 1, "Size": [ 916, - 28, + 29, ], "Visual Type": "SpriteVisual", }, @@ -2530,7 +2530,7 @@ exports[`TextInput Tests TextInputs can customize its padding 1`] = ` "Opacity": 1, "Size": [ 916, - 19, + 20, ], "Visual Type": "SpriteVisual", }, @@ -3681,7 +3681,7 @@ exports[`TextInput Tests TextInputs can have caretHidden 1`] = ` "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, @@ -3728,7 +3728,7 @@ exports[`TextInput Tests TextInputs can have custom return key label, Compile 1` "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, @@ -3775,7 +3775,7 @@ exports[`TextInput Tests TextInputs can have custom return key label, React Nati "Opacity": 1, "Size": [ 916, - 22, + 23, ], "Visual Type": "SpriteVisual", }, @@ -3869,7 +3869,7 @@ exports[`TextInput Tests TextInputs can have custom return key type, go 1`] = ` "Opacity": 1, "Size": [ 916, - 22, + 23, ], "Visual Type": "SpriteVisual", }, @@ -3963,7 +3963,7 @@ exports[`TextInput Tests TextInputs can have custom return key type, none 1`] = "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, @@ -4010,7 +4010,7 @@ exports[`TextInput Tests TextInputs can have custom return key type, previous 1` "Opacity": 1, "Size": [ 916, - 22, + 23, ], "Visual Type": "SpriteVisual", }, @@ -4104,7 +4104,7 @@ exports[`TextInput Tests TextInputs can have custom return key type, send 1`] = "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, @@ -4151,7 +4151,7 @@ exports[`TextInput Tests TextInputs can have customer letter spacing, spacing=-1 "Opacity": 1, "Size": [ 916, - 22, + 23, ], "Visual Type": "SpriteVisual", }, @@ -4245,7 +4245,7 @@ exports[`TextInput Tests TextInputs can have customer letter spacing, spacing=2 "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, @@ -4819,7 +4819,7 @@ exports[`TextInput Tests TextInputs can have inline images, drawableLeft and dra "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, @@ -5819,7 +5819,7 @@ exports[`TextInput Tests TextInputs can set their readOnly prop to false 1`] = ` "Opacity": 1, "Size": [ 916, - 29, + 28, ], "Visual Type": "SpriteVisual", }, @@ -6487,7 +6487,7 @@ exports[`TextInput Tests TextInputs support secure entry, with placeholder text "Opacity": 1, "Size": [ 916, - 23, + 22, ], "Visual Type": "SpriteVisual", }, diff --git a/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap b/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap index 84fb55aee32..e676fd816a7 100644 --- a/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap +++ b/packages/e2e-test-app-fabric/test/__snapshots__/snapshotPages.test.js.snap @@ -34624,6 +34624,7 @@ exports[`snapshotAllPages Pressable 2`] = ` }, ] } + testID="style-change-pressable" > + `; exports[`snapshotAllPages Pressable 17`] = ` + @@ -36639,9 +36644,7 @@ exports[`snapshotAllPages Pressable 19`] = ` `; exports[`snapshotAllPages Pressable 20`] = ` - + Parent Pressable @@ -36725,6 +36729,7 @@ exports[`snapshotAllPages Pressable 20`] = ` exports[`snapshotAllPages Pressable 21`] = ` + + `; From e39cace414a2945cd06b028b0ae3b9c8c4dc43e3 Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Wed, 10 Jan 2024 11:13:06 -0800 Subject: [PATCH 06/16] add issue numbers --- .../components/view/YogaStylableProps.cpp | 521 ------------------ .../yoga/yoga/node/LayoutResults.h | 4 +- .../yoga/yoga/style/Style.h | 4 +- vnext/overrides.json | 11 +- 4 files changed, 13 insertions(+), 527 deletions(-) delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp deleted file mode 100644 index a272b29667f..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/react/renderer/components/view/YogaStylableProps.cpp +++ /dev/null @@ -1,521 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "YogaStylableProps.h" - -#include -#include -#include -#include -#include -#include -#include - -#include "conversions.h" - -namespace facebook::react { - -YogaStylableProps::YogaStylableProps( - const PropsParserContext& context, - const YogaStylableProps& sourceProps, - const RawProps& rawProps) - : Props() { - initialize(context, sourceProps, rawProps); - - yogaStyle = CoreFeatures::enablePropIteratorSetter - ? sourceProps.yogaStyle - : convertRawProp(context, rawProps, sourceProps.yogaStyle); - - if (!CoreFeatures::enablePropIteratorSetter) { - convertRawPropAliases(context, sourceProps, rawProps); - } -}; - -/*static*/ const yoga::Style& YogaStylableProps::defaultStyle() { - static const auto defaultStyle = []() { - yoga::Style style; - style.setPositionType( - CoreFeatures::positionRelativeDefault ? yoga::PositionType::Relative - : yoga::PositionType::Static); - return style; - }(); - - return defaultStyle; -} - -template -static inline T const getFieldValue( - const PropsParserContext& context, - const RawValue& value, - T const defaultValue) { - if (value.hasValue()) { - T res; - fromRawValue(context, value, res); - return res; - } - - return defaultValue; -} - -#define REBUILD_FIELD_SWITCH_CASE2(field, setter, fieldName) \ - case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ - yogaStyle.setter(getFieldValue(context, value, defaultStyle().field())); \ - return; \ - } - -#define REBUILD_FIELD_SWITCH_CASE_YSP(field, setter) \ - REBUILD_FIELD_SWITCH_CASE2(field, setter, #field) - -#define REBUILD_YG_FIELD_SWITCH_CASE_INDEXED(field, setter, index, fieldName) \ - case CONSTEXPR_RAW_PROPS_KEY_HASH(fieldName): { \ - yogaStyle.setter( \ - index, getFieldValue(context, value, defaultStyle().field(index))); \ - return; \ - } - -#define REBUILD_FIELD_YG_DIMENSION(field, setter, widthStr, heightStr) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Dimension::Width, widthStr); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Dimension::Height, heightStr); - -#define REBUILD_FIELD_YG_GUTTER( \ - field, setter, rowGapStr, columnGapStr, gapStr) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Gutter::Row, rowGapStr); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Gutter::Column, columnGapStr); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Gutter::All, gapStr); - -#define REBUILD_FIELD_YG_EDGES(field, setter, prefix, suffix) \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Left, prefix "Left" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Top, prefix "Top" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Right, prefix "Right" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Bottom, prefix "Bottom" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Start, prefix "Start" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::End, prefix "End" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Horizontal, prefix "Horizontal" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::Vertical, prefix "Vertical" suffix); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - field, setter, yoga::Edge::All, prefix "" suffix); - -#define REBUILD_FIELD_YG_EDGES_POSITION() \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Left, "left"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Top, "top"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Right, "right"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Bottom, "bottom"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Start, "start"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::End, "end"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Horizontal, "insetInline"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::Vertical, "insetBlock"); \ - REBUILD_YG_FIELD_SWITCH_CASE_INDEXED( \ - position, setPosition, yoga::Edge::All, "inset"); - -void YogaStylableProps::setProp( - const PropsParserContext& context, - RawPropsPropNameHash hash, - const char* propName, - const RawValue& value) { - static const auto defaults = YogaStylableProps{}; - - Props::setProp(context, hash, propName, value); - - switch (hash) { - REBUILD_FIELD_SWITCH_CASE_YSP(direction, setDirection); - REBUILD_FIELD_SWITCH_CASE_YSP(flexDirection, setFlexDirection); - REBUILD_FIELD_SWITCH_CASE_YSP(justifyContent, setJustifyContent); - REBUILD_FIELD_SWITCH_CASE_YSP(alignContent, setAlignContent); - REBUILD_FIELD_SWITCH_CASE_YSP(alignItems, setAlignItems); - REBUILD_FIELD_SWITCH_CASE_YSP(alignSelf, setAlignSelf); - REBUILD_FIELD_SWITCH_CASE_YSP(flexWrap, setFlexWrap); - REBUILD_FIELD_SWITCH_CASE_YSP(overflow, setOverflow); - REBUILD_FIELD_SWITCH_CASE_YSP(display, setDisplay); - REBUILD_FIELD_SWITCH_CASE_YSP(flex, setFlex); - REBUILD_FIELD_SWITCH_CASE_YSP(flexGrow, setFlexGrow); - REBUILD_FIELD_SWITCH_CASE_YSP(flexShrink, setFlexShrink); - REBUILD_FIELD_SWITCH_CASE_YSP(flexBasis, setFlexBasis); - REBUILD_FIELD_SWITCH_CASE2(positionType, setPositionType, "position"); - REBUILD_FIELD_YG_GUTTER(gap, setGap, "rowGap", "columnGap", "gap"); - REBUILD_FIELD_SWITCH_CASE_YSP(aspectRatio, setAspectRatio); - REBUILD_FIELD_YG_DIMENSION(dimension, setDimension, "width", "height"); - REBUILD_FIELD_YG_DIMENSION( - minDimension, setMinDimension, "minWidth", "minHeight"); - REBUILD_FIELD_YG_DIMENSION( - maxDimension, setMaxDimension, "maxWidth", "maxHeight"); - REBUILD_FIELD_YG_EDGES_POSITION(); - REBUILD_FIELD_YG_EDGES(margin, setMargin, "margin", ""); - REBUILD_FIELD_YG_EDGES(padding, setPadding, "padding", ""); - REBUILD_FIELD_YG_EDGES(border, setBorder, "border", "Width"); - - // Aliases - RAW_SET_PROP_SWITCH_CASE(insetBlockEnd, "insetBlockEnd"); - RAW_SET_PROP_SWITCH_CASE(insetBlockStart, "insetBlockStart"); - RAW_SET_PROP_SWITCH_CASE(insetInlineEnd, "insetInlineEnd"); - RAW_SET_PROP_SWITCH_CASE(insetInlineStart, "insetInlineStart"); - RAW_SET_PROP_SWITCH_CASE(marginInline, "marginInline"); - RAW_SET_PROP_SWITCH_CASE(marginInlineStart, "marginInlineStart"); - RAW_SET_PROP_SWITCH_CASE(marginInlineEnd, "marginInlineEnd"); - RAW_SET_PROP_SWITCH_CASE(marginBlock, "marginBlock"); - RAW_SET_PROP_SWITCH_CASE(marginBlockStart, "marginBlockStart"); - RAW_SET_PROP_SWITCH_CASE(marginBlockEnd, "marginBlockEnd"); - RAW_SET_PROP_SWITCH_CASE(paddingInline, "paddingInline"); - RAW_SET_PROP_SWITCH_CASE(paddingInlineStart, "paddingInlineStart"); - RAW_SET_PROP_SWITCH_CASE(paddingInlineEnd, "paddingInlineEnd"); - RAW_SET_PROP_SWITCH_CASE(paddingBlock, "paddingBlock"); - RAW_SET_PROP_SWITCH_CASE(paddingBlockStart, "paddingBlockStart"); - RAW_SET_PROP_SWITCH_CASE(paddingBlockEnd, "paddingBlockEnd"); - } -} - -#pragma mark - DebugStringConvertible - -#if RN_DEBUG_STRING_CONVERTIBLE -SharedDebugStringConvertibleList YogaStylableProps::getDebugProps() const { - return { - debugStringConvertibleItem( - "direction", yogaStyle.direction(), defaultStyle().direction()), - debugStringConvertibleItem( - "flexDirection", - yogaStyle.flexDirection(), - defaultStyle().flexDirection()), - debugStringConvertibleItem( - "justifyContent", - yogaStyle.justifyContent(), - defaultStyle().justifyContent()), - debugStringConvertibleItem( - "alignContent", - yogaStyle.alignContent(), - defaultStyle().alignContent()), - debugStringConvertibleItem( - "alignItems", yogaStyle.alignItems(), defaultStyle().alignItems()), - debugStringConvertibleItem( - "alignSelf", yogaStyle.alignSelf(), defaultStyle().alignSelf()), - debugStringConvertibleItem( - "positionType", - yogaStyle.positionType(), - defaultStyle().positionType()), - debugStringConvertibleItem( - "flexWrap", yogaStyle.flexWrap(), defaultStyle().flexWrap()), - debugStringConvertibleItem( - "overflow", yogaStyle.overflow(), defaultStyle().overflow()), - debugStringConvertibleItem( - "display", yogaStyle.display(), defaultStyle().display()), - debugStringConvertibleItem( - "flex", yogaStyle.flex(), defaultStyle().flex()), - debugStringConvertibleItem( - "flexGrow", yogaStyle.flexGrow(), defaultStyle().flexGrow()), - debugStringConvertibleItem( - "rowGap", - yogaStyle.gap(yoga::Gutter::Row), - defaultStyle().gap(yoga::Gutter::Row)), - debugStringConvertibleItem( - "columnGap", - yogaStyle.gap(yoga::Gutter::Column), - defaultStyle().gap(yoga::Gutter::Column)), - debugStringConvertibleItem( - "gap", - yogaStyle.gap(yoga::Gutter::All), - defaultStyle().gap(yoga::Gutter::All)), - debugStringConvertibleItem( - "flexShrink", yogaStyle.flexShrink(), defaultStyle().flexShrink()), - debugStringConvertibleItem( - "flexBasis", yogaStyle.flexBasis(), defaultStyle().flexBasis()), - debugStringConvertibleItem( - "marginLeft", - yogaStyle.margin(yoga::Edge::Left), - defaultStyle().margin(yoga::Edge::Left)), - debugStringConvertibleItem( - "marginTop", - yogaStyle.margin(yoga::Edge::Top), - defaultStyle().margin(yoga::Edge::Top)), - debugStringConvertibleItem( - "marginRight", - yogaStyle.margin(yoga::Edge::Right), - defaultStyle().margin(yoga::Edge::Right)), - debugStringConvertibleItem( - "marginBottom", - yogaStyle.margin(yoga::Edge::Bottom), - defaultStyle().margin(yoga::Edge::Bottom)), - debugStringConvertibleItem( - "marginStart", - yogaStyle.margin(yoga::Edge::Start), - defaultStyle().margin(yoga::Edge::Start)), - debugStringConvertibleItem( - "marginEnd", - yogaStyle.margin(yoga::Edge::End), - defaultStyle().margin(yoga::Edge::End)), - debugStringConvertibleItem( - "marginHorizontal", - yogaStyle.margin(yoga::Edge::Horizontal), - defaultStyle().margin(yoga::Edge::Horizontal)), - debugStringConvertibleItem( - "marginVertical", - yogaStyle.margin(yoga::Edge::Vertical), - defaultStyle().margin(yoga::Edge::Vertical)), - debugStringConvertibleItem( - "margin", - yogaStyle.margin(yoga::Edge::All), - defaultStyle().margin(yoga::Edge::All)), - debugStringConvertibleItem( - "left", - yogaStyle.position(yoga::Edge::Left), - defaultStyle().position(yoga::Edge::Left)), - debugStringConvertibleItem( - "top", - yogaStyle.position(yoga::Edge::Top), - defaultStyle().position(yoga::Edge::Top)), - debugStringConvertibleItem( - "right", - yogaStyle.position(yoga::Edge::Right), - defaultStyle().position(yoga::Edge::Right)), - debugStringConvertibleItem( - "bottom", - yogaStyle.position(yoga::Edge::Bottom), - defaultStyle().position(yoga::Edge::Bottom)), - debugStringConvertibleItem( - "start", - yogaStyle.position(yoga::Edge::Start), - defaultStyle().position(yoga::Edge::Start)), - debugStringConvertibleItem( - "end", - yogaStyle.position(yoga::Edge::End), - defaultStyle().position(yoga::Edge::End)), - debugStringConvertibleItem( - "inseInline", - yogaStyle.position(yoga::Edge::Horizontal), - defaultStyle().position(yoga::Edge::Horizontal)), - debugStringConvertibleItem( - "insetBlock", - yogaStyle.position(yoga::Edge::Vertical), - defaultStyle().position(yoga::Edge::Vertical)), - debugStringConvertibleItem( - "inset", - yogaStyle.position(yoga::Edge::All), - defaultStyle().position(yoga::Edge::All)), - debugStringConvertibleItem( - "paddingLeft", - yogaStyle.padding(yoga::Edge::Left), - defaultStyle().padding(yoga::Edge::Left)), - debugStringConvertibleItem( - "paddingTop", - yogaStyle.padding(yoga::Edge::Top), - defaultStyle().padding(yoga::Edge::Top)), - debugStringConvertibleItem( - "paddingRight", - yogaStyle.padding(yoga::Edge::Right), - defaultStyle().padding(yoga::Edge::Right)), - debugStringConvertibleItem( - "paddingBottom", - yogaStyle.padding(yoga::Edge::Bottom), - defaultStyle().padding(yoga::Edge::Bottom)), - debugStringConvertibleItem( - "paddingStart", - yogaStyle.padding(yoga::Edge::Start), - defaultStyle().padding(yoga::Edge::Start)), - debugStringConvertibleItem( - "paddingEnd", - yogaStyle.padding(yoga::Edge::End), - defaultStyle().padding(yoga::Edge::End)), - debugStringConvertibleItem( - "paddingHorizontal", - yogaStyle.padding(yoga::Edge::Horizontal), - defaultStyle().padding(yoga::Edge::Horizontal)), - debugStringConvertibleItem( - "paddingVertical", - yogaStyle.padding(yoga::Edge::Vertical), - defaultStyle().padding(yoga::Edge::Vertical)), - debugStringConvertibleItem( - "padding", - yogaStyle.padding(yoga::Edge::All), - defaultStyle().padding(yoga::Edge::All)), - debugStringConvertibleItem( - "borderLeftWidth", - yogaStyle.border(yoga::Edge::Left), - defaultStyle().border(yoga::Edge::Left)), - debugStringConvertibleItem( - "borderTopWidth", - yogaStyle.border(yoga::Edge::Top), - defaultStyle().border(yoga::Edge::Top)), - debugStringConvertibleItem( - "borderRightWidth", - yogaStyle.border(yoga::Edge::Right), - defaultStyle().border(yoga::Edge::Right)), - debugStringConvertibleItem( - "borderBottomWidth", - yogaStyle.border(yoga::Edge::Bottom), - defaultStyle().border(yoga::Edge::Bottom)), - debugStringConvertibleItem( - "borderStartWidth", - yogaStyle.border(yoga::Edge::Start), - defaultStyle().border(yoga::Edge::Start)), - debugStringConvertibleItem( - "borderEndWidth", - yogaStyle.border(yoga::Edge::End), - defaultStyle().border(yoga::Edge::End)), - debugStringConvertibleItem( - "borderHorizontalWidth", - yogaStyle.border(yoga::Edge::Horizontal), - defaultStyle().border(yoga::Edge::Horizontal)), - debugStringConvertibleItem( - "borderVerticalWidth", - yogaStyle.border(yoga::Edge::Vertical), - defaultStyle().border(yoga::Edge::Vertical)), - debugStringConvertibleItem( - "bordeWidth", - yogaStyle.border(yoga::Edge::All), - defaultStyle().border(yoga::Edge::All)), - debugStringConvertibleItem( - "width", - yogaStyle.dimension(yoga::Dimension::Width), - defaultStyle().dimension(yoga::Dimension::Width)), - debugStringConvertibleItem( - "height", - yogaStyle.dimension(yoga::Dimension::Height), - defaultStyle().dimension(yoga::Dimension::Height)), - debugStringConvertibleItem( - "minWidth", - yogaStyle.minDimension(yoga::Dimension::Width), - defaultStyle().minDimension(yoga::Dimension::Width)), - debugStringConvertibleItem( - "minHeight", - yogaStyle.minDimension(yoga::Dimension::Height), - defaultStyle().minDimension(yoga::Dimension::Height)), - debugStringConvertibleItem( - "maxWidth", - yogaStyle.maxDimension(yoga::Dimension::Width), - defaultStyle().maxDimension(yoga::Dimension::Width)), - debugStringConvertibleItem( - "maxHeight", - yogaStyle.maxDimension(yoga::Dimension::Height), - defaultStyle().maxDimension(yoga::Dimension::Height)), - debugStringConvertibleItem( - "aspectRatio", yogaStyle.aspectRatio(), defaultStyle().aspectRatio()), - }; -} -#endif - -void YogaStylableProps::convertRawPropAliases( - const PropsParserContext& context, - const YogaStylableProps& sourceProps, - const RawProps& rawProps) { - insetBlockEnd = convertRawProp( - context, - rawProps, - "insetBlockEnd", - sourceProps.insetBlockEnd, - yoga::value::undefined()); - insetBlockStart = convertRawProp( - context, - rawProps, - "insetBlockStart", - sourceProps.insetBlockStart, - yoga::value::undefined()); - insetInlineEnd = convertRawProp( - context, - rawProps, - "insetInlineEnd", - sourceProps.insetInlineEnd, - yoga::value::undefined()); - insetInlineStart = convertRawProp( - context, - rawProps, - "insetInlineStart", - sourceProps.insetInlineStart, - yoga::value::undefined()); - marginInline = convertRawProp( - context, - rawProps, - "marginInline", - sourceProps.marginInline, - yoga::value::undefined()); - marginInlineStart = convertRawProp( - context, - rawProps, - "marginInlineStart", - sourceProps.marginInlineStart, - yoga::value::undefined()); - marginInlineEnd = convertRawProp( - context, - rawProps, - "marginInlineEnd", - sourceProps.marginInlineEnd, - yoga::value::undefined()); - marginBlock = convertRawProp( - context, - rawProps, - "marginBlock", - sourceProps.marginBlock, - yoga::value::undefined()); - marginBlockStart = convertRawProp( - context, - rawProps, - "marginBlockStart", - sourceProps.marginBlockStart, - yoga::value::undefined()); - marginBlockEnd = convertRawProp( - context, - rawProps, - "marginBlockEnd", - sourceProps.marginBlockEnd, - yoga::value::undefined()); - - paddingInline = convertRawProp( - context, - rawProps, - "paddingInline", - sourceProps.paddingInline, - yoga::value::undefined()); - paddingInlineStart = convertRawProp( - context, - rawProps, - "paddingInlineStart", - sourceProps.paddingInlineStart, - yoga::value::undefined()); - paddingInlineEnd = convertRawProp( - context, - rawProps, - "paddingInlineEnd", - sourceProps.paddingInlineEnd, - yoga::value::undefined()); - paddingBlock = convertRawProp( - context, - rawProps, - "paddingBlock", - sourceProps.paddingBlock, - yoga::value::undefined()); - paddingBlockStart = convertRawProp( - context, - rawProps, - "paddingBlockStart", - sourceProps.paddingBlockStart, - yoga::value::undefined()); - paddingBlockEnd = convertRawProp( - context, - rawProps, - "paddingBlockEnd", - sourceProps.paddingBlockEnd, - yoga::value::undefined()); -} - -} // namespace facebook::react \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h index 6ba3b430d8c..6975fcf0768 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/node/LayoutResults.h @@ -20,7 +20,7 @@ namespace facebook::yoga { struct LayoutResults { - // [Windows C++20 fix + // [Windows C++20 fix #12195 LayoutResults() : direction_(Direction::Inherit), hadOverflow_(false) {} // Windows] @@ -124,7 +124,7 @@ struct LayoutResults { static_cast(edge) <= 3, "Edge must be top/left/bottom/right"); } - // [Windows c++20 fix + // [Windows c++20 fix #12195 Direction direction_ : bitCount(); bool hadOverflow_ : 1; // Windows] diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h index 8b9e331d720..5820c060ffc 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h @@ -54,7 +54,7 @@ class YG_EXPORT Style { static constexpr float DefaultFlexShrink = 0.0f; static constexpr float WebDefaultFlexShrink = 1.0f; - // [Windows C++20 fix + // [Windows C++20 fix #12195 Style() : direction_(Direction::Inherit), flexDirection_(FlexDirection::Column), justifyContent_(Justify::FlexStart), alignContent_(Align::FlexStart), alignItems_(Align::Stretch), alignSelf_(Align::Auto), positionType_(PositionType::Relative), flexWrap_(Wrap::NoWrap), overflow_(Overflow::Visible), display_(Display::Flex) {} @@ -270,7 +270,7 @@ class YG_EXPORT Style { using Edges = std::array()>; using Gutters = std::array()>; - // [Window C++20 fix + // [Window C++20 fix #12195 Direction direction_ : bitCount(); FlexDirection flexDirection_ : bitCount(); Justify justifyContent_ : bitCount(); diff --git a/vnext/overrides.json b/vnext/overrides.json index 0a957f257f1..b92300eb17d 100644 --- a/vnext/overrides.json +++ b/vnext/overrides.json @@ -64,14 +64,14 @@ "file": "ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.cpp", "baseFile": "packages/react-native/ReactCommon/jsi/jsi/JSIDynamic.cpp", "baseHash": "989722b8812d05adfc0f5e4c8dcbf42ab6026a7f", - "issue": 12210 + "issue": 12581 }, { "type": "copy", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/JSIDynamic.h", "baseFile": "packages/react-native/ReactCommon/jsi/jsi/JSIDynamic.h", "baseHash": "b3df8b8ce255b2d11184ba705407cb399c121a87", - "issue": 12210 + "issue": 12581 }, { "type": "patch", @@ -192,6 +192,13 @@ "baseHash": "c4150273aa8ab23568f31365cd678b9967521362", "issue": 12195 }, + { + "type": "patch", + "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h", + "baseFile": "packages/react-native/ReactCommon/yoga/yoga/style/Style.h", + "baseHash": "c4150273aa8ab23568f31365cd678b9967521362", + "issue": 12195 + }, { "type": "copy", "directory": "ReactCopies/IntegrationTests", From 0f826a08a61dad556db0537df9ac12bfedb0ea14 Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Wed, 10 Jan 2024 13:17:28 -0800 Subject: [PATCH 07/16] add setExternalMemoryPressure --- .../JSI/JsiAbiApi.cpp | 2 + .../Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h | 1 + vnext/Microsoft.ReactNative/JsiApi.cpp | 8 + vnext/Microsoft.ReactNative/JsiApi.h | 1 + vnext/Microsoft.ReactNative/JsiApi.idl | 1 + .../jsi/jsi/decorator.h | 810 +++++++++ .../jsi/jsi/jsi-inl.h | 356 ++++ .../TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h | 1524 +++++++++++++++++ .../yoga/yoga/style/Style.h | 2 +- vnext/Shared/JSI/ChakraApi.h | 5 + vnext/Shared/JSI/ChakraRuntime.cpp | 4 + vnext/Shared/JSI/ChakraRuntime.h | 1 + vnext/overrides.json | 2 +- 13 files changed, 2715 insertions(+), 2 deletions(-) create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h create mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h diff --git a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp index a61d9baff54..c757c707889 100644 --- a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +++ b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp @@ -739,6 +739,8 @@ bool JsiAbiRuntime::instanceOf(const Object &o, const Function &f) try { throw; } +void JsiAbiRuntime::setExternalMemoryPressure(const Object &, size_t) {} + template struct AutoRestore { AutoRestore(T *var, T value) : m_var{var}, m_value{std::exchange(*var, value)} {} diff --git a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h index 55adef2b61a..9514643dbc7 100644 --- a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +++ b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h @@ -179,6 +179,7 @@ struct JsiAbiRuntime : facebook::jsi::Runtime { bool strictEquals(const facebook::jsi::String &a, const facebook::jsi::String &b) const override; bool strictEquals(const facebook::jsi::Object &a, const facebook::jsi::Object &b) const override; bool instanceOf(const facebook::jsi::Object &o, const facebook::jsi::Function &f) override; + void setExternalMemoryPressure(const facebook::jsi::Object &, size_t) override; void RethrowJsiError() const; diff --git a/vnext/Microsoft.ReactNative/JsiApi.cpp b/vnext/Microsoft.ReactNative/JsiApi.cpp index 10662d7e974..3e38092b572 100644 --- a/vnext/Microsoft.ReactNative/JsiApi.cpp +++ b/vnext/Microsoft.ReactNative/JsiApi.cpp @@ -185,6 +185,7 @@ struct RuntimeAccessor : facebook::jsi::Runtime { using facebook::jsi::Runtime::lockWeakObject; using facebook::jsi::Runtime::popScope; using facebook::jsi::Runtime::pushScope; + using facebook::jsi::Runtime::setExternalMemoryPressure; using facebook::jsi::Runtime::setNativeState; using facebook::jsi::Runtime::setPropertyValue; using facebook::jsi::Runtime::setValueAtIndexImpl; @@ -1083,6 +1084,13 @@ bool JsiRuntime::InstanceOf(JsiObjectRef obj, JsiObjectRef constructor) try { throw; } +void JsiRuntime::setExternalMemoryPressure(JsiObjectRef obj, uint32_t size) try { + auto objPtr = RuntimeAccessor::AsPointerValue(obj); + m_runtimeAccessor->setExternalMemoryPressure(RuntimeAccessor::AsObject(&objPtr), size); +} catch (JSI_SET_ERROR) { + throw; +} + void JsiRuntime::ReleaseSymbol(JsiSymbolRef const &symbolData) { auto symbol = RuntimeAccessor::make(reinterpret_cast(symbolData.Data)); diff --git a/vnext/Microsoft.ReactNative/JsiApi.h b/vnext/Microsoft.ReactNative/JsiApi.h index 193075c01a1..44909631cd1 100644 --- a/vnext/Microsoft.ReactNative/JsiApi.h +++ b/vnext/Microsoft.ReactNative/JsiApi.h @@ -160,6 +160,7 @@ struct JsiRuntime : JsiRuntimeT { bool StringStrictEquals(JsiStringRef left, JsiStringRef right); bool ObjectStrictEquals(JsiObjectRef left, JsiObjectRef right); bool InstanceOf(JsiObjectRef obj, JsiObjectRef constructor); + void setExternalMemoryPressure(JsiObjectRef obj, uint32_t size); void ReleaseSymbol(JsiSymbolRef const &symbol); void ReleaseBigInt(JsiBigIntRef const &bigInt); diff --git a/vnext/Microsoft.ReactNative/JsiApi.idl b/vnext/Microsoft.ReactNative/JsiApi.idl index d3418b48c35..75b785c06d3 100644 --- a/vnext/Microsoft.ReactNative/JsiApi.idl +++ b/vnext/Microsoft.ReactNative/JsiApi.idl @@ -328,6 +328,7 @@ namespace Microsoft.ReactNative Boolean ObjectStrictEquals(JsiObjectRef left, JsiObjectRef right); Boolean InstanceOf(JsiObjectRef obj, JsiObjectRef constructor); + void setExternalMemoryPressure(JsiObjectRef obj, UInt32 amt); void ReleaseSymbol(JsiSymbolRef symbol); void ReleaseBigInt(JsiBigIntRef bigInt); diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h new file mode 100644 index 00000000000..faa6e00e73d --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h @@ -0,0 +1,810 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include + +#include +#include + +// This file contains objects to help API users create their own +// runtime adapters, i.e. if you want to compose runtimes to add your +// own behavior. + +namespace facebook { +namespace jsi { + +// Use this to wrap host functions. It will pass the member runtime as +// the first arg to the callback. The first argument to the ctor +// should be the decorated runtime, not the plain one. +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); + } + + private: + template + friend class RuntimeDecorator; + + Runtime& drt_; + HostFunctionType plainHF_; +}; + +// From the perspective of the caller, a plain HostObject is passed to +// the decorated Runtime, and the HostObject methods expect to get +// passed that Runtime. But the plain Runtime will pass itself to its +// callback, so we need a helper here which curries the decorated +// Runtime, and calls the plain HostObject with it. +// +// If the concrete RuntimeDecorator derives DecoratedHostObject, it +// should call the base class get() and set() to invoke the plain +// HostObject functionality. The Runtime& it passes does not matter, +// as it is not used. +class DecoratedHostObject : public HostObject { + public: + DecoratedHostObject(Runtime& drt, std::shared_ptr plainHO) + : drt_(drt), plainHO_(plainHO) {} + + // The derived class methods can call this to get a reference to the + // decorated runtime, since the rt passed to the callback will be + // the plain runtime. + 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 getPropertyNames(Runtime&) override { + return plainHO_->getPropertyNames(decoratedRuntime()); + } + + private: + template + friend class RuntimeDecorator; + + Runtime& drt_; + std::shared_ptr plainHO_; +}; + +/// C++ variant on a standard Decorator pattern, using template +/// parameters. The \c Plain template parameter type is the +/// undecorated Runtime type. You can usually use \c Runtime here, +/// but if you know the concrete type ahead of time and it's final, +/// the compiler can devirtualize calls to the decorated +/// implementation. The \c Base template parameter type will be used +/// as the base class of the decorated type. Here, too, you can +/// usually use \c Runtime, but if you want the decorated type to +/// implement a derived class of Runtime, you can specify that here. +/// For an example, see threadsafe.h. +template +class RuntimeDecorator : public Base, private jsi::Instrumentation { + public: + Plain& plain() { + static_assert( + std::is_base_of::value, + "RuntimeDecorator's Plain type must derive from jsi::Runtime"); + static_assert( + std::is_base_of::value, + "RuntimeDecorator's Base type must derive from jsi::Runtime"); + return plain_; + } + const Plain& plain() const { + return plain_; + } + + Value evaluateJavaScript( + const std::shared_ptr& buffer, + const std::string& sourceURL) override { + return plain().evaluateJavaScript(buffer, sourceURL); + } + std::shared_ptr prepareJavaScript( + const std::shared_ptr& buffer, + std::string sourceURL) override { + return plain().prepareJavaScript(buffer, std::move(sourceURL)); + } + Value evaluatePreparedJavaScript( + const std::shared_ptr& js) override { + return plain().evaluatePreparedJavaScript(js); + } + 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: + // plain is generally going to be a reference to an object managed + // by a derived class. We cache it here so this class can be + // concrete, and avoid making virtual calls to find the plain + // Runtime. Note that the ctor and dtor do not access through the + // reference, so passing a reference to an object before its + // lifetime has started is ok. + 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 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); + }; + std::string utf8(const String& s) override { + return plain_.utf8(s); + } + + Object createObject() override { + return plain_.createObject(); + }; + + Object createObject(std::shared_ptr ho) override { + return plain_.createObject( + std::make_shared(*this, std::move(ho))); + }; + std::shared_ptr getHostObject(const jsi::Object& o) override { + std::shared_ptr dho = plain_.getHostObject(o); + return static_cast(*dho).plainHO_; + }; + HostFunctionType& getHostFunction(const jsi::Function& f) override { + HostFunctionType& dhf = plain_.getHostFunction(f); + // This will fail if a cpp file including this header is not compiled + // with RTTI. + return dhf.target()->plainHF_; + }; + + bool hasNativeState(const Object& o) override { + return plain_.hasNativeState(o); + } + std::shared_ptr getNativeState(const Object& o) override { + return plain_.getNativeState(o); + } + void setNativeState(const Object& o, std::shared_ptr state) + override { + plain_.setNativeState(o, state); + } + + void setExternalMemoryPressure(const Object& obj, size_t amt) override { + plain_.setExternalMemoryPressure(obj, amt); + } + + 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 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); + }; + + // Private data for managing scopes. + 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); + }; + + // jsi::Instrumentation methods + + std::string getRecordedGCStats() override { + return plain().instrumentation().getRecordedGCStats(); + } + + std::unordered_map 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)> 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) override { + plain().instrumentation().createSnapshotToFile(path); + } + + void createSnapshotToStream(std::ostream& os) override { + plain().instrumentation().createSnapshotToStream(os); + } + + std::string flushAndDisableBridgeTrafficTrace() override { + return const_cast(plain()) + .instrumentation() + .flushAndDisableBridgeTrafficTrace(); + } + + void writeBasicBlockProfileTraceToFile( + const std::string& fileName) const override { + const_cast(plain()) + .instrumentation() + .writeBasicBlockProfileTraceToFile(fileName); + } + + /// Dump external profiler symbols to the given file name. + void dumpProfilerSymbolsToFile(const std::string& fileName) const override { + const_cast(plain()).instrumentation().dumpProfilerSymbolsToFile( + fileName); + } + + private: + Plain& plain_; +}; + +namespace detail { + +// This metaprogramming allows the With type's methods to be +// optional. + +template +struct BeforeCaller { + static void before(T&) {} +}; + +template +struct AfterCaller { + static void after(T&) {} +}; + +// decltype((void)&...) is either SFINAE, or void. +// So, if SFINAE does not happen for T, then this specialization exists +// for BeforeCaller, and always applies. If not, only the +// default above exists, and that is used instead. +template +struct BeforeCaller { + static void before(T& t) { + t.before(); + } +}; + +template +struct AfterCaller { + static void after(T& t) { + t.after(); + } +}; + +// It's possible to use multiple decorators by nesting +// WithRuntimeDecorator<...>, but this specialization allows use of +// std::tuple of decorator classes instead. See testlib.cpp for an +// example. +template +struct BeforeCaller> { + static void before(std::tuple& tuple) { + all_before<0, T...>(tuple); + } + + private: + template + static void all_before(std::tuple& tuple) { + detail::BeforeCaller::before(std::get(tuple)); + all_before(tuple); + } + + template + static void all_before(std::tuple&) {} +}; + +template +struct AfterCaller> { + static void after(std::tuple& tuple) { + all_after<0, T...>(tuple); + } + + private: + template + static void all_after(std::tuple& tuple) { + all_after(tuple); + detail::AfterCaller::after(std::get(tuple)); + } + + template + static void all_after(std::tuple&) {} +}; + +} // namespace detail + +// A decorator which implements an around idiom. A With instance is +// RAII constructed before each call to the undecorated class; the +// ctor is passed a single argument of type WithArg&. Plain and Base +// are used as in the base class. +template +class WithRuntimeDecorator : public RuntimeDecorator { + public: + using RD = RuntimeDecorator; + + // The reference arguments to the ctor are stored, but not used by + // the ctor, and there is no ctor, so they can be passed members of + // the derived class. + WithRuntimeDecorator(Plain& plain, With& with) : RD(plain), with_(with) {} + + Value evaluateJavaScript( + const std::shared_ptr& buffer, + const std::string& sourceURL) override { + Around around{with_}; + return RD::evaluateJavaScript(buffer, sourceURL); + } + std::shared_ptr prepareJavaScript( + const std::shared_ptr& buffer, + std::string sourceURL) override { + Around around{with_}; + return RD::prepareJavaScript(buffer, std::move(sourceURL)); + } + Value evaluatePreparedJavaScript( + const std::shared_ptr& js) override { + Around around{with_}; + return RD::evaluatePreparedJavaScript(js); + } + 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(); + }; + + // The jsi:: prefix is necessary because MSVC compiler complains C2247: + // Instrumentation is not accessible because RuntimeDecorator uses private + // to inherit from Instrumentation. + // TODO(T40821815) Consider removing this workaround when updating MSVC + 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* 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 createPropNameIDFromString(const String& str) override { + Around around{with_}; + return RD::createPropNameIDFromString(str); + }; + 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); + }; + + 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); + }; + std::string utf8(const String& s) override { + Around around{with_}; + return RD::utf8(s); + } + + Object createObject() override { + Around around{with_}; + return RD::createObject(); + }; + Object createObject(std::shared_ptr ho) override { + Around around{with_}; + return RD::createObject(std::move(ho)); + }; + std::shared_ptr 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); + }; + + 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 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); + }; + + // Private data for managing scopes. + 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 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); + }; + + private: + // Wrap an RAII type around With& to guarantee after always happens. + struct Around { + Around(With& with) : with_(with) { + detail::BeforeCaller::before(with_); + } + ~Around() { + detail::AfterCaller::after(with_); + } + + With& with_; + }; + + With& with_; +}; + +} // namespace jsi +} // namespace facebook \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h new file mode 100644 index 00000000000..3d9d3fa1a04 --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h @@ -0,0 +1,356 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +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(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 +inline Value toValue(Runtime& runtime, const T& other) { + static_assert( + std::is_base_of::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); +} + +/// Helper to throw while still compiling with exceptions turned off. +template +[[noreturn]] inline void throwOrDie(Args&&... args) { + std::rethrow_exception( + std::make_exception_ptr(E{std::forward(args)...})); +} + +} // namespace detail + +template +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 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 +void Object::setProperty(Runtime& runtime, const char* name, T&& value) const { + setProperty( + runtime, String::createFromAscii(runtime, name), std::forward(value)); +} + +template +void Object::setProperty(Runtime& runtime, const String& name, T&& value) + const { + setPropertyValue( + runtime, name, detail::toValue(runtime, std::forward(value))); +} + +template +void Object::setProperty(Runtime& runtime, const PropNameID& name, T&& value) + const { + setPropertyValue( + runtime, name, detail::toValue(runtime, std::forward(value))); +} + +inline Array Object::getArray(Runtime& runtime) const& { + assert(runtime.isArray(*this)); + (void)runtime; // when assert is disabled we need to mark this as used + return Array(runtime.cloneObject(ptr_)); +} + +inline Array Object::getArray(Runtime& runtime) && { + assert(runtime.isArray(*this)); + (void)runtime; // when assert is disabled we need to mark this as used + Runtime::PointerValue* value = ptr_; + ptr_ = nullptr; + return Array(value); +} + +inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) const& { + assert(runtime.isArrayBuffer(*this)); + (void)runtime; // when assert is disabled we need to mark this as used + return ArrayBuffer(runtime.cloneObject(ptr_)); +} + +inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && { + assert(runtime.isArrayBuffer(*this)); + (void)runtime; // when assert is disabled we need to mark this as used + 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; // when assert is disabled we need to mark this as used + Runtime::PointerValue* value = ptr_; + ptr_ = nullptr; + return Function(value); +} + +template +inline bool Object::isHostObject(Runtime& runtime) const { + return runtime.isHostObject(*this) && + std::dynamic_pointer_cast(runtime.getHostObject(*this)); +} + +template <> +inline bool Object::isHostObject(Runtime& runtime) const { + return runtime.isHostObject(*this); +} + +template +inline std::shared_ptr Object::getHostObject(Runtime& runtime) const { + assert(isHostObject(runtime)); + return std::static_pointer_cast(runtime.getHostObject(*this)); +} + +template +inline std::shared_ptr Object::asHostObject(Runtime& runtime) const { + if (!isHostObject(runtime)) { + detail::throwOrDie( + "Object is not a HostObject of desired type"); + } + return std::static_pointer_cast(runtime.getHostObject(*this)); +} + +template <> +inline std::shared_ptr Object::getHostObject( + Runtime& runtime) const { + assert(runtime.isHostObject(*this)); + return runtime.getHostObject(*this); +} + +template +inline bool Object::hasNativeState(Runtime& runtime) const { + return runtime.hasNativeState(*this) && + std::dynamic_pointer_cast(runtime.getNativeState(*this)); +} + +template <> +inline bool Object::hasNativeState(Runtime& runtime) const { + return runtime.hasNativeState(*this); +} + +template +inline std::shared_ptr Object::getNativeState(Runtime& runtime) const { + assert(hasNativeState(runtime)); + return std::static_pointer_cast(runtime.getNativeState(*this)); +} + +inline void Object::setNativeState( + Runtime& runtime, + std::shared_ptr 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 +void Array::setValueAtIndex(Runtime& runtime, size_t i, T&& value) const { + setValueAtIndexImpl( + runtime, i, detail::toValue(runtime, std::forward(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 args) + const { + return call(runtime, args.begin(), args.size()); +} + +template +inline Value Function::call(Runtime& runtime, Args&&... args) const { + // A more awesome version of this would be able to create raw values + // which can be used directly without wrapping and unwrapping, but + // this will do for now. + return call(runtime, {detail::toValue(runtime, std::forward(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 args) const { + return callWithThis(runtime, jsThis, args.begin(), args.size()); +} + +template +inline Value Function::callWithThis( + Runtime& runtime, + const Object& jsThis, + Args&&... args) const { + // A more awesome version of this would be able to create raw values + // which can be used directly without wrapping and unwrapping, but + // this will do for now. + return callWithThis( + runtime, jsThis, {detail::toValue(runtime, std::forward(args))...}); +} + +template +inline Array Array::createWithElements(Runtime& runtime, Args&&... args) { + return createWithElements( + runtime, {detail::toValue(runtime, std::forward(args))...}); +} + +template +inline std::vector PropNameID::names( + Runtime& runtime, + Args&&... args) { + return names({detail::toPropNameID(runtime, std::forward(args))...}); +} + +template +inline std::vector PropNameID::names( + PropNameID(&&propertyNames)[N]) { + std::vector 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 args) const { + return callAsConstructor(runtime, args.begin(), args.size()); +} + +template +inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args) + const { + return callAsConstructor( + runtime, {detail::toValue(runtime, std::forward(args))...}); +} + +String BigInt::toString(Runtime& runtime, int radix) const { + return runtime.bigintToString(*this, radix); +} + +} // namespace jsi +} // namespace facebook \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h new file mode 100644 index 00000000000..d93f07e707a --- /dev/null +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h @@ -0,0 +1,1524 @@ +/* + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#ifndef JSI_EXPORT +#ifdef _MSC_VER +#ifdef CREATE_SHARED_LIBRARY +#define JSI_EXPORT __declspec(dllexport) +#else +#define JSI_EXPORT +#endif // CREATE_SHARED_LIBRARY +#else // _MSC_VER +#define JSI_EXPORT __attribute__((visibility("default"))) +#endif // _MSC_VER +#endif // !defined(JSI_EXPORT) + +class FBJSRuntime; +namespace facebook { +namespace jsi { + +/// Base class for buffers of data or bytecode that need to be passed to the +/// runtime. The buffer is expected to be fully immutable, so the result of +/// size(), data(), and the contents of the pointer returned by data() must not +/// change after construction. +class JSI_EXPORT Buffer { + public: + virtual ~Buffer(); + virtual size_t size() const = 0; + virtual const uint8_t* data() const = 0; +}; + +class JSI_EXPORT 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(s_.data()); + } + + private: + std::string s_; +}; + +/// Base class for buffers of data that need to be passed to the runtime. The +/// result of size() and data() must not change after construction. However, the +/// region pointed to by data() may be modified by the user or the runtime. The +/// user must ensure that access to the contents of the buffer is properly +/// synchronised. +class JSI_EXPORT MutableBuffer { + public: + virtual ~MutableBuffer(); + virtual size_t size() const = 0; + virtual uint8_t* data() = 0; +}; + +/// PreparedJavaScript is a base class representing JavaScript which is in a +/// form optimized for execution, in a runtime-specific way. Construct one via +/// jsi::Runtime::prepareJavaScript(). +/// ** This is an experimental API that is subject to change. ** +class JSI_EXPORT PreparedJavaScript { + protected: + PreparedJavaScript() = default; + + public: + virtual ~PreparedJavaScript() = 0; +}; + +class Runtime; +class Pointer; +class PropNameID; +class Symbol; +class BigInt; +class String; +class Object; +class WeakObject; +class Array; +class ArrayBuffer; +class Function; +class Value; +class Instrumentation; +class Scope; +class JSIException; +class JSError; + +/// A function which has this type can be registered as a function +/// callable from JavaScript using Function::createFromHostFunction(). +/// When the function is called, args will point to the arguments, and +/// count will indicate how many arguments are passed. The function +/// can return a Value to the caller, or throw an exception. If a C++ +/// exception is thrown, a JS Error will be created and thrown into +/// JS; if the C++ exception extends std::exception, the Error's +/// message will be whatever what() returns. Note that it is undefined whether +/// HostFunctions may or may not be called in strict mode; that is `thisVal` +/// can be any value - it will not necessarily be coerced to an object or +/// or set to the global object. +using HostFunctionType = std::function< + Value(Runtime& rt, const Value& thisVal, const Value* args, size_t count)>; + +/// An object which implements this interface can be registered as an +/// Object with the JS runtime. +class JSI_EXPORT HostObject { + public: + // The C++ object's dtor will be called when the GC finalizes this + // object. (This may be as late as when the Runtime is shut down.) + // You have no control over which thread it is called on. This will + // be called from inside the GC, so it is unsafe to do any VM + // operations which require a Runtime&. Derived classes' dtors + // should also avoid doing anything expensive. Calling the dtor on + // a jsi object is explicitly ok. If you want to do JS operations, + // or any nontrivial work, you should add it to a work queue, and + // manage it externally. + virtual ~HostObject(); + + // When JS wants a property with a given name from the HostObject, + // it will call this method. If it throws an exception, the call + // will throw a JS \c Error object. By default this returns undefined. + // \return the value for the property. + virtual Value get(Runtime&, const PropNameID& name); + + // When JS wants to set a property with a given name on the HostObject, + // it will call this method. If it throws an exception, the call will + // throw a JS \c Error object. By default this throws a type error exception + // mimicking the behavior of a frozen object in strict mode. + virtual void set(Runtime&, const PropNameID& name, const Value& value); + + // When JS wants a list of property names for the HostObject, it will + // call this method. If it throws an exception, the call will throw a + // JS \c Error object. The default implementation returns empty vector. + virtual std::vector getPropertyNames(Runtime& rt); +}; + +/// Native state (and destructor) that can be attached to any JS object +/// using setNativeState. +class JSI_EXPORT NativeState { + public: + virtual ~NativeState(); +}; + +/// Represents a JS runtime. Movable, but not copyable. Note that +/// this object may not be thread-aware, but cannot be used safely from +/// multiple threads at once. The application is responsible for +/// ensuring that it is used safely. This could mean using the +/// Runtime from a single thread, using a mutex, doing all work on a +/// serial queue, etc. This restriction applies to the methods of +/// this class, and any method in the API which take a Runtime& as an +/// argument. Destructors (all but ~Scope), operators, or other methods +/// which do not take Runtime& as an argument are safe to call from any +/// thread, but it is still forbidden to make write operations on a single +/// instance of any class from more than one thread. In addition, to +/// make shutdown safe, destruction of objects associated with the Runtime +/// must be destroyed before the Runtime is destroyed, or from the +/// destructor of a managed HostObject or HostFunction. Informally, this +/// means that the main source of unsafe behavior is to hold a jsi object +/// in a non-Runtime-managed object, and not clean it up before the Runtime +/// is shut down. If your lifecycle is such that avoiding this is hard, +/// you will probably need to do use your own locks. +class JSI_EXPORT Runtime { + public: + virtual ~Runtime(); + + /// Evaluates the given JavaScript \c buffer. \c sourceURL is used + /// to annotate the stack trace if there is an exception. The + /// contents may be utf8-encoded JS source code, or binary bytecode + /// whose format is specific to the implementation. If the input + /// format is unknown, or evaluation causes an error, a JSIException + /// will be thrown. + /// Note this function should ONLY be used when there isn't another means + /// through the JSI API. For example, it will be much slower to use this to + /// call a global function than using the JSI APIs to read the function + /// property from the global object and then calling it explicitly. + virtual Value evaluateJavaScript( + const std::shared_ptr& buffer, + const std::string& sourceURL) = 0; + + /// Prepares to evaluate the given JavaScript \c buffer by processing it into + /// a form optimized for execution. This may include pre-parsing, compiling, + /// etc. If the input is invalid (for example, cannot be parsed), a + /// JSIException will be thrown. The resulting object is tied to the + /// particular concrete type of Runtime from which it was created. It may be + /// used (via evaluatePreparedJavaScript) in any Runtime of the same concrete + /// type. + /// The PreparedJavaScript object may be passed to multiple VM instances, so + /// they can all share and benefit from the prepared script. + /// As with evaluateJavaScript(), using JavaScript code should be avoided + /// when the JSI API is sufficient. + virtual std::shared_ptr prepareJavaScript( + const std::shared_ptr& buffer, + std::string sourceURL) = 0; + + /// Evaluates a PreparedJavaScript. If evaluation causes an error, a + /// JSIException will be thrown. + /// As with evaluateJavaScript(), using JavaScript code should be avoided + /// when the JSI API is sufficient. + virtual Value evaluatePreparedJavaScript( + const std::shared_ptr& js) = 0; + + /// Drain the JavaScript VM internal Microtask (a.k.a. Job in ECMA262) queue. + /// + /// \param maxMicrotasksHint a hint to tell an implementation that it should + /// make a best effort not execute more than the given number. It's default + /// to -1 for infinity (unbounded execution). + /// \return true if the queue is drained or false if there is more work to do. + /// + /// When there were exceptions thrown from the execution of microtasks, + /// implementations shall discard the exceptional jobs. An implementation may + /// \throw a \c JSError object to signal the hosts to handle. In that case, an + /// implementation may or may not suspend the draining. + /// + /// Hosts may call this function again to resume the draining if it was + /// suspended due to either exceptions or the \p maxMicrotasksHint bound. + /// E.g. a host may repetitively invoke this function until the queue is + /// drained to implement the "microtask checkpoint" defined in WHATWG HTML + /// event loop: https://html.spec.whatwg.org/C#perform-a-microtask-checkpoint. + /// + /// Note that error propagation is only a concern if a host needs to implement + /// `queueMicrotask`, a recent API that allows enqueueing arbitrary functions + /// (hence may throw) as microtasks. Exceptions from ECMA-262 Promise Jobs are + /// handled internally to VMs and are never propagated to hosts. + /// + /// This API offers some queue management to hosts at its best effort due to + /// different behaviors and limitations imposed by different VMs and APIs. By + /// the time this is written, An implementation may swallow exceptions (JSC), + /// may not pause (V8), and may not support bounded executions. + virtual bool drainMicrotasks(int maxMicrotasksHint = -1) = 0; + + /// \return the global object + virtual Object global() = 0; + + /// \return a short printable description of the instance. It should + /// at least include some human-readable indication of the runtime + /// implementation. This should only be used by logging, debugging, + /// and other developer-facing callers. + virtual std::string description() = 0; + + /// \return whether or not the underlying runtime supports debugging via the + /// Chrome remote debugging protocol. + /// + /// NOTE: the API for determining whether a runtime is debuggable and + /// registering a runtime with the debugger is still in flux, so please don't + /// use this API unless you know what you're doing. + virtual bool isInspectable() = 0; + + /// \return an interface to extract metrics from this \c Runtime. The default + /// implementation of this function returns an \c Instrumentation instance + /// which returns no metrics. + virtual Instrumentation& instrumentation(); + + protected: + friend class Pointer; + friend class PropNameID; + friend class Symbol; + friend class BigInt; + friend class String; + friend class Object; + friend class WeakObject; + friend class Array; + friend class ArrayBuffer; + friend class Function; + friend class Value; + friend class Scope; + friend class JSError; + + // Potential optimization: avoid the cloneFoo() virtual dispatch, + // and instead just fix the number of fields, and copy them, since + // in practice they are trivially copyable. Sufficient use of + // rvalue arguments/methods would also reduce the number of clones. + + struct PointerValue { + virtual void invalidate() = 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 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 std::string utf8(const String&) = 0; + + // \return a \c Value created from a utf8-encoded JSON string. The default + // implementation creates a \c String and invokes JSON.parse. + virtual Value createValueFromJsonUtf8(const uint8_t* json, size_t length); + + virtual Object createObject() = 0; + virtual Object createObject(std::shared_ptr ho) = 0; + virtual std::shared_ptr getHostObject(const jsi::Object&) = 0; + virtual HostFunctionType& getHostFunction(const jsi::Function&) = 0; + + virtual bool hasNativeState(const jsi::Object&) = 0; + virtual std::shared_ptr getNativeState(const jsi::Object&) = 0; + virtual void setNativeState( + const jsi::Object&, + std::shared_ptr state) = 0; + + 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 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; + + // Private data for managing scopes. + struct ScopeState; + 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; + + /// See Object::setExternalMemoryPressure. + virtual void setExternalMemoryPressure( + const jsi::Object& obj, + size_t amount) = 0; + + // These exist so derived classes can access the private parts of + // Value, Symbol, String, and Object, which are all friends of Runtime. + template + 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 class ::FBJSRuntime; + template + friend class RuntimeDecorator; +}; + +// Base class for pointer-storing types. +class JSI_EXPORT Pointer { + protected: + explicit Pointer(Pointer&& other) : ptr_(other.ptr_) { + other.ptr_ = nullptr; + } + + ~Pointer() { + if (ptr_) { + ptr_->invalidate(); + } + } + + Pointer& operator=(Pointer&& other); + + friend class Runtime; + friend class Value; + + explicit Pointer(Runtime::PointerValue* ptr) : ptr_(ptr) {} + + typename Runtime::PointerValue* ptr_; +}; + +/// Represents something that can be a JS property key. Movable, not copyable. +class JSI_EXPORT 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; + + /// Create a JS property name id from ascii values. The data is + /// copied. + static PropNameID forAscii(Runtime& runtime, const char* str, size_t length) { + return runtime.createPropNameIDFromAscii(str, length); + } + + /// Create a property name id from a nul-terminated C ascii name. The data is + /// copied. + static PropNameID forAscii(Runtime& runtime, const char* str) { + return forAscii(runtime, str, strlen(str)); + } + + /// Create a PropNameID from a C++ string. The string is copied. + static PropNameID forAscii(Runtime& runtime, const std::string& str) { + return forAscii(runtime, str.c_str(), str.size()); + } + + /// Create a PropNameID from utf8 values. The data is copied. + /// Results are undefined if \p utf8 contains invalid code points. + static PropNameID + forUtf8(Runtime& runtime, const uint8_t* utf8, size_t length) { + return runtime.createPropNameIDFromUtf8(utf8, length); + } + + /// Create a PropNameID from utf8-encoded octets stored in a + /// std::string. The string data is transformed and copied. + /// Results are undefined if \p utf8 contains invalid code points. + static PropNameID forUtf8(Runtime& runtime, const std::string& utf8) { + return runtime.createPropNameIDFromUtf8( + reinterpret_cast(utf8.data()), utf8.size()); + } + + /// Create a PropNameID from a JS string. + static PropNameID forString(Runtime& runtime, const jsi::String& str) { + return runtime.createPropNameIDFromString(str); + } + + /// Create a PropNameID from a JS symbol. + static PropNameID forSymbol(Runtime& runtime, const jsi::Symbol& sym) { + return runtime.createPropNameIDFromSymbol(sym); + } + + // Creates a vector of PropNameIDs constructed from given arguments. + template + static std::vector names(Runtime& runtime, Args&&... args); + + // Creates a vector of given PropNameIDs. + template + static std::vector names(PropNameID(&&propertyNames)[N]); + + /// Copies the data in a PropNameID as utf8 into a C++ string. + std::string utf8(Runtime& runtime) const { + return runtime.utf8(*this); + } + + static bool compare( + Runtime& runtime, + const jsi::PropNameID& a, + const jsi::PropNameID& b) { + return runtime.compare(a, b); + } + + friend class Runtime; + friend class Value; +}; + +/// Represents a JS Symbol (es6). Movable, not copyable. +/// TODO T40778724: this is a limited implementation sufficient for +/// the debugger not to crash when a Symbol is a property in an Object +/// or element in an array. Complete support for creating will come +/// later. +class JSI_EXPORT Symbol : public Pointer { + public: + using Pointer::Pointer; + + Symbol(Symbol&& other) = default; + Symbol& operator=(Symbol&& other) = default; + + /// \return whether a and b refer to the same symbol. + static bool strictEquals(Runtime& runtime, const Symbol& a, const Symbol& b) { + return runtime.strictEquals(a, b); + } + + /// Converts a Symbol into a C++ string as JS .toString would. The output + /// will look like \c Symbol(description) . + std::string toString(Runtime& runtime) const { + return runtime.symbolToString(*this); + } + + friend class Runtime; + friend class Value; +}; + +/// Represents a JS BigInt. Movable, not copyable. +class JSI_EXPORT BigInt : public Pointer { + public: + using Pointer::Pointer; + + BigInt(BigInt&& other) = default; + BigInt& operator=(BigInt&& other) = default; + + /// Create a BigInt representing the signed 64-bit \p value. + static BigInt fromInt64(Runtime& runtime, int64_t value) { + return runtime.createBigIntFromInt64(value); + } + + /// Create a BigInt representing the unsigned 64-bit \p value. + static BigInt fromUint64(Runtime& runtime, uint64_t value) { + return runtime.createBigIntFromUint64(value); + } + + /// \return whether a === b. + static bool strictEquals(Runtime& runtime, const BigInt& a, const BigInt& b) { + return runtime.strictEquals(a, b); + } + + /// \returns This bigint truncated to a signed 64-bit integer. + int64_t getInt64(Runtime& runtime) const { + return runtime.truncate(*this); + } + + /// \returns Whether this bigint can be losslessly converted to int64_t. + bool isInt64(Runtime& runtime) const { + return runtime.bigintIsInt64(*this); + } + + /// \returns This bigint truncated to a signed 64-bit integer. Throws a + /// JSIException if the truncation is lossy. + int64_t asInt64(Runtime& runtime) const; + + /// \returns This bigint truncated to an unsigned 64-bit integer. + uint64_t getUint64(Runtime& runtime) const { + return runtime.truncate(*this); + } + + /// \returns Whether this bigint can be losslessly converted to uint64_t. + bool isUint64(Runtime& runtime) const { + return runtime.bigintIsUint64(*this); + } + + /// \returns This bigint truncated to an unsigned 64-bit integer. Throws a + /// JSIException if the truncation is lossy. + uint64_t asUint64(Runtime& runtime) const; + + /// \returns this BigInt converted to a String in base \p radix. Throws a + /// JSIException if radix is not in the [2, 36] range. + inline String toString(Runtime& runtime, int radix = 10) const; + + friend class Runtime; + friend class Value; +}; + +/// Represents a JS String. Movable, not copyable. +class JSI_EXPORT String : public Pointer { + public: + using Pointer::Pointer; + + String(String&& other) = default; + String& operator=(String&& other) = default; + + /// Create a JS string from ascii values. The string data is + /// copied. + static String + createFromAscii(Runtime& runtime, const char* str, size_t length) { + return runtime.createStringFromAscii(str, length); + } + + /// Create a JS string from a nul-terminated C ascii string. The + /// string data is copied. + static String createFromAscii(Runtime& runtime, const char* str) { + return createFromAscii(runtime, str, strlen(str)); + } + + /// Create a JS string from a C++ string. The string data is + /// copied. + static String createFromAscii(Runtime& runtime, const std::string& str) { + return createFromAscii(runtime, str.c_str(), str.size()); + } + + /// Create a JS string from utf8-encoded octets. The string data is + /// transformed and copied. Results are undefined if \p utf8 contains invalid + /// code points. + static String + createFromUtf8(Runtime& runtime, const uint8_t* utf8, size_t length) { + return runtime.createStringFromUtf8(utf8, length); + } + + /// Create a JS string from utf8-encoded octets stored in a + /// std::string. The string data is transformed and copied. Results are + /// undefined if \p utf8 contains invalid code points. + static String createFromUtf8(Runtime& runtime, const std::string& utf8) { + return runtime.createStringFromUtf8( + reinterpret_cast(utf8.data()), utf8.length()); + } + + /// \return whether a and b contain the same characters. + static bool strictEquals(Runtime& runtime, const String& a, const String& b) { + return runtime.strictEquals(a, b); + } + + /// Copies the data in a JS string as utf8 into a C++ string. + std::string utf8(Runtime& runtime) const { + return runtime.utf8(*this); + } + + friend class Runtime; + friend class Value; +}; + +class Array; +class Function; + +/// Represents a JS Object. Movable, not copyable. +class JSI_EXPORT Object : public Pointer { + public: + using Pointer::Pointer; + + Object(Object&& other) = default; + Object& operator=(Object&& other) = default; + + /// Creates a new Object instance, like '{}' in JS. + Object(Runtime& runtime) : Object(runtime.createObject()) {} + + static Object createFromHostObject( + Runtime& runtime, + std::shared_ptr ho) { + return runtime.createObject(ho); + } + + /// \return whether this and \c obj are the same JSObject or not. + static bool strictEquals(Runtime& runtime, const Object& a, const Object& b) { + return runtime.strictEquals(a, b); + } + + /// \return the result of `this instanceOf ctor` in JS. + bool instanceOf(Runtime& rt, const Function& ctor) const { + return rt.instanceOf(*this, ctor); + } + + /// \return the property of the object with the given ascii name. + /// If the name isn't a property on the object, returns the + /// undefined value. + Value getProperty(Runtime& runtime, const char* name) const; + + /// \return the property of the object with the String name. + /// If the name isn't a property on the object, returns the + /// undefined value. + Value getProperty(Runtime& runtime, const String& name) const; + + /// \return the property of the object with the given JS PropNameID + /// name. If the name isn't a property on the object, returns the + /// undefined value. + Value getProperty(Runtime& runtime, const PropNameID& name) const; + + /// \return true if and only if the object has a property with the + /// given ascii name. + bool hasProperty(Runtime& runtime, const char* name) const; + + /// \return true if and only if the object has a property with the + /// given String name. + bool hasProperty(Runtime& runtime, const String& name) const; + + /// \return true if and only if the object has a property with the + /// given PropNameID name. + bool hasProperty(Runtime& runtime, const PropNameID& name) const; + + /// Sets the property value from a Value or anything which can be + /// used to make one: nullptr_t, bool, double, int, const char*, + /// String, or Object. + template + void setProperty(Runtime& runtime, const char* name, T&& value) const; + + /// Sets the property value from a Value or anything which can be + /// used to make one: nullptr_t, bool, double, int, const char*, + /// String, or Object. + template + void setProperty(Runtime& runtime, const String& name, T&& value) const; + + /// Sets the property value from a Value or anything which can be + /// used to make one: nullptr_t, bool, double, int, const char*, + /// String, or Object. + template + void setProperty(Runtime& runtime, const PropNameID& name, T&& value) const; + + /// \return true iff JS \c Array.isArray() would return \c true. If + /// so, then \c getArray() will succeed. + bool isArray(Runtime& runtime) const { + return runtime.isArray(*this); + } + + /// \return true iff the Object is an ArrayBuffer. If so, then \c + /// getArrayBuffer() will succeed. + bool isArrayBuffer(Runtime& runtime) const { + return runtime.isArrayBuffer(*this); + } + + /// \return true iff the Object is callable. If so, then \c + /// getFunction will succeed. + bool isFunction(Runtime& runtime) const { + return runtime.isFunction(*this); + } + + /// \return true iff the Object was initialized with \c createFromHostObject + /// and the HostObject passed is of type \c T. If returns \c true then + /// \c getHostObject will succeed. + template + bool isHostObject(Runtime& runtime) const; + + /// \return an Array instance which refers to the same underlying + /// object. If \c isArray() would return false, this will assert. + Array getArray(Runtime& runtime) const&; + + /// \return an Array instance which refers to the same underlying + /// object. If \c isArray() would return false, this will assert. + Array getArray(Runtime& runtime) &&; + + /// \return an Array instance which refers to the same underlying + /// object. If \c isArray() would return false, this will throw + /// JSIException. + Array asArray(Runtime& runtime) const&; + + /// \return an Array instance which refers to the same underlying + /// object. If \c isArray() would return false, this will throw + /// JSIException. + Array asArray(Runtime& runtime) &&; + + /// \return an ArrayBuffer instance which refers to the same underlying + /// object. If \c isArrayBuffer() would return false, this will assert. + ArrayBuffer getArrayBuffer(Runtime& runtime) const&; + + /// \return an ArrayBuffer instance which refers to the same underlying + /// object. If \c isArrayBuffer() would return false, this will assert. + ArrayBuffer getArrayBuffer(Runtime& runtime) &&; + + /// \return a Function instance which refers to the same underlying + /// object. If \c isFunction() would return false, this will assert. + Function getFunction(Runtime& runtime) const&; + + /// \return a Function instance which refers to the same underlying + /// object. If \c isFunction() would return false, this will assert. + Function getFunction(Runtime& runtime) &&; + + /// \return a Function instance which refers to the same underlying + /// object. If \c isFunction() would return false, this will throw + /// JSIException. + Function asFunction(Runtime& runtime) const&; + + /// \return a Function instance which refers to the same underlying + /// object. If \c isFunction() would return false, this will throw + /// JSIException. + Function asFunction(Runtime& runtime) &&; + + /// \return a shared_ptr which refers to the same underlying + /// \c HostObject that was used to create this object. If \c isHostObject + /// is false, this will assert. Note that this does a type check and will + /// assert if the underlying HostObject isn't of type \c T + template + std::shared_ptr getHostObject(Runtime& runtime) const; + + /// \return a shared_ptr which refers to the same underlying + /// \c HostObject that was used to create this object. If \c isHostObject + /// is false, this will throw. + template + std::shared_ptr asHostObject(Runtime& runtime) const; + + /// \return whether this object has native state of type T previously set by + /// \c setNativeState. + template + bool hasNativeState(Runtime& runtime) const; + + /// \return a shared_ptr to the state previously set by \c setNativeState. + /// If \c hasNativeState is false, this will assert. Note that this does a + /// type check and will assert if the native state isn't of type \c T + template + std::shared_ptr getNativeState(Runtime& runtime) const; + + /// Set the internal native state property of this object, overwriting any old + /// value. Creates a new shared_ptr to the object managed by \p state, which + /// will live until the value at this property becomes unreachable. + /// + /// Throws a type error if this object is a proxy or host object. + void setNativeState(Runtime& runtime, std::shared_ptr state) + const; + + /// \return same as \c getProperty(name).asObject(), except with + /// a better exception message. + Object getPropertyAsObject(Runtime& runtime, const char* name) const; + + /// \return similar to \c + /// getProperty(name).getObject().getFunction(), except it will + /// throw JSIException instead of asserting if the property is + /// not an object, or the object is not callable. + Function getPropertyAsFunction(Runtime& runtime, const char* name) const; + + /// \return an Array consisting of all enumerable property names in + /// the object and its prototype chain. All values in the return + /// will be isString(). (This is probably not optimal, but it + /// works. I only need it in one place.) + Array getPropertyNames(Runtime& runtime) const; + + /// Inform the runtime that there is additional memory associated with a given + /// JavaScript object that is not visible to the GC. This can be used if an + /// object is known to retain some native memory, and may be used to guide + /// decisions about when to run garbage collection. + /// This method may be invoked multiple times on an object, and subsequent + /// calls will overwrite any previously set value. Once the object is garbage + /// collected, the associated external memory will be considered freed and may + /// no longer factor into GC decisions. + 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 class Runtime; + friend class Value; +}; + +/// Represents a weak reference to a JS Object. If the only reference +/// to an Object are these, the object is eligible for GC. Method +/// names are inspired by C++ weak_ptr. Movable, not copyable. +class JSI_EXPORT WeakObject : public Pointer { + public: + using Pointer::Pointer; + + WeakObject(WeakObject&& other) = default; + WeakObject& operator=(WeakObject&& other) = default; + + /// Create a WeakObject from an Object. + WeakObject(Runtime& runtime, const Object& o) + : WeakObject(runtime.createWeakObject(o)) {} + + /// \return a Value representing the underlying Object if it is still valid; + /// otherwise returns \c undefined. Note that this method has nothing to do + /// with threads or concurrency. The name is based on std::weak_ptr::lock() + /// which serves a similar purpose. + Value lock(Runtime& runtime) const; + + friend class Runtime; +}; + +/// Represents a JS Object which can be efficiently used as an array +/// with integral indices. +class JSI_EXPORT Array : public Object { + public: + Array(Array&&) = default; + /// Creates a new Array instance, with \c length undefined elements. + Array(Runtime& runtime, size_t length) : Array(runtime.createArray(length)) {} + + Array& operator=(Array&&) = default; + + /// \return the size of the Array, according to its length property. + /// (C++ naming convention) + size_t size(Runtime& runtime) const { + return runtime.size(*this); + } + + /// \return the size of the Array, according to its length property. + /// (JS naming convention) + size_t length(Runtime& runtime) const { + return size(runtime); + } + + /// \return the property of the array at index \c i. If there is no + /// such property, returns the undefined value. If \c i is out of + /// range [ 0..\c length ] throws a JSIException. + Value getValueAtIndex(Runtime& runtime, size_t i) const; + + /// Sets the property of the array at index \c i. The argument + /// value behaves as with Object::setProperty(). If \c i is out of + /// range [ 0..\c length ] throws a JSIException. + template + void setValueAtIndex(Runtime& runtime, size_t i, T&& value) const; + + /// There is no current API for changing the size of an array once + /// created. We'll probably need that eventually. + + /// Creates a new Array instance from provided values + template + static Array createWithElements(Runtime&, Args&&... args); + + /// Creates a new Array instance from initializer list. + static Array createWithElements( + Runtime& runtime, + std::initializer_list elements); + + private: + friend class Object; + friend class Value; + friend class Runtime; + + void setValueAtIndexImpl(Runtime& runtime, size_t i, const Value& value) + const { + return runtime.setValueAtIndexImpl(*this, i, value); + } + + Array(Runtime::PointerValue* value) : Object(value) {} +}; + +/// Represents a JSArrayBuffer +class JSI_EXPORT ArrayBuffer : public Object { + public: + ArrayBuffer(ArrayBuffer&&) = default; + ArrayBuffer& operator=(ArrayBuffer&&) = default; + + ArrayBuffer(Runtime& runtime, std::shared_ptr buffer) + : ArrayBuffer(runtime.createArrayBuffer(std::move(buffer))) {} + + /// \return the size of the ArrayBuffer storage. This is not affected by + /// overriding the byteLength property. + /// (C++ naming convention) + 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); + } + + private: + friend class Object; + friend class Value; + friend class Runtime; + + ArrayBuffer(Runtime::PointerValue* value) : Object(value) {} +}; + +/// Represents a JS Object which is guaranteed to be Callable. +class JSI_EXPORT Function : public Object { + public: + Function(Function&&) = default; + Function& operator=(Function&&) = default; + + /// Create a function which, when invoked, calls C++ code. If the + /// function throws an exception, a JS Error will be created and + /// thrown. + /// \param name the name property for the function. + /// \param paramCount the length property for the function, which + /// may not be the number of arguments the function is passed. + static Function createFromHostFunction( + Runtime& runtime, + const jsi::PropNameID& name, + unsigned int paramCount, + jsi::HostFunctionType func); + + /// Calls the function with \c count \c args. The \c this value of the JS + /// function will not be set by the C++ caller, similar to calling + /// Function.prototype.apply(undefined, args) in JS. + /// \b Note: as with Function.prototype.apply, \c this may not always be + /// \c undefined in the function itself. If the function is non-strict, + /// \c this will be set to the global object. + Value call(Runtime& runtime, const Value* args, size_t count) const; + + /// Calls the function with a \c std::initializer_list of Value + /// arguments. The \c this value of the JS function will not be set by the + /// C++ caller, similar to calling Function.prototype.apply(undefined, args) + /// in JS. + /// \b Note: as with Function.prototype.apply, \c this may not always be + /// \c undefined in the function itself. If the function is non-strict, + /// \c this will be set to the global object. + Value call(Runtime& runtime, std::initializer_list args) const; + + /// Calls the function with any number of arguments similarly to + /// Object::setProperty(). The \c this value of the JS function will not be + /// set by the C++ caller, similar to calling + /// Function.prototype.call(undefined, ...args) in JS. + /// \b Note: as with Function.prototype.call, \c this may not always be + /// \c undefined in the function itself. If the function is non-strict, + /// \c this will be set to the global object. + template + Value call(Runtime& runtime, Args&&... args) const; + + /// Calls the function with \c count \c args and \c jsThis value passed + /// as the \c this value. + Value callWithThis( + Runtime& Runtime, + const Object& jsThis, + const Value* args, + size_t count) const; + + /// Calls the function with a \c std::initializer_list of Value + /// arguments and \c jsThis passed as the \c this value. + Value callWithThis( + Runtime& runtime, + const Object& jsThis, + std::initializer_list args) const; + + /// Calls the function with any number of arguments similarly to + /// Object::setProperty(), and with \c jsThis passed as the \c this value. + template + Value callWithThis(Runtime& runtime, const Object& jsThis, Args&&... args) + const; + + /// Calls the function as a constructor with \c count \c args. Equivalent + /// to calling `new Func` where `Func` is the js function reqresented by + /// this. + Value callAsConstructor(Runtime& runtime, const Value* args, size_t count) + const; + + /// Same as above `callAsConstructor`, except use an initializer_list to + /// supply the arguments. + Value callAsConstructor(Runtime& runtime, std::initializer_list args) + const; + + /// Same as above `callAsConstructor`, but automatically converts/wraps + /// any argument with a jsi Value. + template + Value callAsConstructor(Runtime& runtime, Args&&... args) const; + + /// Returns whether this was created with Function::createFromHostFunction. + /// If true then you can use getHostFunction to get the underlying + /// HostFunctionType. + bool isHostFunction(Runtime& runtime) const { + return runtime.isHostFunction(*this); + } + + /// Returns the underlying HostFunctionType iff isHostFunction returns true + /// and asserts otherwise. You can use this to use std::function<>::target + /// to get the object that was passed to create the HostFunctionType. + /// + /// Note: The reference returned is borrowed from the JS object underlying + /// \c this, and thus only lasts as long as the object underlying + /// \c this does. + HostFunctionType& getHostFunction(Runtime& runtime) const { + assert(isHostFunction(runtime)); + return runtime.getHostFunction(*this); + } + + private: + friend class Object; + friend class Value; + friend class Runtime; + + Function(Runtime::PointerValue* value) : Object(value) {} +}; + +/// Represents any JS Value (undefined, null, boolean, number, symbol, +/// string, or object). Movable, or explicitly copyable (has no copy +/// ctor). +class JSI_EXPORT Value { + public: + /// Default ctor creates an \c undefined JS value. + Value() : Value(UndefinedKind) {} + + /// Creates a \c null JS value. + /* implicit */ Value(std::nullptr_t) : kind_(NullKind) {} + + /// Creates a boolean JS value. + /* implicit */ Value(bool b) : Value(BooleanKind) { + data_.boolean = b; + } + + /// Creates a number JS value. + /* implicit */ Value(double d) : Value(NumberKind) { + data_.number = d; + } + + /// Creates a number JS value. + /* implicit */ Value(int i) : Value(NumberKind) { + data_.number = i; + } + + /// Moves a Symbol, String, or Object rvalue into a new JS value. + template < + typename T, + typename = std::enable_if_t< + std::is_base_of::value || + std::is_base_of::value || + std::is_base_of::value || + std::is_base_of::value>> + /* implicit */ Value(T&& other) : Value(kindOf(other)) { + new (&data_.pointer) T(std::move(other)); + } + + /// Value("foo") will treat foo as a bool. This makes doing that a + /// compile error. + template + Value(const char*) { + static_assert( + !std::is_same::value, + "Value cannot be constructed directly from const char*"); + } + + Value(Value&& value); + + /// Copies a Symbol lvalue into a new JS value. + Value(Runtime& runtime, const Symbol& sym) : Value(SymbolKind) { + new (&data_.pointer) Symbol(runtime.cloneSymbol(sym.ptr_)); + } + + /// Copies a BigInt lvalue into a new JS value. + Value(Runtime& runtime, const BigInt& bigint) : Value(BigIntKind) { + new (&data_.pointer) BigInt(runtime.cloneBigInt(bigint.ptr_)); + } + + /// Copies a String lvalue into a new JS value. + Value(Runtime& runtime, const String& str) : Value(StringKind) { + new (&data_.pointer) String(runtime.cloneString(str.ptr_)); + } + + /// Copies a Object lvalue into a new JS value. + Value(Runtime& runtime, const Object& obj) : Value(ObjectKind) { + new (&data_.pointer) Object(runtime.cloneObject(obj.ptr_)); + } + + /// Creates a JS value from another Value lvalue. + Value(Runtime& runtime, const Value& value); + + /// Value(rt, "foo") will treat foo as a bool. This makes doing + /// that a compile error. + template + Value(Runtime&, const char*) { + static_assert( + !std::is_same::value, + "Value cannot be constructed directly from const char*"); + } + + ~Value(); + // \return the undefined \c Value. + static Value undefined() { + return Value(); + } + + // \return the null \c Value. + static Value null() { + return Value(nullptr); + } + + // \return a \c Value created from a utf8-encoded JSON string. + static Value + createFromJsonUtf8(Runtime& runtime, const uint8_t* json, size_t length) { + return runtime.createValueFromJsonUtf8(json, length); + } + + /// \return according to the Strict Equality Comparison algorithm, see: + /// https://262.ecma-international.org/11.0/#sec-strict-equality-comparison + static bool strictEquals(Runtime& runtime, const Value& a, const Value& b); + + Value& operator=(Value&& other) { + 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; + } + + /// \return the boolean value, or asserts if not a boolean. + bool getBool() const { + assert(isBool()); + return data_.boolean; + } + + /// \return the boolean value, or throws JSIException if not a + /// boolean. + bool asBool() const; + + /// \return the number value, or asserts if not a number. + double getNumber() const { + assert(isNumber()); + return data_.number; + } + + /// \return the number value, or throws JSIException if not a + /// number. + double asNumber() const; + + /// \return the Symbol value, or asserts if not a symbol. + Symbol getSymbol(Runtime& runtime) const& { + assert(isSymbol()); + return Symbol(runtime.cloneSymbol(data_.pointer.ptr_)); + } + + /// \return the Symbol value, or asserts if not a symbol. + /// Can be used on rvalue references to avoid cloning more symbols. + Symbol getSymbol(Runtime&) && { + assert(isSymbol()); + auto ptr = data_.pointer.ptr_; + data_.pointer.ptr_ = nullptr; + return static_cast(ptr); + } + + /// \return the Symbol value, or throws JSIException if not a + /// symbol + Symbol asSymbol(Runtime& runtime) const&; + Symbol asSymbol(Runtime& runtime) &&; + + /// \return the BigInt value, or asserts if not a bigint. + BigInt getBigInt(Runtime& runtime) const& { + assert(isBigInt()); + return BigInt(runtime.cloneBigInt(data_.pointer.ptr_)); + } + + /// \return the BigInt value, or asserts if not a bigint. + /// Can be used on rvalue references to avoid cloning more bigints. + BigInt getBigInt(Runtime&) && { + assert(isBigInt()); + auto ptr = data_.pointer.ptr_; + data_.pointer.ptr_ = nullptr; + return static_cast(ptr); + } + + /// \return the BigInt value, or throws JSIException if not a + /// bigint + BigInt asBigInt(Runtime& runtime) const&; + BigInt asBigInt(Runtime& runtime) &&; + + /// \return the String value, or asserts if not a string. + String getString(Runtime& runtime) const& { + assert(isString()); + return String(runtime.cloneString(data_.pointer.ptr_)); + } + + /// \return the String value, or asserts if not a string. + /// Can be used on rvalue references to avoid cloning more strings. + String getString(Runtime&) && { + assert(isString()); + auto ptr = data_.pointer.ptr_; + data_.pointer.ptr_ = nullptr; + return static_cast(ptr); + } + + /// \return the String value, or throws JSIException if not a + /// string. + String asString(Runtime& runtime) const&; + String asString(Runtime& runtime) &&; + + /// \return the Object value, or asserts if not an object. + Object getObject(Runtime& runtime) const& { + assert(isObject()); + return Object(runtime.cloneObject(data_.pointer.ptr_)); + } + + /// \return the Object value, or asserts if not an object. + /// Can be used on rvalue references to avoid cloning more objects. + Object getObject(Runtime&) && { + assert(isObject()); + auto ptr = data_.pointer.ptr_; + data_.pointer.ptr_ = nullptr; + return static_cast(ptr); + } + + /// \return the Object value, or throws JSIException if not an + /// object. + Object asObject(Runtime& runtime) const&; + Object asObject(Runtime& runtime) &&; + + // \return a String like JS .toString() would do. + String toString(Runtime& runtime) const; + + private: + friend class Runtime; + + enum ValueKind { + UndefinedKind, + NullKind, + BooleanKind, + NumberKind, + SymbolKind, + BigIntKind, + StringKind, + ObjectKind, + PointerKind = SymbolKind, + }; + + union Data { + // Value's ctor and dtor will manage the lifecycle of the contained Data. + Data() { + static_assert( + sizeof(Data) == sizeof(uint64_t), + "Value data should fit in a 64-bit register"); + } + ~Data() {} + + // scalars + bool boolean; + double number; + // pointers + Pointer pointer; // Symbol, String, Object, Array, Function + }; + + 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_; + + // In the future: Value becomes NaN-boxed. See T40538354. +}; + +/// Not movable and not copyable RAII marker advising the underlying +/// JavaScript VM to track resources allocated since creation until +/// destruction so that they can be recycled eagerly when the Scope +/// goes out of scope instead of floating in the air until the next +/// garbage collection or any other delayed release occurs. +/// +/// This API should be treated only as advice, implementations can +/// choose to ignore the fact that Scopes are created or destroyed. +/// +/// This class is an exception to the rule allowing destructors to be +/// called without proper synchronization (see Runtime documentation). +/// The whole point of this class is to enable all sorts of clean ups +/// when the destructor is called and this proper synchronization is +/// required at that time. +/// +/// Instances of this class are intended to be created as automatic stack +/// variables in which case destructor calls don't require any additional +/// locking, provided that the lock (if any) is managed with RAII helpers. +class JSI_EXPORT 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 + static auto callInNewScope(Runtime& rt, F f) -> decltype(f()) { + Scope s(rt); + return f(); + } + + private: + Runtime& rt_; + Runtime::ScopeState* prv_; +}; + +/// Base class for jsi exceptions +class JSI_EXPORT 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_; +}; + +/// This exception will be thrown by API functions on errors not related to +/// JavaScript execution. +class JSI_EXPORT JSINativeException : public JSIException { + public: + JSINativeException(std::string what) : JSIException(std::move(what)) {} + + JSINativeException(const JSINativeException&) = default; + + virtual ~JSINativeException(); +}; + +/// This exception will be thrown by API functions whenever a JS +/// operation causes an exception as described by the spec, or as +/// otherwise described. +class JSI_EXPORT JSError : public JSIException { + public: + /// Creates a JSError referring to provided \c value + JSError(Runtime& r, Value&& value); + + /// Creates a JSError referring to new \c Error instance capturing current + /// JavaScript stack. The error message property is set to given \c message. + JSError(Runtime& rt, std::string message); + + /// Creates a JSError referring to new \c Error instance capturing current + /// JavaScript stack. The error message property is set to given \c message. + JSError(Runtime& rt, const char* message) + : JSError(rt, std::string(message)) {} + + /// Creates a JSError referring to a JavaScript Object having message and + /// stack properties set to provided values. + JSError(Runtime& rt, std::string message, std::string stack); + + /// Creates a JSError referring to provided value and what string + /// set to provided message. This argument order is a bit weird, + /// but necessary to avoid ambiguity with the above. + JSError(std::string what, Runtime& rt, Value&& value); + + /// Creates a JSError referring to the provided value, message and stack. This + /// constructor does not take a Runtime parameter, and therefore cannot result + /// in recursively invoking the JSError constructor. + 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_; + } + + private: + // This initializes the value_ member and does some other + // validation, so it must be called by every branch through the + // constructors. + void setValue(Runtime& rt, Value&& value); + + // This needs to be on the heap, because throw requires the object + // be copyable, and Value is not. + std::shared_ptr value_; + std::string message_; + std::string stack_; +}; + +} // namespace jsi +} // namespace facebook + +#include \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h index 5820c060ffc..95750aaa6d9 100644 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h +++ b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h @@ -298,4 +298,4 @@ class YG_EXPORT Style { FloatOptional aspectRatio_{}; }; -} // namespace facebook::yoga \ No newline at end of file +} // namespace facebook::yoga diff --git a/vnext/Shared/JSI/ChakraApi.h b/vnext/Shared/JSI/ChakraApi.h index 1d639f7e2e9..497582d2b42 100644 --- a/vnext/Shared/JSI/ChakraApi.h +++ b/vnext/Shared/JSI/ChakraApi.h @@ -349,6 +349,11 @@ struct ChakraApi { */ static bool InstanceOf(JsValueRef object, JsValueRef constructor); + /** + * @brief test. + */ + static void setExternalMemoryPressure(JsValueRef object, size_t amt); + /** * @brief Gets an object's property. */ diff --git a/vnext/Shared/JSI/ChakraRuntime.cpp b/vnext/Shared/JSI/ChakraRuntime.cpp index bed984a66ac..48dd74cd553 100644 --- a/vnext/Shared/JSI/ChakraRuntime.cpp +++ b/vnext/Shared/JSI/ChakraRuntime.cpp @@ -678,6 +678,10 @@ bool ChakraRuntime::instanceOf(const facebook::jsi::Object &obj, const facebook: return InstanceOf(GetJsRef(obj), GetJsRef(func)); } +void ChakraRuntime::setExternalMemoryPressure(const facebook::jsi::Object &obj, size_t amt) { + return setExternalMemoryPressure(obj, amt); +} + #pragma endregion Functions_inherited_from_Runtime // Sets variable in the constructor and then restores its value in the destructor. diff --git a/vnext/Shared/JSI/ChakraRuntime.h b/vnext/Shared/JSI/ChakraRuntime.h index 3cf3d0fbff6..bd10475b1eb 100644 --- a/vnext/Shared/JSI/ChakraRuntime.h +++ b/vnext/Shared/JSI/ChakraRuntime.h @@ -152,6 +152,7 @@ class ChakraRuntime : public facebook::jsi::Runtime, public ChakraApi, ChakraApi bool strictEquals(const facebook::jsi::Object &a, const facebook::jsi::Object &b) const override; bool instanceOf(const facebook::jsi::Object &obj, const facebook::jsi::Function &func) override; + void setExternalMemoryPressure(const facebook::jsi::Object &obj, size_t amt) override; #pragma endregion Functions_inherited_from_Runtime diff --git a/vnext/overrides.json b/vnext/overrides.json index b92300eb17d..1ea0ed1a3ab 100644 --- a/vnext/overrides.json +++ b/vnext/overrides.json @@ -196,7 +196,7 @@ "type": "patch", "file": "ReactCommon/TEMP_UntilReactCommonUpdate/yoga/yoga/style/Style.h", "baseFile": "packages/react-native/ReactCommon/yoga/yoga/style/Style.h", - "baseHash": "c4150273aa8ab23568f31365cd678b9967521362", + "baseHash": "97d57900ffa9a3ade3f3278811d07f267e48f706", "issue": 12195 }, { From 71f2a54a8984a33246601c562a6320649a40e181 Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Wed, 10 Jan 2024 15:45:48 -0800 Subject: [PATCH 08/16] fix build --- vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp | 4 +++- vnext/Shared/JSI/ChakraApi.cpp | 2 ++ vnext/Shared/JSI/ChakraApi.h | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp index c757c707889..24832985464 100644 --- a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +++ b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp @@ -739,7 +739,9 @@ bool JsiAbiRuntime::instanceOf(const Object &o, const Function &f) try { throw; } -void JsiAbiRuntime::setExternalMemoryPressure(const Object &, size_t) {} +void JsiAbiRuntime::setExternalMemoryPressure(const Object &o, size_t amt) { + return m_runtime.setExternalMemoryPressure(AsJsiObjectRef(o), static_cast(amt)); +} template struct AutoRestore { diff --git a/vnext/Shared/JSI/ChakraApi.cpp b/vnext/Shared/JSI/ChakraApi.cpp index a49b70ec80d..6cf2e1c77b1 100644 --- a/vnext/Shared/JSI/ChakraApi.cpp +++ b/vnext/Shared/JSI/ChakraApi.cpp @@ -319,6 +319,8 @@ ChakraApi::JsRefHolder::~JsRefHolder() noexcept { return result; } +/*static*/ void ChakraApi::setExternalMemoryPressure(JsValueRef object, size_t amt) {} + /*static*/ JsValueRef ChakraApi::GetProperty(JsValueRef object, JsPropertyIdRef propertyId) { JsValueRef result{JS_INVALID_REFERENCE}; ChakraVerifyJsErrorElseThrow(JsGetProperty(object, propertyId, &result)); diff --git a/vnext/Shared/JSI/ChakraApi.h b/vnext/Shared/JSI/ChakraApi.h index 497582d2b42..4c3c4f977f2 100644 --- a/vnext/Shared/JSI/ChakraApi.h +++ b/vnext/Shared/JSI/ChakraApi.h @@ -350,7 +350,8 @@ struct ChakraApi { static bool InstanceOf(JsValueRef object, JsValueRef constructor); /** - * @brief test. + * @brief Inform the runtime that there is additional memory associated with a given JavaScript object that is not + * visible to the GC. */ static void setExternalMemoryPressure(JsValueRef object, size_t amt); From 888697cdee8c8d71170ea6ee086b0c190a82aa5a Mon Sep 17 00:00:00 2001 From: TatianaKapos Date: Thu, 11 Jan 2024 16:46:10 -0800 Subject: [PATCH 09/16] revert changes --- .../JSI/JsiAbiApi.cpp | 4 - .../Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h | 1 - vnext/Microsoft.ReactNative/JsiApi.cpp | 8 - vnext/Microsoft.ReactNative/JsiApi.h | 1 - vnext/Microsoft.ReactNative/JsiApi.idl | 1 - .../jsi/jsi/decorator.h | 810 --------- .../jsi/jsi/jsi-inl.h | 356 ---- .../TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h | 1524 ----------------- vnext/Shared/JSI/ChakraApi.cpp | 2 - vnext/Shared/JSI/ChakraApi.h | 6 - vnext/Shared/JSI/ChakraRuntime.cpp | 4 - vnext/Shared/JSI/ChakraRuntime.h | 1 - 12 files changed, 2718 deletions(-) delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h delete mode 100644 vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h diff --git a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp index 24832985464..a61d9baff54 100644 --- a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp +++ b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.cpp @@ -739,10 +739,6 @@ bool JsiAbiRuntime::instanceOf(const Object &o, const Function &f) try { throw; } -void JsiAbiRuntime::setExternalMemoryPressure(const Object &o, size_t amt) { - return m_runtime.setExternalMemoryPressure(AsJsiObjectRef(o), static_cast(amt)); -} - template struct AutoRestore { AutoRestore(T *var, T value) : m_var{var}, m_value{std::exchange(*var, value)} {} diff --git a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h index 9514643dbc7..55adef2b61a 100644 --- a/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h +++ b/vnext/Microsoft.ReactNative.Cxx/JSI/JsiAbiApi.h @@ -179,7 +179,6 @@ struct JsiAbiRuntime : facebook::jsi::Runtime { bool strictEquals(const facebook::jsi::String &a, const facebook::jsi::String &b) const override; bool strictEquals(const facebook::jsi::Object &a, const facebook::jsi::Object &b) const override; bool instanceOf(const facebook::jsi::Object &o, const facebook::jsi::Function &f) override; - void setExternalMemoryPressure(const facebook::jsi::Object &, size_t) override; void RethrowJsiError() const; diff --git a/vnext/Microsoft.ReactNative/JsiApi.cpp b/vnext/Microsoft.ReactNative/JsiApi.cpp index 3e38092b572..10662d7e974 100644 --- a/vnext/Microsoft.ReactNative/JsiApi.cpp +++ b/vnext/Microsoft.ReactNative/JsiApi.cpp @@ -185,7 +185,6 @@ struct RuntimeAccessor : facebook::jsi::Runtime { using facebook::jsi::Runtime::lockWeakObject; using facebook::jsi::Runtime::popScope; using facebook::jsi::Runtime::pushScope; - using facebook::jsi::Runtime::setExternalMemoryPressure; using facebook::jsi::Runtime::setNativeState; using facebook::jsi::Runtime::setPropertyValue; using facebook::jsi::Runtime::setValueAtIndexImpl; @@ -1084,13 +1083,6 @@ bool JsiRuntime::InstanceOf(JsiObjectRef obj, JsiObjectRef constructor) try { throw; } -void JsiRuntime::setExternalMemoryPressure(JsiObjectRef obj, uint32_t size) try { - auto objPtr = RuntimeAccessor::AsPointerValue(obj); - m_runtimeAccessor->setExternalMemoryPressure(RuntimeAccessor::AsObject(&objPtr), size); -} catch (JSI_SET_ERROR) { - throw; -} - void JsiRuntime::ReleaseSymbol(JsiSymbolRef const &symbolData) { auto symbol = RuntimeAccessor::make(reinterpret_cast(symbolData.Data)); diff --git a/vnext/Microsoft.ReactNative/JsiApi.h b/vnext/Microsoft.ReactNative/JsiApi.h index 44909631cd1..193075c01a1 100644 --- a/vnext/Microsoft.ReactNative/JsiApi.h +++ b/vnext/Microsoft.ReactNative/JsiApi.h @@ -160,7 +160,6 @@ struct JsiRuntime : JsiRuntimeT { bool StringStrictEquals(JsiStringRef left, JsiStringRef right); bool ObjectStrictEquals(JsiObjectRef left, JsiObjectRef right); bool InstanceOf(JsiObjectRef obj, JsiObjectRef constructor); - void setExternalMemoryPressure(JsiObjectRef obj, uint32_t size); void ReleaseSymbol(JsiSymbolRef const &symbol); void ReleaseBigInt(JsiBigIntRef const &bigInt); diff --git a/vnext/Microsoft.ReactNative/JsiApi.idl b/vnext/Microsoft.ReactNative/JsiApi.idl index 75b785c06d3..d3418b48c35 100644 --- a/vnext/Microsoft.ReactNative/JsiApi.idl +++ b/vnext/Microsoft.ReactNative/JsiApi.idl @@ -328,7 +328,6 @@ namespace Microsoft.ReactNative Boolean ObjectStrictEquals(JsiObjectRef left, JsiObjectRef right); Boolean InstanceOf(JsiObjectRef obj, JsiObjectRef constructor); - void setExternalMemoryPressure(JsiObjectRef obj, UInt32 amt); void ReleaseSymbol(JsiSymbolRef symbol); void ReleaseBigInt(JsiBigIntRef bigInt); diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h deleted file mode 100644 index faa6e00e73d..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/decorator.h +++ /dev/null @@ -1,810 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -#include -#include - -// This file contains objects to help API users create their own -// runtime adapters, i.e. if you want to compose runtimes to add your -// own behavior. - -namespace facebook { -namespace jsi { - -// Use this to wrap host functions. It will pass the member runtime as -// the first arg to the callback. The first argument to the ctor -// should be the decorated runtime, not the plain one. -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); - } - - private: - template - friend class RuntimeDecorator; - - Runtime& drt_; - HostFunctionType plainHF_; -}; - -// From the perspective of the caller, a plain HostObject is passed to -// the decorated Runtime, and the HostObject methods expect to get -// passed that Runtime. But the plain Runtime will pass itself to its -// callback, so we need a helper here which curries the decorated -// Runtime, and calls the plain HostObject with it. -// -// If the concrete RuntimeDecorator derives DecoratedHostObject, it -// should call the base class get() and set() to invoke the plain -// HostObject functionality. The Runtime& it passes does not matter, -// as it is not used. -class DecoratedHostObject : public HostObject { - public: - DecoratedHostObject(Runtime& drt, std::shared_ptr plainHO) - : drt_(drt), plainHO_(plainHO) {} - - // The derived class methods can call this to get a reference to the - // decorated runtime, since the rt passed to the callback will be - // the plain runtime. - 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 getPropertyNames(Runtime&) override { - return plainHO_->getPropertyNames(decoratedRuntime()); - } - - private: - template - friend class RuntimeDecorator; - - Runtime& drt_; - std::shared_ptr plainHO_; -}; - -/// C++ variant on a standard Decorator pattern, using template -/// parameters. The \c Plain template parameter type is the -/// undecorated Runtime type. You can usually use \c Runtime here, -/// but if you know the concrete type ahead of time and it's final, -/// the compiler can devirtualize calls to the decorated -/// implementation. The \c Base template parameter type will be used -/// as the base class of the decorated type. Here, too, you can -/// usually use \c Runtime, but if you want the decorated type to -/// implement a derived class of Runtime, you can specify that here. -/// For an example, see threadsafe.h. -template -class RuntimeDecorator : public Base, private jsi::Instrumentation { - public: - Plain& plain() { - static_assert( - std::is_base_of::value, - "RuntimeDecorator's Plain type must derive from jsi::Runtime"); - static_assert( - std::is_base_of::value, - "RuntimeDecorator's Base type must derive from jsi::Runtime"); - return plain_; - } - const Plain& plain() const { - return plain_; - } - - Value evaluateJavaScript( - const std::shared_ptr& buffer, - const std::string& sourceURL) override { - return plain().evaluateJavaScript(buffer, sourceURL); - } - std::shared_ptr prepareJavaScript( - const std::shared_ptr& buffer, - std::string sourceURL) override { - return plain().prepareJavaScript(buffer, std::move(sourceURL)); - } - Value evaluatePreparedJavaScript( - const std::shared_ptr& js) override { - return plain().evaluatePreparedJavaScript(js); - } - 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: - // plain is generally going to be a reference to an object managed - // by a derived class. We cache it here so this class can be - // concrete, and avoid making virtual calls to find the plain - // Runtime. Note that the ctor and dtor do not access through the - // reference, so passing a reference to an object before its - // lifetime has started is ok. - 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 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); - }; - std::string utf8(const String& s) override { - return plain_.utf8(s); - } - - Object createObject() override { - return plain_.createObject(); - }; - - Object createObject(std::shared_ptr ho) override { - return plain_.createObject( - std::make_shared(*this, std::move(ho))); - }; - std::shared_ptr getHostObject(const jsi::Object& o) override { - std::shared_ptr dho = plain_.getHostObject(o); - return static_cast(*dho).plainHO_; - }; - HostFunctionType& getHostFunction(const jsi::Function& f) override { - HostFunctionType& dhf = plain_.getHostFunction(f); - // This will fail if a cpp file including this header is not compiled - // with RTTI. - return dhf.target()->plainHF_; - }; - - bool hasNativeState(const Object& o) override { - return plain_.hasNativeState(o); - } - std::shared_ptr getNativeState(const Object& o) override { - return plain_.getNativeState(o); - } - void setNativeState(const Object& o, std::shared_ptr state) - override { - plain_.setNativeState(o, state); - } - - void setExternalMemoryPressure(const Object& obj, size_t amt) override { - plain_.setExternalMemoryPressure(obj, amt); - } - - 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 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); - }; - - // Private data for managing scopes. - 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); - }; - - // jsi::Instrumentation methods - - std::string getRecordedGCStats() override { - return plain().instrumentation().getRecordedGCStats(); - } - - std::unordered_map 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)> 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) override { - plain().instrumentation().createSnapshotToFile(path); - } - - void createSnapshotToStream(std::ostream& os) override { - plain().instrumentation().createSnapshotToStream(os); - } - - std::string flushAndDisableBridgeTrafficTrace() override { - return const_cast(plain()) - .instrumentation() - .flushAndDisableBridgeTrafficTrace(); - } - - void writeBasicBlockProfileTraceToFile( - const std::string& fileName) const override { - const_cast(plain()) - .instrumentation() - .writeBasicBlockProfileTraceToFile(fileName); - } - - /// Dump external profiler symbols to the given file name. - void dumpProfilerSymbolsToFile(const std::string& fileName) const override { - const_cast(plain()).instrumentation().dumpProfilerSymbolsToFile( - fileName); - } - - private: - Plain& plain_; -}; - -namespace detail { - -// This metaprogramming allows the With type's methods to be -// optional. - -template -struct BeforeCaller { - static void before(T&) {} -}; - -template -struct AfterCaller { - static void after(T&) {} -}; - -// decltype((void)&...) is either SFINAE, or void. -// So, if SFINAE does not happen for T, then this specialization exists -// for BeforeCaller, and always applies. If not, only the -// default above exists, and that is used instead. -template -struct BeforeCaller { - static void before(T& t) { - t.before(); - } -}; - -template -struct AfterCaller { - static void after(T& t) { - t.after(); - } -}; - -// It's possible to use multiple decorators by nesting -// WithRuntimeDecorator<...>, but this specialization allows use of -// std::tuple of decorator classes instead. See testlib.cpp for an -// example. -template -struct BeforeCaller> { - static void before(std::tuple& tuple) { - all_before<0, T...>(tuple); - } - - private: - template - static void all_before(std::tuple& tuple) { - detail::BeforeCaller::before(std::get(tuple)); - all_before(tuple); - } - - template - static void all_before(std::tuple&) {} -}; - -template -struct AfterCaller> { - static void after(std::tuple& tuple) { - all_after<0, T...>(tuple); - } - - private: - template - static void all_after(std::tuple& tuple) { - all_after(tuple); - detail::AfterCaller::after(std::get(tuple)); - } - - template - static void all_after(std::tuple&) {} -}; - -} // namespace detail - -// A decorator which implements an around idiom. A With instance is -// RAII constructed before each call to the undecorated class; the -// ctor is passed a single argument of type WithArg&. Plain and Base -// are used as in the base class. -template -class WithRuntimeDecorator : public RuntimeDecorator { - public: - using RD = RuntimeDecorator; - - // The reference arguments to the ctor are stored, but not used by - // the ctor, and there is no ctor, so they can be passed members of - // the derived class. - WithRuntimeDecorator(Plain& plain, With& with) : RD(plain), with_(with) {} - - Value evaluateJavaScript( - const std::shared_ptr& buffer, - const std::string& sourceURL) override { - Around around{with_}; - return RD::evaluateJavaScript(buffer, sourceURL); - } - std::shared_ptr prepareJavaScript( - const std::shared_ptr& buffer, - std::string sourceURL) override { - Around around{with_}; - return RD::prepareJavaScript(buffer, std::move(sourceURL)); - } - Value evaluatePreparedJavaScript( - const std::shared_ptr& js) override { - Around around{with_}; - return RD::evaluatePreparedJavaScript(js); - } - 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(); - }; - - // The jsi:: prefix is necessary because MSVC compiler complains C2247: - // Instrumentation is not accessible because RuntimeDecorator uses private - // to inherit from Instrumentation. - // TODO(T40821815) Consider removing this workaround when updating MSVC - 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* 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 createPropNameIDFromString(const String& str) override { - Around around{with_}; - return RD::createPropNameIDFromString(str); - }; - 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); - }; - - 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); - }; - std::string utf8(const String& s) override { - Around around{with_}; - return RD::utf8(s); - } - - Object createObject() override { - Around around{with_}; - return RD::createObject(); - }; - Object createObject(std::shared_ptr ho) override { - Around around{with_}; - return RD::createObject(std::move(ho)); - }; - std::shared_ptr 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); - }; - - 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 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); - }; - - // Private data for managing scopes. - 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 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); - }; - - private: - // Wrap an RAII type around With& to guarantee after always happens. - struct Around { - Around(With& with) : with_(with) { - detail::BeforeCaller::before(with_); - } - ~Around() { - detail::AfterCaller::after(with_); - } - - With& with_; - }; - - With& with_; -}; - -} // namespace jsi -} // namespace facebook \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h deleted file mode 100644 index 3d9d3fa1a04..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi-inl.h +++ /dev/null @@ -1,356 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -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(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 -inline Value toValue(Runtime& runtime, const T& other) { - static_assert( - std::is_base_of::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); -} - -/// Helper to throw while still compiling with exceptions turned off. -template -[[noreturn]] inline void throwOrDie(Args&&... args) { - std::rethrow_exception( - std::make_exception_ptr(E{std::forward(args)...})); -} - -} // namespace detail - -template -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 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 -void Object::setProperty(Runtime& runtime, const char* name, T&& value) const { - setProperty( - runtime, String::createFromAscii(runtime, name), std::forward(value)); -} - -template -void Object::setProperty(Runtime& runtime, const String& name, T&& value) - const { - setPropertyValue( - runtime, name, detail::toValue(runtime, std::forward(value))); -} - -template -void Object::setProperty(Runtime& runtime, const PropNameID& name, T&& value) - const { - setPropertyValue( - runtime, name, detail::toValue(runtime, std::forward(value))); -} - -inline Array Object::getArray(Runtime& runtime) const& { - assert(runtime.isArray(*this)); - (void)runtime; // when assert is disabled we need to mark this as used - return Array(runtime.cloneObject(ptr_)); -} - -inline Array Object::getArray(Runtime& runtime) && { - assert(runtime.isArray(*this)); - (void)runtime; // when assert is disabled we need to mark this as used - Runtime::PointerValue* value = ptr_; - ptr_ = nullptr; - return Array(value); -} - -inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) const& { - assert(runtime.isArrayBuffer(*this)); - (void)runtime; // when assert is disabled we need to mark this as used - return ArrayBuffer(runtime.cloneObject(ptr_)); -} - -inline ArrayBuffer Object::getArrayBuffer(Runtime& runtime) && { - assert(runtime.isArrayBuffer(*this)); - (void)runtime; // when assert is disabled we need to mark this as used - 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; // when assert is disabled we need to mark this as used - Runtime::PointerValue* value = ptr_; - ptr_ = nullptr; - return Function(value); -} - -template -inline bool Object::isHostObject(Runtime& runtime) const { - return runtime.isHostObject(*this) && - std::dynamic_pointer_cast(runtime.getHostObject(*this)); -} - -template <> -inline bool Object::isHostObject(Runtime& runtime) const { - return runtime.isHostObject(*this); -} - -template -inline std::shared_ptr Object::getHostObject(Runtime& runtime) const { - assert(isHostObject(runtime)); - return std::static_pointer_cast(runtime.getHostObject(*this)); -} - -template -inline std::shared_ptr Object::asHostObject(Runtime& runtime) const { - if (!isHostObject(runtime)) { - detail::throwOrDie( - "Object is not a HostObject of desired type"); - } - return std::static_pointer_cast(runtime.getHostObject(*this)); -} - -template <> -inline std::shared_ptr Object::getHostObject( - Runtime& runtime) const { - assert(runtime.isHostObject(*this)); - return runtime.getHostObject(*this); -} - -template -inline bool Object::hasNativeState(Runtime& runtime) const { - return runtime.hasNativeState(*this) && - std::dynamic_pointer_cast(runtime.getNativeState(*this)); -} - -template <> -inline bool Object::hasNativeState(Runtime& runtime) const { - return runtime.hasNativeState(*this); -} - -template -inline std::shared_ptr Object::getNativeState(Runtime& runtime) const { - assert(hasNativeState(runtime)); - return std::static_pointer_cast(runtime.getNativeState(*this)); -} - -inline void Object::setNativeState( - Runtime& runtime, - std::shared_ptr 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 -void Array::setValueAtIndex(Runtime& runtime, size_t i, T&& value) const { - setValueAtIndexImpl( - runtime, i, detail::toValue(runtime, std::forward(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 args) - const { - return call(runtime, args.begin(), args.size()); -} - -template -inline Value Function::call(Runtime& runtime, Args&&... args) const { - // A more awesome version of this would be able to create raw values - // which can be used directly without wrapping and unwrapping, but - // this will do for now. - return call(runtime, {detail::toValue(runtime, std::forward(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 args) const { - return callWithThis(runtime, jsThis, args.begin(), args.size()); -} - -template -inline Value Function::callWithThis( - Runtime& runtime, - const Object& jsThis, - Args&&... args) const { - // A more awesome version of this would be able to create raw values - // which can be used directly without wrapping and unwrapping, but - // this will do for now. - return callWithThis( - runtime, jsThis, {detail::toValue(runtime, std::forward(args))...}); -} - -template -inline Array Array::createWithElements(Runtime& runtime, Args&&... args) { - return createWithElements( - runtime, {detail::toValue(runtime, std::forward(args))...}); -} - -template -inline std::vector PropNameID::names( - Runtime& runtime, - Args&&... args) { - return names({detail::toPropNameID(runtime, std::forward(args))...}); -} - -template -inline std::vector PropNameID::names( - PropNameID(&&propertyNames)[N]) { - std::vector 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 args) const { - return callAsConstructor(runtime, args.begin(), args.size()); -} - -template -inline Value Function::callAsConstructor(Runtime& runtime, Args&&... args) - const { - return callAsConstructor( - runtime, {detail::toValue(runtime, std::forward(args))...}); -} - -String BigInt::toString(Runtime& runtime, int radix) const { - return runtime.bigintToString(*this, radix); -} - -} // namespace jsi -} // namespace facebook \ No newline at end of file diff --git a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h b/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h deleted file mode 100644 index d93f07e707a..00000000000 --- a/vnext/ReactCommon/TEMP_UntilReactCommonUpdate/jsi/jsi/jsi.h +++ /dev/null @@ -1,1524 +0,0 @@ -/* - * Copyright (c) Meta Platforms, Inc. and affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#ifndef JSI_EXPORT -#ifdef _MSC_VER -#ifdef CREATE_SHARED_LIBRARY -#define JSI_EXPORT __declspec(dllexport) -#else -#define JSI_EXPORT -#endif // CREATE_SHARED_LIBRARY -#else // _MSC_VER -#define JSI_EXPORT __attribute__((visibility("default"))) -#endif // _MSC_VER -#endif // !defined(JSI_EXPORT) - -class FBJSRuntime; -namespace facebook { -namespace jsi { - -/// Base class for buffers of data or bytecode that need to be passed to the -/// runtime. The buffer is expected to be fully immutable, so the result of -/// size(), data(), and the contents of the pointer returned by data() must not -/// change after construction. -class JSI_EXPORT Buffer { - public: - virtual ~Buffer(); - virtual size_t size() const = 0; - virtual const uint8_t* data() const = 0; -}; - -class JSI_EXPORT 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(s_.data()); - } - - private: - std::string s_; -}; - -/// Base class for buffers of data that need to be passed to the runtime. The -/// result of size() and data() must not change after construction. However, the -/// region pointed to by data() may be modified by the user or the runtime. The -/// user must ensure that access to the contents of the buffer is properly -/// synchronised. -class JSI_EXPORT MutableBuffer { - public: - virtual ~MutableBuffer(); - virtual size_t size() const = 0; - virtual uint8_t* data() = 0; -}; - -/// PreparedJavaScript is a base class representing JavaScript which is in a -/// form optimized for execution, in a runtime-specific way. Construct one via -/// jsi::Runtime::prepareJavaScript(). -/// ** This is an experimental API that is subject to change. ** -class JSI_EXPORT PreparedJavaScript { - protected: - PreparedJavaScript() = default; - - public: - virtual ~PreparedJavaScript() = 0; -}; - -class Runtime; -class Pointer; -class PropNameID; -class Symbol; -class BigInt; -class String; -class Object; -class WeakObject; -class Array; -class ArrayBuffer; -class Function; -class Value; -class Instrumentation; -class Scope; -class JSIException; -class JSError; - -/// A function which has this type can be registered as a function -/// callable from JavaScript using Function::createFromHostFunction(). -/// When the function is called, args will point to the arguments, and -/// count will indicate how many arguments are passed. The function -/// can return a Value to the caller, or throw an exception. If a C++ -/// exception is thrown, a JS Error will be created and thrown into -/// JS; if the C++ exception extends std::exception, the Error's -/// message will be whatever what() returns. Note that it is undefined whether -/// HostFunctions may or may not be called in strict mode; that is `thisVal` -/// can be any value - it will not necessarily be coerced to an object or -/// or set to the global object. -using HostFunctionType = std::function< - Value(Runtime& rt, const Value& thisVal, const Value* args, size_t count)>; - -/// An object which implements this interface can be registered as an -/// Object with the JS runtime. -class JSI_EXPORT HostObject { - public: - // The C++ object's dtor will be called when the GC finalizes this - // object. (This may be as late as when the Runtime is shut down.) - // You have no control over which thread it is called on. This will - // be called from inside the GC, so it is unsafe to do any VM - // operations which require a Runtime&. Derived classes' dtors - // should also avoid doing anything expensive. Calling the dtor on - // a jsi object is explicitly ok. If you want to do JS operations, - // or any nontrivial work, you should add it to a work queue, and - // manage it externally. - virtual ~HostObject(); - - // When JS wants a property with a given name from the HostObject, - // it will call this method. If it throws an exception, the call - // will throw a JS \c Error object. By default this returns undefined. - // \return the value for the property. - virtual Value get(Runtime&, const PropNameID& name); - - // When JS wants to set a property with a given name on the HostObject, - // it will call this method. If it throws an exception, the call will - // throw a JS \c Error object. By default this throws a type error exception - // mimicking the behavior of a frozen object in strict mode. - virtual void set(Runtime&, const PropNameID& name, const Value& value); - - // When JS wants a list of property names for the HostObject, it will - // call this method. If it throws an exception, the call will throw a - // JS \c Error object. The default implementation returns empty vector. - virtual std::vector getPropertyNames(Runtime& rt); -}; - -/// Native state (and destructor) that can be attached to any JS object -/// using setNativeState. -class JSI_EXPORT NativeState { - public: - virtual ~NativeState(); -}; - -/// Represents a JS runtime. Movable, but not copyable. Note that -/// this object may not be thread-aware, but cannot be used safely from -/// multiple threads at once. The application is responsible for -/// ensuring that it is used safely. This could mean using the -/// Runtime from a single thread, using a mutex, doing all work on a -/// serial queue, etc. This restriction applies to the methods of -/// this class, and any method in the API which take a Runtime& as an -/// argument. Destructors (all but ~Scope), operators, or other methods -/// which do not take Runtime& as an argument are safe to call from any -/// thread, but it is still forbidden to make write operations on a single -/// instance of any class from more than one thread. In addition, to -/// make shutdown safe, destruction of objects associated with the Runtime -/// must be destroyed before the Runtime is destroyed, or from the -/// destructor of a managed HostObject or HostFunction. Informally, this -/// means that the main source of unsafe behavior is to hold a jsi object -/// in a non-Runtime-managed object, and not clean it up before the Runtime -/// is shut down. If your lifecycle is such that avoiding this is hard, -/// you will probably need to do use your own locks. -class JSI_EXPORT Runtime { - public: - virtual ~Runtime(); - - /// Evaluates the given JavaScript \c buffer. \c sourceURL is used - /// to annotate the stack trace if there is an exception. The - /// contents may be utf8-encoded JS source code, or binary bytecode - /// whose format is specific to the implementation. If the input - /// format is unknown, or evaluation causes an error, a JSIException - /// will be thrown. - /// Note this function should ONLY be used when there isn't another means - /// through the JSI API. For example, it will be much slower to use this to - /// call a global function than using the JSI APIs to read the function - /// property from the global object and then calling it explicitly. - virtual Value evaluateJavaScript( - const std::shared_ptr& buffer, - const std::string& sourceURL) = 0; - - /// Prepares to evaluate the given JavaScript \c buffer by processing it into - /// a form optimized for execution. This may include pre-parsing, compiling, - /// etc. If the input is invalid (for example, cannot be parsed), a - /// JSIException will be thrown. The resulting object is tied to the - /// particular concrete type of Runtime from which it was created. It may be - /// used (via evaluatePreparedJavaScript) in any Runtime of the same concrete - /// type. - /// The PreparedJavaScript object may be passed to multiple VM instances, so - /// they can all share and benefit from the prepared script. - /// As with evaluateJavaScript(), using JavaScript code should be avoided - /// when the JSI API is sufficient. - virtual std::shared_ptr prepareJavaScript( - const std::shared_ptr& buffer, - std::string sourceURL) = 0; - - /// Evaluates a PreparedJavaScript. If evaluation causes an error, a - /// JSIException will be thrown. - /// As with evaluateJavaScript(), using JavaScript code should be avoided - /// when the JSI API is sufficient. - virtual Value evaluatePreparedJavaScript( - const std::shared_ptr& js) = 0; - - /// Drain the JavaScript VM internal Microtask (a.k.a. Job in ECMA262) queue. - /// - /// \param maxMicrotasksHint a hint to tell an implementation that it should - /// make a best effort not execute more than the given number. It's default - /// to -1 for infinity (unbounded execution). - /// \return true if the queue is drained or false if there is more work to do. - /// - /// When there were exceptions thrown from the execution of microtasks, - /// implementations shall discard the exceptional jobs. An implementation may - /// \throw a \c JSError object to signal the hosts to handle. In that case, an - /// implementation may or may not suspend the draining. - /// - /// Hosts may call this function again to resume the draining if it was - /// suspended due to either exceptions or the \p maxMicrotasksHint bound. - /// E.g. a host may repetitively invoke this function until the queue is - /// drained to implement the "microtask checkpoint" defined in WHATWG HTML - /// event loop: https://html.spec.whatwg.org/C#perform-a-microtask-checkpoint. - /// - /// Note that error propagation is only a concern if a host needs to implement - /// `queueMicrotask`, a recent API that allows enqueueing arbitrary functions - /// (hence may throw) as microtasks. Exceptions from ECMA-262 Promise Jobs are - /// handled internally to VMs and are never propagated to hosts. - /// - /// This API offers some queue management to hosts at its best effort due to - /// different behaviors and limitations imposed by different VMs and APIs. By - /// the time this is written, An implementation may swallow exceptions (JSC), - /// may not pause (V8), and may not support bounded executions. - virtual bool drainMicrotasks(int maxMicrotasksHint = -1) = 0; - - /// \return the global object - virtual Object global() = 0; - - /// \return a short printable description of the instance. It should - /// at least include some human-readable indication of the runtime - /// implementation. This should only be used by logging, debugging, - /// and other developer-facing callers. - virtual std::string description() = 0; - - /// \return whether or not the underlying runtime supports debugging via the - /// Chrome remote debugging protocol. - /// - /// NOTE: the API for determining whether a runtime is debuggable and - /// registering a runtime with the debugger is still in flux, so please don't - /// use this API unless you know what you're doing. - virtual bool isInspectable() = 0; - - /// \return an interface to extract metrics from this \c Runtime. The default - /// implementation of this function returns an \c Instrumentation instance - /// which returns no metrics. - virtual Instrumentation& instrumentation(); - - protected: - friend class Pointer; - friend class PropNameID; - friend class Symbol; - friend class BigInt; - friend class String; - friend class Object; - friend class WeakObject; - friend class Array; - friend class ArrayBuffer; - friend class Function; - friend class Value; - friend class Scope; - friend class JSError; - - // Potential optimization: avoid the cloneFoo() virtual dispatch, - // and instead just fix the number of fields, and copy them, since - // in practice they are trivially copyable. Sufficient use of - // rvalue arguments/methods would also reduce the number of clones. - - struct PointerValue { - virtual void invalidate() = 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 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 std::string utf8(const String&) = 0; - - // \return a \c Value created from a utf8-encoded JSON string. The default - // implementation creates a \c String and invokes JSON.parse. - virtual Value createValueFromJsonUtf8(const uint8_t* json, size_t length); - - virtual Object createObject() = 0; - virtual Object createObject(std::shared_ptr ho) = 0; - virtual std::shared_ptr getHostObject(const jsi::Object&) = 0; - virtual HostFunctionType& getHostFunction(const jsi::Function&) = 0; - - virtual bool hasNativeState(const jsi::Object&) = 0; - virtual std::shared_ptr getNativeState(const jsi::Object&) = 0; - virtual void setNativeState( - const jsi::Object&, - std::shared_ptr state) = 0; - - 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 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; - - // Private data for managing scopes. - struct ScopeState; - 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; - - /// See Object::setExternalMemoryPressure. - virtual void setExternalMemoryPressure( - const jsi::Object& obj, - size_t amount) = 0; - - // These exist so derived classes can access the private parts of - // Value, Symbol, String, and Object, which are all friends of Runtime. - template - 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 class ::FBJSRuntime; - template - friend class RuntimeDecorator; -}; - -// Base class for pointer-storing types. -class JSI_EXPORT Pointer { - protected: - explicit Pointer(Pointer&& other) : ptr_(other.ptr_) { - other.ptr_ = nullptr; - } - - ~Pointer() { - if (ptr_) { - ptr_->invalidate(); - } - } - - Pointer& operator=(Pointer&& other); - - friend class Runtime; - friend class Value; - - explicit Pointer(Runtime::PointerValue* ptr) : ptr_(ptr) {} - - typename Runtime::PointerValue* ptr_; -}; - -/// Represents something that can be a JS property key. Movable, not copyable. -class JSI_EXPORT 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; - - /// Create a JS property name id from ascii values. The data is - /// copied. - static PropNameID forAscii(Runtime& runtime, const char* str, size_t length) { - return runtime.createPropNameIDFromAscii(str, length); - } - - /// Create a property name id from a nul-terminated C ascii name. The data is - /// copied. - static PropNameID forAscii(Runtime& runtime, const char* str) { - return forAscii(runtime, str, strlen(str)); - } - - /// Create a PropNameID from a C++ string. The string is copied. - static PropNameID forAscii(Runtime& runtime, const std::string& str) { - return forAscii(runtime, str.c_str(), str.size()); - } - - /// Create a PropNameID from utf8 values. The data is copied. - /// Results are undefined if \p utf8 contains invalid code points. - static PropNameID - forUtf8(Runtime& runtime, const uint8_t* utf8, size_t length) { - return runtime.createPropNameIDFromUtf8(utf8, length); - } - - /// Create a PropNameID from utf8-encoded octets stored in a - /// std::string. The string data is transformed and copied. - /// Results are undefined if \p utf8 contains invalid code points. - static PropNameID forUtf8(Runtime& runtime, const std::string& utf8) { - return runtime.createPropNameIDFromUtf8( - reinterpret_cast(utf8.data()), utf8.size()); - } - - /// Create a PropNameID from a JS string. - static PropNameID forString(Runtime& runtime, const jsi::String& str) { - return runtime.createPropNameIDFromString(str); - } - - /// Create a PropNameID from a JS symbol. - static PropNameID forSymbol(Runtime& runtime, const jsi::Symbol& sym) { - return runtime.createPropNameIDFromSymbol(sym); - } - - // Creates a vector of PropNameIDs constructed from given arguments. - template - static std::vector names(Runtime& runtime, Args&&... args); - - // Creates a vector of given PropNameIDs. - template - static std::vector names(PropNameID(&&propertyNames)[N]); - - /// Copies the data in a PropNameID as utf8 into a C++ string. - std::string utf8(Runtime& runtime) const { - return runtime.utf8(*this); - } - - static bool compare( - Runtime& runtime, - const jsi::PropNameID& a, - const jsi::PropNameID& b) { - return runtime.compare(a, b); - } - - friend class Runtime; - friend class Value; -}; - -/// Represents a JS Symbol (es6). Movable, not copyable. -/// TODO T40778724: this is a limited implementation sufficient for -/// the debugger not to crash when a Symbol is a property in an Object -/// or element in an array. Complete support for creating will come -/// later. -class JSI_EXPORT Symbol : public Pointer { - public: - using Pointer::Pointer; - - Symbol(Symbol&& other) = default; - Symbol& operator=(Symbol&& other) = default; - - /// \return whether a and b refer to the same symbol. - static bool strictEquals(Runtime& runtime, const Symbol& a, const Symbol& b) { - return runtime.strictEquals(a, b); - } - - /// Converts a Symbol into a C++ string as JS .toString would. The output - /// will look like \c Symbol(description) . - std::string toString(Runtime& runtime) const { - return runtime.symbolToString(*this); - } - - friend class Runtime; - friend class Value; -}; - -/// Represents a JS BigInt. Movable, not copyable. -class JSI_EXPORT BigInt : public Pointer { - public: - using Pointer::Pointer; - - BigInt(BigInt&& other) = default; - BigInt& operator=(BigInt&& other) = default; - - /// Create a BigInt representing the signed 64-bit \p value. - static BigInt fromInt64(Runtime& runtime, int64_t value) { - return runtime.createBigIntFromInt64(value); - } - - /// Create a BigInt representing the unsigned 64-bit \p value. - static BigInt fromUint64(Runtime& runtime, uint64_t value) { - return runtime.createBigIntFromUint64(value); - } - - /// \return whether a === b. - static bool strictEquals(Runtime& runtime, const BigInt& a, const BigInt& b) { - return runtime.strictEquals(a, b); - } - - /// \returns This bigint truncated to a signed 64-bit integer. - int64_t getInt64(Runtime& runtime) const { - return runtime.truncate(*this); - } - - /// \returns Whether this bigint can be losslessly converted to int64_t. - bool isInt64(Runtime& runtime) const { - return runtime.bigintIsInt64(*this); - } - - /// \returns This bigint truncated to a signed 64-bit integer. Throws a - /// JSIException if the truncation is lossy. - int64_t asInt64(Runtime& runtime) const; - - /// \returns This bigint truncated to an unsigned 64-bit integer. - uint64_t getUint64(Runtime& runtime) const { - return runtime.truncate(*this); - } - - /// \returns Whether this bigint can be losslessly converted to uint64_t. - bool isUint64(Runtime& runtime) const { - return runtime.bigintIsUint64(*this); - } - - /// \returns This bigint truncated to an unsigned 64-bit integer. Throws a - /// JSIException if the truncation is lossy. - uint64_t asUint64(Runtime& runtime) const; - - /// \returns this BigInt converted to a String in base \p radix. Throws a - /// JSIException if radix is not in the [2, 36] range. - inline String toString(Runtime& runtime, int radix = 10) const; - - friend class Runtime; - friend class Value; -}; - -/// Represents a JS String. Movable, not copyable. -class JSI_EXPORT String : public Pointer { - public: - using Pointer::Pointer; - - String(String&& other) = default; - String& operator=(String&& other) = default; - - /// Create a JS string from ascii values. The string data is - /// copied. - static String - createFromAscii(Runtime& runtime, const char* str, size_t length) { - return runtime.createStringFromAscii(str, length); - } - - /// Create a JS string from a nul-terminated C ascii string. The - /// string data is copied. - static String createFromAscii(Runtime& runtime, const char* str) { - return createFromAscii(runtime, str, strlen(str)); - } - - /// Create a JS string from a C++ string. The string data is - /// copied. - static String createFromAscii(Runtime& runtime, const std::string& str) { - return createFromAscii(runtime, str.c_str(), str.size()); - } - - /// Create a JS string from utf8-encoded octets. The string data is - /// transformed and copied. Results are undefined if \p utf8 contains invalid - /// code points. - static String - createFromUtf8(Runtime& runtime, const uint8_t* utf8, size_t length) { - return runtime.createStringFromUtf8(utf8, length); - } - - /// Create a JS string from utf8-encoded octets stored in a - /// std::string. The string data is transformed and copied. Results are - /// undefined if \p utf8 contains invalid code points. - static String createFromUtf8(Runtime& runtime, const std::string& utf8) { - return runtime.createStringFromUtf8( - reinterpret_cast(utf8.data()), utf8.length()); - } - - /// \return whether a and b contain the same characters. - static bool strictEquals(Runtime& runtime, const String& a, const String& b) { - return runtime.strictEquals(a, b); - } - - /// Copies the data in a JS string as utf8 into a C++ string. - std::string utf8(Runtime& runtime) const { - return runtime.utf8(*this); - } - - friend class Runtime; - friend class Value; -}; - -class Array; -class Function; - -/// Represents a JS Object. Movable, not copyable. -class JSI_EXPORT Object : public Pointer { - public: - using Pointer::Pointer; - - Object(Object&& other) = default; - Object& operator=(Object&& other) = default; - - /// Creates a new Object instance, like '{}' in JS. - Object(Runtime& runtime) : Object(runtime.createObject()) {} - - static Object createFromHostObject( - Runtime& runtime, - std::shared_ptr ho) { - return runtime.createObject(ho); - } - - /// \return whether this and \c obj are the same JSObject or not. - static bool strictEquals(Runtime& runtime, const Object& a, const Object& b) { - return runtime.strictEquals(a, b); - } - - /// \return the result of `this instanceOf ctor` in JS. - bool instanceOf(Runtime& rt, const Function& ctor) const { - return rt.instanceOf(*this, ctor); - } - - /// \return the property of the object with the given ascii name. - /// If the name isn't a property on the object, returns the - /// undefined value. - Value getProperty(Runtime& runtime, const char* name) const; - - /// \return the property of the object with the String name. - /// If the name isn't a property on the object, returns the - /// undefined value. - Value getProperty(Runtime& runtime, const String& name) const; - - /// \return the property of the object with the given JS PropNameID - /// name. If the name isn't a property on the object, returns the - /// undefined value. - Value getProperty(Runtime& runtime, const PropNameID& name) const; - - /// \return true if and only if the object has a property with the - /// given ascii name. - bool hasProperty(Runtime& runtime, const char* name) const; - - /// \return true if and only if the object has a property with the - /// given String name. - bool hasProperty(Runtime& runtime, const String& name) const; - - /// \return true if and only if the object has a property with the - /// given PropNameID name. - bool hasProperty(Runtime& runtime, const PropNameID& name) const; - - /// Sets the property value from a Value or anything which can be - /// used to make one: nullptr_t, bool, double, int, const char*, - /// String, or Object. - template - void setProperty(Runtime& runtime, const char* name, T&& value) const; - - /// Sets the property value from a Value or anything which can be - /// used to make one: nullptr_t, bool, double, int, const char*, - /// String, or Object. - template - void setProperty(Runtime& runtime, const String& name, T&& value) const; - - /// Sets the property value from a Value or anything which can be - /// used to make one: nullptr_t, bool, double, int, const char*, - /// String, or Object. - template - void setProperty(Runtime& runtime, const PropNameID& name, T&& value) const; - - /// \return true iff JS \c Array.isArray() would return \c true. If - /// so, then \c getArray() will succeed. - bool isArray(Runtime& runtime) const { - return runtime.isArray(*this); - } - - /// \return true iff the Object is an ArrayBuffer. If so, then \c - /// getArrayBuffer() will succeed. - bool isArrayBuffer(Runtime& runtime) const { - return runtime.isArrayBuffer(*this); - } - - /// \return true iff the Object is callable. If so, then \c - /// getFunction will succeed. - bool isFunction(Runtime& runtime) const { - return runtime.isFunction(*this); - } - - /// \return true iff the Object was initialized with \c createFromHostObject - /// and the HostObject passed is of type \c T. If returns \c true then - /// \c getHostObject will succeed. - template - bool isHostObject(Runtime& runtime) const; - - /// \return an Array instance which refers to the same underlying - /// object. If \c isArray() would return false, this will assert. - Array getArray(Runtime& runtime) const&; - - /// \return an Array instance which refers to the same underlying - /// object. If \c isArray() would return false, this will assert. - Array getArray(Runtime& runtime) &&; - - /// \return an Array instance which refers to the same underlying - /// object. If \c isArray() would return false, this will throw - /// JSIException. - Array asArray(Runtime& runtime) const&; - - /// \return an Array instance which refers to the same underlying - /// object. If \c isArray() would return false, this will throw - /// JSIException. - Array asArray(Runtime& runtime) &&; - - /// \return an ArrayBuffer instance which refers to the same underlying - /// object. If \c isArrayBuffer() would return false, this will assert. - ArrayBuffer getArrayBuffer(Runtime& runtime) const&; - - /// \return an ArrayBuffer instance which refers to the same underlying - /// object. If \c isArrayBuffer() would return false, this will assert. - ArrayBuffer getArrayBuffer(Runtime& runtime) &&; - - /// \return a Function instance which refers to the same underlying - /// object. If \c isFunction() would return false, this will assert. - Function getFunction(Runtime& runtime) const&; - - /// \return a Function instance which refers to the same underlying - /// object. If \c isFunction() would return false, this will assert. - Function getFunction(Runtime& runtime) &&; - - /// \return a Function instance which refers to the same underlying - /// object. If \c isFunction() would return false, this will throw - /// JSIException. - Function asFunction(Runtime& runtime) const&; - - /// \return a Function instance which refers to the same underlying - /// object. If \c isFunction() would return false, this will throw - /// JSIException. - Function asFunction(Runtime& runtime) &&; - - /// \return a shared_ptr which refers to the same underlying - /// \c HostObject that was used to create this object. If \c isHostObject - /// is false, this will assert. Note that this does a type check and will - /// assert if the underlying HostObject isn't of type \c T - template - std::shared_ptr getHostObject(Runtime& runtime) const; - - /// \return a shared_ptr which refers to the same underlying - /// \c HostObject that was used to create this object. If \c isHostObject - /// is false, this will throw. - template - std::shared_ptr asHostObject(Runtime& runtime) const; - - /// \return whether this object has native state of type T previously set by - /// \c setNativeState. - template - bool hasNativeState(Runtime& runtime) const; - - /// \return a shared_ptr to the state previously set by \c setNativeState. - /// If \c hasNativeState is false, this will assert. Note that this does a - /// type check and will assert if the native state isn't of type \c T - template - std::shared_ptr getNativeState(Runtime& runtime) const; - - /// Set the internal native state property of this object, overwriting any old - /// value. Creates a new shared_ptr to the object managed by \p state, which - /// will live until the value at this property becomes unreachable. - /// - /// Throws a type error if this object is a proxy or host object. - void setNativeState(Runtime& runtime, std::shared_ptr state) - const; - - /// \return same as \c getProperty(name).asObject(), except with - /// a better exception message. - Object getPropertyAsObject(Runtime& runtime, const char* name) const; - - /// \return similar to \c - /// getProperty(name).getObject().getFunction(), except it will - /// throw JSIException instead of asserting if the property is - /// not an object, or the object is not callable. - Function getPropertyAsFunction(Runtime& runtime, const char* name) const; - - /// \return an Array consisting of all enumerable property names in - /// the object and its prototype chain. All values in the return - /// will be isString(). (This is probably not optimal, but it - /// works. I only need it in one place.) - Array getPropertyNames(Runtime& runtime) const; - - /// Inform the runtime that there is additional memory associated with a given - /// JavaScript object that is not visible to the GC. This can be used if an - /// object is known to retain some native memory, and may be used to guide - /// decisions about when to run garbage collection. - /// This method may be invoked multiple times on an object, and subsequent - /// calls will overwrite any previously set value. Once the object is garbage - /// collected, the associated external memory will be considered freed and may - /// no longer factor into GC decisions. - 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 class Runtime; - friend class Value; -}; - -/// Represents a weak reference to a JS Object. If the only reference -/// to an Object are these, the object is eligible for GC. Method -/// names are inspired by C++ weak_ptr. Movable, not copyable. -class JSI_EXPORT WeakObject : public Pointer { - public: - using Pointer::Pointer; - - WeakObject(WeakObject&& other) = default; - WeakObject& operator=(WeakObject&& other) = default; - - /// Create a WeakObject from an Object. - WeakObject(Runtime& runtime, const Object& o) - : WeakObject(runtime.createWeakObject(o)) {} - - /// \return a Value representing the underlying Object if it is still valid; - /// otherwise returns \c undefined. Note that this method has nothing to do - /// with threads or concurrency. The name is based on std::weak_ptr::lock() - /// which serves a similar purpose. - Value lock(Runtime& runtime) const; - - friend class Runtime; -}; - -/// Represents a JS Object which can be efficiently used as an array -/// with integral indices. -class JSI_EXPORT Array : public Object { - public: - Array(Array&&) = default; - /// Creates a new Array instance, with \c length undefined elements. - Array(Runtime& runtime, size_t length) : Array(runtime.createArray(length)) {} - - Array& operator=(Array&&) = default; - - /// \return the size of the Array, according to its length property. - /// (C++ naming convention) - size_t size(Runtime& runtime) const { - return runtime.size(*this); - } - - /// \return the size of the Array, according to its length property. - /// (JS naming convention) - size_t length(Runtime& runtime) const { - return size(runtime); - } - - /// \return the property of the array at index \c i. If there is no - /// such property, returns the undefined value. If \c i is out of - /// range [ 0..\c length ] throws a JSIException. - Value getValueAtIndex(Runtime& runtime, size_t i) const; - - /// Sets the property of the array at index \c i. The argument - /// value behaves as with Object::setProperty(). If \c i is out of - /// range [ 0..\c length ] throws a JSIException. - template - void setValueAtIndex(Runtime& runtime, size_t i, T&& value) const; - - /// There is no current API for changing the size of an array once - /// created. We'll probably need that eventually. - - /// Creates a new Array instance from provided values - template - static Array createWithElements(Runtime&, Args&&... args); - - /// Creates a new Array instance from initializer list. - static Array createWithElements( - Runtime& runtime, - std::initializer_list elements); - - private: - friend class Object; - friend class Value; - friend class Runtime; - - void setValueAtIndexImpl(Runtime& runtime, size_t i, const Value& value) - const { - return runtime.setValueAtIndexImpl(*this, i, value); - } - - Array(Runtime::PointerValue* value) : Object(value) {} -}; - -/// Represents a JSArrayBuffer -class JSI_EXPORT ArrayBuffer : public Object { - public: - ArrayBuffer(ArrayBuffer&&) = default; - ArrayBuffer& operator=(ArrayBuffer&&) = default; - - ArrayBuffer(Runtime& runtime, std::shared_ptr buffer) - : ArrayBuffer(runtime.createArrayBuffer(std::move(buffer))) {} - - /// \return the size of the ArrayBuffer storage. This is not affected by - /// overriding the byteLength property. - /// (C++ naming convention) - 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); - } - - private: - friend class Object; - friend class Value; - friend class Runtime; - - ArrayBuffer(Runtime::PointerValue* value) : Object(value) {} -}; - -/// Represents a JS Object which is guaranteed to be Callable. -class JSI_EXPORT Function : public Object { - public: - Function(Function&&) = default; - Function& operator=(Function&&) = default; - - /// Create a function which, when invoked, calls C++ code. If the - /// function throws an exception, a JS Error will be created and - /// thrown. - /// \param name the name property for the function. - /// \param paramCount the length property for the function, which - /// may not be the number of arguments the function is passed. - static Function createFromHostFunction( - Runtime& runtime, - const jsi::PropNameID& name, - unsigned int paramCount, - jsi::HostFunctionType func); - - /// Calls the function with \c count \c args. The \c this value of the JS - /// function will not be set by the C++ caller, similar to calling - /// Function.prototype.apply(undefined, args) in JS. - /// \b Note: as with Function.prototype.apply, \c this may not always be - /// \c undefined in the function itself. If the function is non-strict, - /// \c this will be set to the global object. - Value call(Runtime& runtime, const Value* args, size_t count) const; - - /// Calls the function with a \c std::initializer_list of Value - /// arguments. The \c this value of the JS function will not be set by the - /// C++ caller, similar to calling Function.prototype.apply(undefined, args) - /// in JS. - /// \b Note: as with Function.prototype.apply, \c this may not always be - /// \c undefined in the function itself. If the function is non-strict, - /// \c this will be set to the global object. - Value call(Runtime& runtime, std::initializer_list args) const; - - /// Calls the function with any number of arguments similarly to - /// Object::setProperty(). The \c this value of the JS function will not be - /// set by the C++ caller, similar to calling - /// Function.prototype.call(undefined, ...args) in JS. - /// \b Note: as with Function.prototype.call, \c this may not always be - /// \c undefined in the function itself. If the function is non-strict, - /// \c this will be set to the global object. - template - Value call(Runtime& runtime, Args&&... args) const; - - /// Calls the function with \c count \c args and \c jsThis value passed - /// as the \c this value. - Value callWithThis( - Runtime& Runtime, - const Object& jsThis, - const Value* args, - size_t count) const; - - /// Calls the function with a \c std::initializer_list of Value - /// arguments and \c jsThis passed as the \c this value. - Value callWithThis( - Runtime& runtime, - const Object& jsThis, - std::initializer_list args) const; - - /// Calls the function with any number of arguments similarly to - /// Object::setProperty(), and with \c jsThis passed as the \c this value. - template - Value callWithThis(Runtime& runtime, const Object& jsThis, Args&&... args) - const; - - /// Calls the function as a constructor with \c count \c args. Equivalent - /// to calling `new Func` where `Func` is the js function reqresented by - /// this. - Value callAsConstructor(Runtime& runtime, const Value* args, size_t count) - const; - - /// Same as above `callAsConstructor`, except use an initializer_list to - /// supply the arguments. - Value callAsConstructor(Runtime& runtime, std::initializer_list args) - const; - - /// Same as above `callAsConstructor`, but automatically converts/wraps - /// any argument with a jsi Value. - template - Value callAsConstructor(Runtime& runtime, Args&&... args) const; - - /// Returns whether this was created with Function::createFromHostFunction. - /// If true then you can use getHostFunction to get the underlying - /// HostFunctionType. - bool isHostFunction(Runtime& runtime) const { - return runtime.isHostFunction(*this); - } - - /// Returns the underlying HostFunctionType iff isHostFunction returns true - /// and asserts otherwise. You can use this to use std::function<>::target - /// to get the object that was passed to create the HostFunctionType. - /// - /// Note: The reference returned is borrowed from the JS object underlying - /// \c this, and thus only lasts as long as the object underlying - /// \c this does. - HostFunctionType& getHostFunction(Runtime& runtime) const { - assert(isHostFunction(runtime)); - return runtime.getHostFunction(*this); - } - - private: - friend class Object; - friend class Value; - friend class Runtime; - - Function(Runtime::PointerValue* value) : Object(value) {} -}; - -/// Represents any JS Value (undefined, null, boolean, number, symbol, -/// string, or object). Movable, or explicitly copyable (has no copy -/// ctor). -class JSI_EXPORT Value { - public: - /// Default ctor creates an \c undefined JS value. - Value() : Value(UndefinedKind) {} - - /// Creates a \c null JS value. - /* implicit */ Value(std::nullptr_t) : kind_(NullKind) {} - - /// Creates a boolean JS value. - /* implicit */ Value(bool b) : Value(BooleanKind) { - data_.boolean = b; - } - - /// Creates a number JS value. - /* implicit */ Value(double d) : Value(NumberKind) { - data_.number = d; - } - - /// Creates a number JS value. - /* implicit */ Value(int i) : Value(NumberKind) { - data_.number = i; - } - - /// Moves a Symbol, String, or Object rvalue into a new JS value. - template < - typename T, - typename = std::enable_if_t< - std::is_base_of::value || - std::is_base_of::value || - std::is_base_of::value || - std::is_base_of::value>> - /* implicit */ Value(T&& other) : Value(kindOf(other)) { - new (&data_.pointer) T(std::move(other)); - } - - /// Value("foo") will treat foo as a bool. This makes doing that a - /// compile error. - template - Value(const char*) { - static_assert( - !std::is_same::value, - "Value cannot be constructed directly from const char*"); - } - - Value(Value&& value); - - /// Copies a Symbol lvalue into a new JS value. - Value(Runtime& runtime, const Symbol& sym) : Value(SymbolKind) { - new (&data_.pointer) Symbol(runtime.cloneSymbol(sym.ptr_)); - } - - /// Copies a BigInt lvalue into a new JS value. - Value(Runtime& runtime, const BigInt& bigint) : Value(BigIntKind) { - new (&data_.pointer) BigInt(runtime.cloneBigInt(bigint.ptr_)); - } - - /// Copies a String lvalue into a new JS value. - Value(Runtime& runtime, const String& str) : Value(StringKind) { - new (&data_.pointer) String(runtime.cloneString(str.ptr_)); - } - - /// Copies a Object lvalue into a new JS value. - Value(Runtime& runtime, const Object& obj) : Value(ObjectKind) { - new (&data_.pointer) Object(runtime.cloneObject(obj.ptr_)); - } - - /// Creates a JS value from another Value lvalue. - Value(Runtime& runtime, const Value& value); - - /// Value(rt, "foo") will treat foo as a bool. This makes doing - /// that a compile error. - template - Value(Runtime&, const char*) { - static_assert( - !std::is_same::value, - "Value cannot be constructed directly from const char*"); - } - - ~Value(); - // \return the undefined \c Value. - static Value undefined() { - return Value(); - } - - // \return the null \c Value. - static Value null() { - return Value(nullptr); - } - - // \return a \c Value created from a utf8-encoded JSON string. - static Value - createFromJsonUtf8(Runtime& runtime, const uint8_t* json, size_t length) { - return runtime.createValueFromJsonUtf8(json, length); - } - - /// \return according to the Strict Equality Comparison algorithm, see: - /// https://262.ecma-international.org/11.0/#sec-strict-equality-comparison - static bool strictEquals(Runtime& runtime, const Value& a, const Value& b); - - Value& operator=(Value&& other) { - 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; - } - - /// \return the boolean value, or asserts if not a boolean. - bool getBool() const { - assert(isBool()); - return data_.boolean; - } - - /// \return the boolean value, or throws JSIException if not a - /// boolean. - bool asBool() const; - - /// \return the number value, or asserts if not a number. - double getNumber() const { - assert(isNumber()); - return data_.number; - } - - /// \return the number value, or throws JSIException if not a - /// number. - double asNumber() const; - - /// \return the Symbol value, or asserts if not a symbol. - Symbol getSymbol(Runtime& runtime) const& { - assert(isSymbol()); - return Symbol(runtime.cloneSymbol(data_.pointer.ptr_)); - } - - /// \return the Symbol value, or asserts if not a symbol. - /// Can be used on rvalue references to avoid cloning more symbols. - Symbol getSymbol(Runtime&) && { - assert(isSymbol()); - auto ptr = data_.pointer.ptr_; - data_.pointer.ptr_ = nullptr; - return static_cast(ptr); - } - - /// \return the Symbol value, or throws JSIException if not a - /// symbol - Symbol asSymbol(Runtime& runtime) const&; - Symbol asSymbol(Runtime& runtime) &&; - - /// \return the BigInt value, or asserts if not a bigint. - BigInt getBigInt(Runtime& runtime) const& { - assert(isBigInt()); - return BigInt(runtime.cloneBigInt(data_.pointer.ptr_)); - } - - /// \return the BigInt value, or asserts if not a bigint. - /// Can be used on rvalue references to avoid cloning more bigints. - BigInt getBigInt(Runtime&) && { - assert(isBigInt()); - auto ptr = data_.pointer.ptr_; - data_.pointer.ptr_ = nullptr; - return static_cast(ptr); - } - - /// \return the BigInt value, or throws JSIException if not a - /// bigint - BigInt asBigInt(Runtime& runtime) const&; - BigInt asBigInt(Runtime& runtime) &&; - - /// \return the String value, or asserts if not a string. - String getString(Runtime& runtime) const& { - assert(isString()); - return String(runtime.cloneString(data_.pointer.ptr_)); - } - - /// \return the String value, or asserts if not a string. - /// Can be used on rvalue references to avoid cloning more strings. - String getString(Runtime&) && { - assert(isString()); - auto ptr = data_.pointer.ptr_; - data_.pointer.ptr_ = nullptr; - return static_cast(ptr); - } - - /// \return the String value, or throws JSIException if not a - /// string. - String asString(Runtime& runtime) const&; - String asString(Runtime& runtime) &&; - - /// \return the Object value, or asserts if not an object. - Object getObject(Runtime& runtime) const& { - assert(isObject()); - return Object(runtime.cloneObject(data_.pointer.ptr_)); - } - - /// \return the Object value, or asserts if not an object. - /// Can be used on rvalue references to avoid cloning more objects. - Object getObject(Runtime&) && { - assert(isObject()); - auto ptr = data_.pointer.ptr_; - data_.pointer.ptr_ = nullptr; - return static_cast(ptr); - } - - /// \return the Object value, or throws JSIException if not an - /// object. - Object asObject(Runtime& runtime) const&; - Object asObject(Runtime& runtime) &&; - - // \return a String like JS .toString() would do. - String toString(Runtime& runtime) const; - - private: - friend class Runtime; - - enum ValueKind { - UndefinedKind, - NullKind, - BooleanKind, - NumberKind, - SymbolKind, - BigIntKind, - StringKind, - ObjectKind, - PointerKind = SymbolKind, - }; - - union Data { - // Value's ctor and dtor will manage the lifecycle of the contained Data. - Data() { - static_assert( - sizeof(Data) == sizeof(uint64_t), - "Value data should fit in a 64-bit register"); - } - ~Data() {} - - // scalars - bool boolean; - double number; - // pointers - Pointer pointer; // Symbol, String, Object, Array, Function - }; - - 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_; - - // In the future: Value becomes NaN-boxed. See T40538354. -}; - -/// Not movable and not copyable RAII marker advising the underlying -/// JavaScript VM to track resources allocated since creation until -/// destruction so that they can be recycled eagerly when the Scope -/// goes out of scope instead of floating in the air until the next -/// garbage collection or any other delayed release occurs. -/// -/// This API should be treated only as advice, implementations can -/// choose to ignore the fact that Scopes are created or destroyed. -/// -/// This class is an exception to the rule allowing destructors to be -/// called without proper synchronization (see Runtime documentation). -/// The whole point of this class is to enable all sorts of clean ups -/// when the destructor is called and this proper synchronization is -/// required at that time. -/// -/// Instances of this class are intended to be created as automatic stack -/// variables in which case destructor calls don't require any additional -/// locking, provided that the lock (if any) is managed with RAII helpers. -class JSI_EXPORT 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 - static auto callInNewScope(Runtime& rt, F f) -> decltype(f()) { - Scope s(rt); - return f(); - } - - private: - Runtime& rt_; - Runtime::ScopeState* prv_; -}; - -/// Base class for jsi exceptions -class JSI_EXPORT 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_; -}; - -/// This exception will be thrown by API functions on errors not related to -/// JavaScript execution. -class JSI_EXPORT JSINativeException : public JSIException { - public: - JSINativeException(std::string what) : JSIException(std::move(what)) {} - - JSINativeException(const JSINativeException&) = default; - - virtual ~JSINativeException(); -}; - -/// This exception will be thrown by API functions whenever a JS -/// operation causes an exception as described by the spec, or as -/// otherwise described. -class JSI_EXPORT JSError : public JSIException { - public: - /// Creates a JSError referring to provided \c value - JSError(Runtime& r, Value&& value); - - /// Creates a JSError referring to new \c Error instance capturing current - /// JavaScript stack. The error message property is set to given \c message. - JSError(Runtime& rt, std::string message); - - /// Creates a JSError referring to new \c Error instance capturing current - /// JavaScript stack. The error message property is set to given \c message. - JSError(Runtime& rt, const char* message) - : JSError(rt, std::string(message)) {} - - /// Creates a JSError referring to a JavaScript Object having message and - /// stack properties set to provided values. - JSError(Runtime& rt, std::string message, std::string stack); - - /// Creates a JSError referring to provided value and what string - /// set to provided message. This argument order is a bit weird, - /// but necessary to avoid ambiguity with the above. - JSError(std::string what, Runtime& rt, Value&& value); - - /// Creates a JSError referring to the provided value, message and stack. This - /// constructor does not take a Runtime parameter, and therefore cannot result - /// in recursively invoking the JSError constructor. - 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_; - } - - private: - // This initializes the value_ member and does some other - // validation, so it must be called by every branch through the - // constructors. - void setValue(Runtime& rt, Value&& value); - - // This needs to be on the heap, because throw requires the object - // be copyable, and Value is not. - std::shared_ptr value_; - std::string message_; - std::string stack_; -}; - -} // namespace jsi -} // namespace facebook - -#include \ No newline at end of file diff --git a/vnext/Shared/JSI/ChakraApi.cpp b/vnext/Shared/JSI/ChakraApi.cpp index 6cf2e1c77b1..a49b70ec80d 100644 --- a/vnext/Shared/JSI/ChakraApi.cpp +++ b/vnext/Shared/JSI/ChakraApi.cpp @@ -319,8 +319,6 @@ ChakraApi::JsRefHolder::~JsRefHolder() noexcept { return result; } -/*static*/ void ChakraApi::setExternalMemoryPressure(JsValueRef object, size_t amt) {} - /*static*/ JsValueRef ChakraApi::GetProperty(JsValueRef object, JsPropertyIdRef propertyId) { JsValueRef result{JS_INVALID_REFERENCE}; ChakraVerifyJsErrorElseThrow(JsGetProperty(object, propertyId, &result)); diff --git a/vnext/Shared/JSI/ChakraApi.h b/vnext/Shared/JSI/ChakraApi.h index 4c3c4f977f2..1d639f7e2e9 100644 --- a/vnext/Shared/JSI/ChakraApi.h +++ b/vnext/Shared/JSI/ChakraApi.h @@ -349,12 +349,6 @@ struct ChakraApi { */ static bool InstanceOf(JsValueRef object, JsValueRef constructor); - /** - * @brief Inform the runtime that there is additional memory associated with a given JavaScript object that is not - * visible to the GC. - */ - static void setExternalMemoryPressure(JsValueRef object, size_t amt); - /** * @brief Gets an object's property. */ diff --git a/vnext/Shared/JSI/ChakraRuntime.cpp b/vnext/Shared/JSI/ChakraRuntime.cpp index 48dd74cd553..bed984a66ac 100644 --- a/vnext/Shared/JSI/ChakraRuntime.cpp +++ b/vnext/Shared/JSI/ChakraRuntime.cpp @@ -678,10 +678,6 @@ bool ChakraRuntime::instanceOf(const facebook::jsi::Object &obj, const facebook: return InstanceOf(GetJsRef(obj), GetJsRef(func)); } -void ChakraRuntime::setExternalMemoryPressure(const facebook::jsi::Object &obj, size_t amt) { - return setExternalMemoryPressure(obj, amt); -} - #pragma endregion Functions_inherited_from_Runtime // Sets variable in the constructor and then restores its value in the destructor. diff --git a/vnext/Shared/JSI/ChakraRuntime.h b/vnext/Shared/JSI/ChakraRuntime.h index bd10475b1eb..3cf3d0fbff6 100644 --- a/vnext/Shared/JSI/ChakraRuntime.h +++ b/vnext/Shared/JSI/ChakraRuntime.h @@ -152,7 +152,6 @@ class ChakraRuntime : public facebook::jsi::Runtime, public ChakraApi, ChakraApi bool strictEquals(const facebook::jsi::Object &a, const facebook::jsi::Object &b) const override; bool instanceOf(const facebook::jsi::Object &obj, const facebook::jsi::Function &func) override; - void setExternalMemoryPressure(const facebook::jsi::Object &obj, size_t amt) override; #pragma endregion Functions_inherited_from_Runtime From d4469ae9479b1a7e4e73bb9a8ea4f88adec58901 Mon Sep 17 00:00:00 2001 From: Vladimir Morozov Date: Thu, 18 Jan 2024 11:58:31 -0800 Subject: [PATCH 10/16] Update NodeApiJsi with the new JSI APIs --- vnext/Directory.Build.props | 2 +- vnext/ReactCommon/cgmanifest.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/vnext/Directory.Build.props b/vnext/Directory.Build.props index 7751b7e2b0e..cf9913e0e27 100644 --- a/vnext/Directory.Build.props +++ b/vnext/Directory.Build.props @@ -22,7 +22,7 @@ 10.1.0 ca2e3685b160617d3d95fcd9e789c4e06ca88 - 53b897b03c1c7e57c3372acc6234447a44e150d6 + 98abc6602c5c189bebff46cc5de9d303811657ab - 98abc6602c5c189bebff46cc5de9d303811657ab + 83cfef428a97627c9185c73da097e42742de56eb