From 97a9b15975d23919cc13313053df69613c09d5b6 Mon Sep 17 00:00:00 2001 From: Adam Gleitman Date: Tue, 3 Aug 2021 22:35:45 -0700 Subject: [PATCH] Merge from upstream through 2020-05-09 (#806) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Update default Podfile to not depend on a path (#28572) Summary: Recently, a default Podfile has been modified to not contain all the React Native pods, but use a helper method `use_react_native!`. While this is great, it assumes a hardcoded path of `../node_modules/react-native` to be always the correct location of the React Native. https://github.com/facebook/react-native/blob/d4d8887b5018782eeb3f26efa85125e6bbff73e4/scripts/autolink-ios.rb#L7-L9 Unfortunately, due to the way Ruby works, this completely hides the path away from the users. Before, they could have seen the wrong path explicitly in a Podfile and knew to update it to resolve path-related issues. With the current version in `master`, I can see a lot of issues where developers wonder how to resolve the path issues and how to pass the path itself. https://github.com/facebook/react-native/blob/4118d798265341061105f3a53550db83c66a71cb/template/ios/Podfile#L5-L10 This PR uses React Native CLI configuration (that is already used to link 3rd party dependencies) to explicitly define the correct path to the React Native. As a result, we don't have to change the paths here whether we're running monorepo or not. ## Changelog [IOS] [INTERNAL] - Always provide an explicit path to React Native Pull Request resolved: https://github.com/facebook/react-native/pull/28572 Differential Revision: D20945194 Pulled By: TheSavior fbshipit-source-id: 010f9754f2ed78ef62fd52f4d201f296f5af6d27 * Upgrade Prettier in Xplat to version 1.19.1 Summary: Upgrades Prettier in Xplat to 1.19.1 Ignores upgrading packages on already on versions greater than 1.19.1 Changelog: [Internal] allow-large-files bypass-lint (Note: this ignores all push blocking failures!) Reviewed By: gkz, cpojer Differential Revision: D20879147 fbshipit-source-id: 0deee7ac941e91e1c3c3a1e7d3d3ed20de1d657d * Stop using get_fbobjc_enable_exception_lang_compiler_flags_DEPRECATED in xplat Summary: Old deprecated function. Changelog: [Internal] Reviewed By: nlutsenko Differential Revision: D20148856 fbshipit-source-id: 79d6fb97824b059e50f67ff5a0b4c38ec7a19469 * Add ProGuard rule for hermes (#28571) Summary: This adds a ProGuard for `hermes` rule so it does not have to be added by users manually. https://github.com/facebook/react-native/issues/28270 ## Changelog [Android] [Added] - ProGuard rule for hermes Pull Request resolved: https://github.com/facebook/react-native/pull/28571 Test Plan: 1. Create a project with/without hermes. 2. Enable proguard. Reviewed By: cpojer Differential Revision: D20947095 Pulled By: hramos fbshipit-source-id: 79b166ad2dd060f20041d9f5cfe2f794c754843d * Move CheckBox JS files to FB Internal Summary: Move CheckBox JS files to FB internal ## Changelog: [General] [Removed] This diff removes the CheckBox export from React Native. Internally, we are requiring CheckBox directly now and externally people will have to use the community maintained module. Reviewed By: cpojer Differential Revision: D20910775 fbshipit-source-id: 809e135dc3f68911ac0a004e6eafa8488f0d5327 * fix: ripple should be applied even when borderless == false (#28526) Summary: With current master, when you render ``, there is no ripple effect at all. I think the expected behavior is to have ripple with default color and radius, just not borderless. This was how it was done (by me) in https://github.com/facebook/react-native/pull/28156/files but in the import process, the implementation was changed: https://github.com/facebook/react-native/commit/bd3868643d29e93610e19312571a9736df2cbdf8 so either this PR is a fix or you can just close it (but I'd be curious why). ## Changelog [Android] [fixed] - ripple should be applied even when borderless == false Pull Request resolved: https://github.com/facebook/react-native/pull/28526 Test Plan: `` on master ![SVID_20200404_123614_1](https://user-images.githubusercontent.com/1566403/78424971-6b315a80-7671-11ea-8be4-5fea428bc556.gif) `` in this PR ![SVID_20200404_122754_1](https://user-images.githubusercontent.com/1566403/78424986-8bf9b000-7671-11ea-9804-37cd58dbb61e.gif) Differential Revision: D20952026 Pulled By: TheSavior fbshipit-source-id: df2b95fc6f20d7e958e91805b1a928c4f85904f1 * Remove ColorAndroid function as it adds no value over PlatfromColor (#28577) Summary: This change removes the `ColorAndroid` API. It was added more as a validation tool than as something useful to a developer. When making the original [PlatformColor PR](https://github.com/facebook/react-native/pull/27908) we felt it was valuable and useful to have working platform specific methods for the two platforms in core to test that the pattern worked in app code (PlatformColorExample.js in RNTester) and that the Flow validation worked, etc. Practically `PlatformColor()` is more useful to a developer on Android than `ColorAndroid()`. Now that the construct has served its purpose, this PR removes the `ColorAndroid` function and its related tests and other collateral. ## Changelog [Android] [Removed] - Remove ColorAndroid function as it adds no value over PlatfromColor Pull Request resolved: https://github.com/facebook/react-native/pull/28577 Test Plan: RNTester in both iOS and Android was tested. Jest tests, Flow checks, Lint checks all pass. Reviewed By: cpojer Differential Revision: D20952613 Pulled By: TheSavior fbshipit-source-id: 7d2cbaa2a347fffe59a1f3a26a210676008fdac0 * iOS: mark some old NativeModule targets with depslint_never_remove Summary: Label some BUCK targets properly. Changelog: [Internal] Reviewed By: shergin Differential Revision: D20960917 fbshipit-source-id: 42fa2266105b6c3dd5108a1b56035a19a95cd61f * Update Gradle Wrapper to 6.3 (#28173) Summary: ``` Welcome to Gradle 6.3! Here are the highlights of this release: - Java 14 support - Improved error messages for unexpected failures For more details see https://docs.gradle.org/6.3/release-notes.html ``` ## Changelog [Android] [Changed] - Update Gradle Wrapper to 6.3 Pull Request resolved: https://github.com/facebook/react-native/pull/28173 Test Plan: Build project Differential Revision: D20958894 Pulled By: mdvacca fbshipit-source-id: a02ab0eb6aff97148c12b844fdd1f9f2617ae53f * Fix crash inside RCTRedBox when trying to present same UIViewController twice Summary: Calling `-[RCTRedBox showErrorMessage]` twice causes a crash We used `-[UIViewController isBeingPresented]` to tell whether view controller is already presented. But from the documentation: > A Boolean value indicating whether the view controller is being presented. Source: https://developer.apple.com/documentation/uikit/uiviewcontroller/2097564-beingpresented?language=objc# --- So this means that if you present it, wait until presentation animation is finished and then call `-[RCTRedBox showErrorMessage]` again, following exception will be thrown. ``` *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Application tried to present modally an active controller .' ``` Changelog: Fix crash caused by presenting view controller twice from RCTRedBox Reviewed By: PeteTheHeat Differential Revision: D20946645 fbshipit-source-id: 763066e37db4e56efb0118b2e7867ad0724bae81 * Animated: Early detection of division by zero in AnimatedDivision Summary: We currently see a lot of errors happens because of division by zero in `AnimatedDivision` module. We already have a check for that in the module but it happens during the animation tick where the context of execution is already lost and it's hard to find why exactly it happens. Adding an additional check to the constructor should trigger an error right inside render function which should make the error actionable. Changelog: [Internal] Early crash in AnimatedDivision in case of division by zero. Reviewed By: mdvacca Differential Revision: D20969087 fbshipit-source-id: 0d98774b79be2cc56d468a4f56d2d7c8abf58344 * Fabric: Controlling DifferentiatorMode via ReactNativeConfig Summary: Now we can control the differentiator mode via MC. Changelog: [Internal] Fabric-specific internal change. Reviewed By: fkgozali Differential Revision: D20978857 fbshipit-source-id: 13264948762f02f874d8d051c873d378062d6db4 * Upgrade Hermes dependency to 0.5.0 Summary: Use the latest published release of hermes-engine. Update RN to invoke `hermesc` instead of `hermes`. Changelog: [Android] [Changed] - Upgraded to Hermes 0.5.0 allow-large-files Reviewed By: mhorowitz Differential Revision: D20998564 fbshipit-source-id: 4824e273bcb044029a5a7e9379f168d3da47da50 * Set width/height also to Undefined when we change the measure mode to Undefined Summary: Make sure width/height is always passed as Undefined when measure mode is changed to Undefined. Changelog: [Internal][Yoga] Set width and height as Undefined when we change measure mode to Undefined Reviewed By: alickbass Differential Revision: D20029838 fbshipit-source-id: b9931f6ddb13ffd1565889535ade5bbffbe0c304 * Remove redundant input from TextInput Summary: `const ReactNative` is assigned to but never used. Let's get rid of it. Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D21016502 fbshipit-source-id: afcb0cfc501adf07e0c4d4452a831160e1cda088 * Update RNTester AppDelegate for changes made to SurfacePresenter API (#28580) Summary: This pull request updates RNTester's AppDelegate's Fabric mode to reflect changes made to the SurfacePresenter APIs. It now makes use of `RCTSurfacePresenterBridgeAdapter` to create its `SurfacePresenter`. ## Changelog [Internal] [Fixed] - Fixed outdated API usage in RNTester's AppDelegate Pull Request resolved: https://github.com/facebook/react-native/pull/28580 Test Plan: `RNTester/RNTester/AppDelegate.mm` now compiles without error when `RN_FABRIC_ENABLED` is enabled. Reviewed By: hramos Differential Revision: D20966067 Pulled By: mdvacca fbshipit-source-id: 8d0168d468240cff61554f2f2df799aaf5d876c1 * Retryable ViewCommand exceptions shouldn't crash Summary: Early ViewCommand Dispatch will solve this category of crashes by going through an entirely different codepath. For users not in that experiment, it might be good to have a mitigation that prevents non-critical issues from crashing (like "blur" failing). Currently, "blur" failures cause lots of screens to crash. There's no useful signal and those crashes aren't super actionable, so seems better to swallow. If/when early viewcommand dispatch ships as the default/only mode, we can remove this try/catch entirely. The only concern I have with landing this is the perf implications of putting a try/catch inside this loop. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21023213 fbshipit-source-id: 310fe2d55a44bc424692a2365ccd5882f35f9d82 * Remove setMostRecentEventCount from TextInput view commands Summary: Changelog: [Internal] We don't use view command `setMostRecentEventCount`, let's get rid of it. Reviewed By: JoshuaGross Differential Revision: D21016600 fbshipit-source-id: 6491c063e9d6a89252300cb47c010b248e473f4b * label-actions: Add canned response for upgrade issues Summary: Enhance the label-actions config and support a "Type: Upgrade Issue" label. - Point to the Upgrade Support repository whenever the Type: Upgrade Issue label is applied. - Close the issue. Changelog: [Internal] label-actions: Add canned response for upgrade issues Reviewed By: cpojer Differential Revision: D20974607 fbshipit-source-id: 3cd7890aaeb1e57baf2acc5ca85a9b3ae5117c56 * Yoga Podspec: Export YGNode and YGStyle headers (#997) Summary: This pull request adds `YGNode.h` and `YGStyle.h` to the headers exported by Yoga's podspec. They are required by the new Fabric architecture of React Native. The modulemap and its umbrella header automatically generated by Cocoapods adds all exported headers to the `modulemap`. Having YGNode and YGStyle exported through here has problems, because they are only available in environments that have C++ available, and will produce errors otherwise. This pull request fences off the contents of those headers in an `#ifdef __cplusplus` block, so they will not cause errors when imported into environments where C++ isn't available. I had considered adding a custom modulemap to the podspec as part of this pull request, but this way seems the least "invasive", and this way you are able to add and remove exported headers in the podspec without needing to worry about updating the umbrella header at the same time. Changelog: [Internal] - Yoga Podspec: Export YGNore and YGStyle headers Pull Request resolved: https://github.com/facebook/yoga/pull/997 Reviewed By: hramos Differential Revision: D20966075 Pulled By: mdvacca fbshipit-source-id: 5f5caa6b639d11e660b968d681da9a4de6c0eb8e * Add logging to catch null TurboModules Summary: We're still seeing NativeModule eager-init crashes in T46487253. So, just to be extra careful, in case this diff doesn't fix the problem, I'm adding logging into `TurboModuleManager.getModule(moduleName)` to see why TurboModules are showing up as `null`. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21027984 fbshipit-source-id: 74ee62aeac09a4fdb29547e90ef4fa7c07de17a6 * Remove module cache from ReactPackageTurboModuleManagerDelegate Summary: This cache is unnecessary, because: 1. TurboModuleManager caches all created TurboModules 2. TurboModuleManager calls into the TurboModuleManagerDelegate at most once per NativeModule `moduleName`. This diff also makes ReactPackageTurboModuleManager thread-safe, which should help get rid of the crashes in T46487253. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21027998 fbshipit-source-id: c9b5ccc3da7b81787b749e70aa5e55883317eed7 * Control concurrent calls into TMMDelegate from TMM Summary: In D20659799, I improved `TurboModuleManager.getModule(moduleName)` thread-safety by ensuring that if two threads race to require the same NativeModule, only one thread creates the NativeModule, while the other one waits until it's created. ## The problem: What I failed to realize was that when two threads race to require two different NativeModules, we can get concurrent calls into `TurboModuleManagerDelegate.getModule(moduleName)`, and `TurboModuleManagerDelegate.getLegacyCxxModule(moduleName)`, which don't have any thread-safe guarantees. ## The fix `TurboModuleManagerDelegate` is supposed to be an input to the TurboModule system. So, rather than expecting that all TurboModuleManagerDelegates are thread-safe, which might be a reasonable ask (see T65532092), this diff has `TurboModuleManager` acquire the delegate's lock before calling into it. This ensures that we don't get concurrent access into the delegate, which could be reading from, or writing to, some data structure in these method calls. (This was the case with `ReactPackageTurboModuleManagerDelegate`, which is what Fb4a and Workplace use under the hood). Changelog: [Android][Fixed] - Control concurrent calls into TMMDelegate from TurboModuleManager Reviewed By: mdvacca Differential Revision: D21025965 fbshipit-source-id: d22c4abfe87f9e534717a06f186dde87d3cd24df * Bump eslint-plugin-react-native-community version to 1.1.0 Summary: This release will include the new platform-colors rule. Changelog: [Internal] (Note: this ignores all push blocking failures!) Reviewed By: cpojer Differential Revision: D21022163 fbshipit-source-id: 65c831b3c820e44f75631b935118b043180ab3c7 * Update Babel to 7.8.x/7.9.x Reviewed By: motiz88 Differential Revision: D20697095 fbshipit-source-id: ef35d02da0916109ce528d3026f7ca0956911dda * fix: do not throw on missing `cliPath`, use the default value (#28625) Summary: The `cliPath` has always been optional value and in fact, even had its default value hardcoded in the React gradle file. In this PR, I am just taking use of it and remove throwing an error, which is going to be a really annoying breaking change. ## Changelog [ANDROID] [INTERNAL] - Don't require `cliPath` Pull Request resolved: https://github.com/facebook/react-native/pull/28625 Test Plan: Run Android project, everything works. Provide custom `cliPath`, it gets respected Reviewed By: cpojer Differential Revision: D21044222 Pulled By: TheSavior fbshipit-source-id: 8029f988d92abb9f64f30e05932c0d407d0c997e * Fix CIRCLE_PR_NUMBER may not always be set (#28640) Summary: This fixes build failures where `CIRCLE_PR_NUMBER` is not set. This can happen if the PR did not come from a fork. ## Changelog [Internal] [Fixed] - Fix CIRCLE_PR_NUMBER may not always be set Pull Request resolved: https://github.com/facebook/react-native/pull/28640 Test Plan: Report bundle size step should pass on both this PR and https://github.com/facebook/react-native/issues/28641. Reviewed By: cpojer Differential Revision: D21045553 Pulled By: TheSavior fbshipit-source-id: fdfcb1bb88a96345b78ca69c49623df71d4cd608 * Add "Open Debugger" and "Open React DevTools" to iOS dev menu Summary: This diff introduces a new "Open Debugger" menu item for VMs that support on device debugging and for opening the React DevTools in Flipper. Provided so that we don't drift too far from the Android code. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D20784270 fbshipit-source-id: 6bb16431d25a6c093a583e2e041b8cffa6765ddd * Changed iOS LaunchScreen from xib to storyboard (#28239) Summary: > Starting April 30, 2020, all apps submitted to the App Store must use an Xcode storyboard to provide the app’s launch screen and all iPhone apps must support all iPhone screens. Updated iOS Launch screen as per [App Store policy change](https://developer.apple.com/news/?id=03042020b). Community discussion: https://github.com/react-native-community/discussions-and-proposals/issues/209 ## Changelog Changed iOS Launch Screen from a `xib` to `storyboard`. The `LaunchScreen.xib` file has been replaced with `LaunchScreen.storyboard`. Xcode automatically picks up the new Launch Screen no additional change is required. [iOS] [Deleted] - Deleted LaunchScreen.xib [iOS] [Added] - Added LaunchScreen.storyboard Pull Request resolved: https://github.com/facebook/react-native/pull/28239 Test Plan: Build the Xcode project under `template/iOS` and verify that the new launch screen is identical to the previous one. Reviewed By: cpojer Differential Revision: D20408892 Pulled By: hramos fbshipit-source-id: 9c38df58d1304088a23f3d73e0fbd87675804f1a * Switch over to JavaTurboModule::InitParams Summary: ## Problem Every time we want to add, remove, or change the data passed to JavaTurboModule's constructor, we have to modify the C++ TurboModule codegen. (The same is true of `ObjCTurboModule`). **Why was this necessary?** - `JavaTurboModule` is effectively an abstract class whose constructor is always invoked by code-generated C++ classes. These C++ code-generated class constructors accept an argument list, and manually foward each and every item in that list to `JavaTurboModule::JavaTurboModule`. ## The fix In this diff, I introduce a struct `JavaTurboModule::InitParams`, to represent a bag of arguments: ``` class JSI_EXPORT JavaTurboModule : public TurboModule { public: struct InitParams { std::string moduleName; jni::alias_ref instance; std::shared_ptr jsInvoker; std::shared_ptr nativeInvoker; }; ``` All `JavaTurboModules` will be created with an instance of this `InitParams` struct, instead of a list of arguments. Our code-generated C++ `jsi::HostObject` sublcasses will simply accept `InitParams` in their constructor, and forward it to `JavaTurboModule`'s constructor. This way, the codegen remains oblivious to what arguments JavaTurboModule requires. ## Okay, but why do we need this change now? In the future, I plan to modify the constructor for `JavaTurboModule` to accept a performance logger, and a `RuntimeExecutor`. Similar modifications are planned for ObjC. For this reason, to avoid these four codemods, and any potential other codemods that occur because we're making modifications to `JavaTurboModule` or `ObjCTurboModule`, I'm launching this codemod, and the codemods in this stack. ## Misc Fix - Previously, we were generating the TurboModule name from the Spec filename. This is incorrect because that name represents the spec name. Now, the name will be forwarded from TurboModuleManager in the `JavaTurboModule::InitParams` struct. ## Alternative implementations I initially considered using `ContextContainer`, but decided against it because: 1. There are no type-safety guarantees. 2. I think it's a bit overkill for this scenario. We just need an opaque bag of data, and for our purposes a simple struct does the job fine. ## Commands run Reviewed By: fkgozali Differential Revision: D21035208 fbshipit-source-id: 9542cafea192081bc34d337ab3a7a783083eb06c * RN: Shrinkwrap Text Layout (Android) Summary: When text is in a constrained parent view using `maxWidth`, long text may wrap. When the text wraps, the final width is dependent on the word breaking strategy and text content. This means that the text width is not necessarily `maxWidth`. However, the current way that we compute text layout does not shrinkwrap the text width as much as possible. This leads to visual gaps to the end-side of wrapped text. This changes the text layout slightly so that we use the length of the longest line. This bug only exists on Android. After this change, Android behaves like iOS. Changelog: [Android] [Fixed] - Fixed excessive space in Text view with word-wrapping Reviewed By: JoshuaGross, mdvacca Differential Revision: D21056031 fbshipit-source-id: e9b7793f2632caafcce69bc15bac61330b0ed958 * (eslint-config) update community eslint plugin in eslint config (#28642) Summary: Updating the community eslint-plugin used in the eslint-config to the latest version. expecting new eslint-config version to be released with this change so that it can be included in new project template for 0.63 https://github.com/react-native-community/releases/issues/186 ## Changelog [General] [Changed] - Update community eslint plugin in the eslint config Pull Request resolved: https://github.com/facebook/react-native/pull/28642 Test Plan: yarn lint passes Differential Revision: D21048976 Pulled By: cpojer fbshipit-source-id: 2c3ec0ef450cf357d8c88db7873f4ca1154b2034 * chore: update CLI to the latest version (#28623) Summary: Bumps CLI to the latest version, needed by https://github.com/facebook/react-native/pull/28572 to work. ## Changelog [INTERNAL] - Bump CLI to latest Pull Request resolved: https://github.com/facebook/react-native/pull/28623 Reviewed By: hramos Differential Revision: D21017766 Pulled By: cpojer fbshipit-source-id: 62a873923c58f8752edb0394db7e6dfceed92485 * Add "Open Debugger" and "Open React DevTools" to Android dev menu Summary: This diff introduces a new "Open Debugger" menu item for VMs that support on device debugging and for opening the React DevTools in Flipper. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D20784279 fbshipit-source-id: caecdace00007224692d994a75c106842c8b2acb * Remove the post install step (#28651) Summary: Removes the post install step for Flipper, as the latest version of YogaKit is compatible with swift 5. cc alloy ## Changelog [Flipper] [Template] - Remove the post install step for Flipper Pull Request resolved: https://github.com/facebook/react-native/pull/28651 Test Plan: Tested a newly created RN app without post install step and it built successfully. Reviewed By: passy Differential Revision: D21064653 Pulled By: priteshrnandgaonkar fbshipit-source-id: da56d0754d918e30a0ebe480c77590f0139d48ac * Revert D21064653: Remove the post install step Differential Revision: D21064653 Original commit changeset: da56d0754d91 fbshipit-source-id: 1086cfdeca9aa3830370ea115ba7b5f05d3fb124 * Remove out of date TODO Summary: No longer relevant. Changelog: [Internal] Reviewed By: mhorowitz Differential Revision: D21070955 fbshipit-source-id: 11b0384501b2780f5ac41899b5e8bbb4f7a4d730 * RNTester LayoutAnimation example: add more options Summary: Add more options to the LayoutAnimation example so it's easier to test more features of LayoutAnimations. 1) Add an option to animate reordering of views 2) Make animations slower, so it's easier to see what's going on and easier to trigger race conditions 3) Add options to mutate without animation, to test interrupting existing animations Changelog: [Internal] Updated Catalyst RNTester LayoutAnimation example with additional options Reviewed By: mdvacca Differential Revision: D21050309 fbshipit-source-id: 1daba4fd487693c34a2d40eb39a68c7d03c24f93 * Add a "reparenting" LayoutAnimation example that animates flattening/unflattening Summary: Simple test to see what it looks like when view flattening/unflattening is animated with LayoutAnimations. Changelog: [Internal] adding another example to LayoutAnimations example Reviewed By: mdvacca Differential Revision: D21074805 fbshipit-source-id: 551ed740f0ab5c5adcb19f5c35e932b8983cd108 * Fix jsi cmake include dirs (#207) Summary: I'm trying to use JSI for a React Native custom module. I saw these existing examples where the JSI API is used in the context of a CMakeLists.txt: https://github.com/terrysahaidak/host-object-test/blob/master/libs/android-jsi/test-jsi/src/main/cpp/CMakeLists.txt https://github.com/ericlewis/react-native-hostobject-demo/pull/4/files#diff-834320be1b4e4016bac27c05dcd17fb9 In both cases, they manually grab the include directories and jsi.cpp from node_modules/react-native, but I also saw that node_modules/react-native/ReactCommon/jsi/jsi already has a CMakeLists.txt that appears to be intended to provide a jsi static lib, so I tried to pull this into my own CMakeLists.txt like this: ``` add_subdirectory(${RN_DIR}/ReactCommon/jsi/jsi ${CMAKE_CURRENT_BINARY_DIR}/jsi) ... target_link_libraries(MyLib jsi) ``` Unfortunately when doing this, the consuming project still doesn't see the correct include directories. The change I'm proposing here is to use `target_include_directories` and declare that `..` is a public (to consumers) include directory for the library named `jsi`. With this change, you can do what I showed above to consume the jsi lib by just pulling in the CMakeLists.txt file into your own CMakeLists.txt file. Changelog: [General][Fixed] Fix jsi cmake include dirs Pull Request resolved: https://github.com/facebook/hermes/pull/207 Reviewed By: willholen Differential Revision: D21074270 Pulled By: tmikov fbshipit-source-id: 7d9ec3255f57a16c0b2be489dffa4540727738a1 * Resolve `kind-of` vulnerability by bumping to 6.0.3 Summary: https://github.com/advisories/GHSA-6c8f-qphg-qjgp Changelog: [General][Changed] Updated transitive dependency kind-of to 6.0.3 to resolve vulnerability (Note: this ignores all push blocking failures!) Reviewed By: cpojer Differential Revision: D21077747 fbshipit-source-id: d5c19b21b665130c6423f5caeddcd6378bac7dcb * Move CheckBox Android files to FB internal (#28658) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/28658 This moves the Java files to FB internal and updates all the buck files. ## Changelog: [Android] [Removed] This diff removes the CheckBox export from React Native. Internally, we are requiring CheckBox directly now and externally people will have to use the community maintained module. Reviewed By: cpojer Differential Revision: D21066998 fbshipit-source-id: 76821fcae899ff7342697ea7dd4737ef3b008213 * Part 1: Update ObjC++ codegen classes to use ObjCTurboModule::InitParams Summary: ## Summary Please check out D21035208. ## Changes - `ObjCTurboModule::ObjCTurboModule` changed to accept a bag of arguments `const ObjCTurboModule::InitParams` instead of an argument list. - TurboModule iOS codegen scripts updated to generated `ObjCTurboModule` subclasses that accept a `const ObjCTurboModule::InitParams` object in their constructor, and forward it to `ObjCTurboModule::ObjCTurboModule`. - All manually checked in code-generated ObjC++ classes (i.e: RCTNativeSampleTurboModule, RCTTestModule, FBReactNativeSpec) are updated. ## Rationale This way, the code-gen can remain constant while we add, remove, or modify the arguments passed to ObjCTurboModule. ## Commands run ``` function update-codegen() { pushd ~/fbsource && js1 build oss-native-modules-specs -p ios && js1 build oss-native-modules-specs -p android && popd; } > update-codegen ``` Changelog: [iOS][Changed] Update ObjCTurboModule to use ObjCTurboModule::InitParams Reviewed By: PeteTheHeat Differential Revision: D21036266 fbshipit-source-id: 6584b0838dca082a69e8c14c7ca50c3568b95086 * Part 2: Update ObjC++ codegen classes to use ObjCTurboModule::InitParams Summary: ## Summary Please check out D21035209. ## Changes - Codemod all ObjC NativeModule `getTurboModuleWithJsInvoker:nativeInvoker:perfLogger` methods to `getTurboModule:(const ObjCTurboModule::Args)` ## Script ``` var withSpaces = (...args) => args.join('\s*') var regexString = withSpaces( '-', '\(', 'std::shared_ptr', '<', '(?(facebook::react::|react::|::|)TurboModule)', '>', '\)', 'getTurboModuleWithJsInvoker', ':', '\(', 'std::shared_ptr', '<', '(?(facebook::react::|react::|::|))CallInvoker', '>', '\)', '(?[A-Za-z0-9]+)', 'nativeInvoker', ':', '\(', 'std::shared_ptr', '<', '(facebook::react::|react::|::|)CallInvoker', '>', '\)', '(?[A-Za-z0-9]+)', 'perfLogger', ':', '\(', 'id', '<', 'RCTTurboModulePerformanceLogger', '>', '\)', '(?[A-Za-z0-9]+)', '{', 'return', 'std::make_shared', '<', '(?(facebook::react::|react::|::|)Native[%A-Za-z0-9]+SpecJSI)', '>', '\(', 'self', ',', '\k', ',', '\k', ',', '\k', '\)', ';', '}', ) var replaceString = `- (std::shared_ptr<$>) getTurboModule:(const $ObjCTurboModule::InitParams &)params { return std::make_shared<$>(params); }` const exec = require('../lib/exec'); const abspath = require('../lib/abspath'); const relpath = require('../lib/relpath'); const readFile = (filename) => require('fs').readFileSync(filename, 'utf8'); const writeFile = (filename, content) => require('fs').writeFileSync(filename, content); function main() { const tmFiles = exec('cd ~/fbsource && xbgs -n 10000 -l getTurboModuleWithJsInvoker:').split('\n').filter(Boolean); tmFiles .filter((filename) => !filename.includes('microsoft-fork-of-react-native')) .map(abspath) .forEach((filename) => { const source = readFile(filename); const newSource = source.replace(new RegExp(regexString, 'g'), replaceString); if (source == newSource) { console.log(relpath(filename)); } writeFile(filename, newSource); }); } if (!module.parent) { main(); } ``` ## Re-generating diff ``` > hg revert -r .^ --all > node index.js # run script ``` Changelog: [iOS][Changed] - Make all ObjC NativeModules create TurboModules using ObjCTurboModule::Args Reviewed By: PeteTheHeat Differential Revision: D21036265 fbshipit-source-id: 404bcc548d1775ef23d793527606d02fe384a0a2 * Part 3: Update RCTTurboModuleManagerDelegate to use ObjCTurboModule::InitParams Summary: ## Summary Please check out D21035208. ## Changes - Update `RCTTurboModuleManagerDelegate getTurboModule:instance:jsInvoker:nativeInvoker:perfLogger` to use `RCTTurboModuleManagerDelegate getTurboModule:(const ObjCTurboModule::InitParams)` - Update all implementations of `RCTTurboModuleManagerDelegate` in accordance with this API change Changelog: [iOS][Changed] - Make RCTTurboModuleManagerDelegate create TurboModules via ObjCTurboModuleManager::InitParams Reviewed By: PeteTheHeat Differential Revision: D21036272 fbshipit-source-id: c16002c47db26e2ba143fc1080afe9e2fe1e7816 * chore: update `./scripts/test-manual-e2e.sh` (#28653) Summary: Recent changes broke the script - wrong path to open `RNTesterPods.xcworkspace` and other scripts - we change dir with `cd`. Another change is incorrect use of `RNTesterProject.xcodeproj` instead of a `xcworkspace`. This PR is a simple and short fix to make it run. ## Changelog [INTERNAL] - chore: update `./scripts/test-manual-e2e.sh` Pull Request resolved: https://github.com/facebook/react-native/pull/28653 Test Plan: Run `./scripts/test-manual-e2e.sh`. Things work. Differential Revision: D21079792 Pulled By: hramos fbshipit-source-id: 6bdb8be016f044852ed216ec53f80db40c84b5fd * use default value of enums YGDirection and YGMeasureMode instead of -1 Summary: Changelog: [Internal][Yoga] YGDirection variable was initialized incorrectly by casting -1 to YGDirection. Changing it to default value of direction Same for YGMeasureMode. Reviewed By: pasqualeanatriello Differential Revision: D20869042 fbshipit-source-id: 7bfe490193321baae875ef6fb49a938851950c9f * fix typo as there is no file called YGJNI.cpp (#990) Summary: fix typo in `YogaJNIBase.java` as there is no such file called `YGJNI.cpp` Pull Request resolved: https://github.com/facebook/yoga/pull/990 Reviewed By: pasqualeanatriello Differential Revision: D20735102 Pulled By: SidharthGuglani fbshipit-source-id: 3f9f4d78ba390feae3451330f997a221ab4ec70e * Remove unused packages from xplat/js/package.json Summary: We have a large amount of small packages that are completely unused, or only have one call site. This diff cleans up a lot of them and reduces node_modules by 12 MiB (down to 187). Changelog: [Internal] Reviewed By: motiz88 Differential Revision: D21088213 fbshipit-source-id: 5fa7d3da5cbe744b0d9d3e3450d6135c1488ee79 * Make ColorValue public in StyleSheet.js Summary: This diff makes the ColorValue export "official" by exporting it from StyleSheet in order to encourage its use in product code. Changelog: Moved ColorValue export from StyleSheetTypes to StyleSheet Reviewed By: TheSavior Differential Revision: D21076969 fbshipit-source-id: 972ef5a1b13bd9f6b7691a279a73168e7ce9d9ab * Fabric: `LayoutableShadowNode:getLayoutMetrics` is not a virtual method anymore Summary: We don't use it as vitrual anymore (setLayoutMetrics is a non-virtual method already), so it does not need to be marker virtual. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D21028572 fbshipit-source-id: 99f86fdd4cf2f5972034d9058d7b82bdc8680187 * Fabric: Proper traits for `ImageShadowNode` and `ViewShadowNode` Summary: * must be a leaf node; having a proper trait will fail earlier in case of misuse (mounting something inside). * must have a `View` trait because it's for what that trait is. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D21028573 fbshipit-source-id: 457716d4661333eb2357f34316f3e495ab4fda24 * Fabric: "Attempt to mutate a sealed object." is now an assert (not exception) Summary: This is a debug-only feature that simply should be an assert. When it triggers in debugger and bubbles to some random exception catch block which makes it impossible to understand was exactly it happens. Making it an assert will stop debugger exactly where it happens. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D21028571 fbshipit-source-id: 3df4ec0da922026bb9df61081cb71113577e06e9 * Fabric: Implementation of `getDebugDescription` for `std::array` Summary: Yoga uses `std::array` a lot (and `std::array` is not a `std::vector`), so it's useful for printing Yoga values. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D21028570 fbshipit-source-id: c6bf114d5362f085ea201ecdc5b7d59646b33ebd * Fabric: `componentregistry` module was decoupled from `uimanager` Summary: We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise). Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D20885163 fbshipit-source-id: 08eb1ba1d408fc0948e8d0da62380786a40973af * Fabric: `scheduler` module was decoupled from `uimanager` Summary: We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise). Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D20885645 fbshipit-source-id: 8148bd934879802b076261ed86fa78acf0a07ed3 * Fabric: `templateprocessor` module was decoupled from `uimanager` Summary: We need to break up the `uimanager` module in order to solve circular dependencies problem (which future diff would have otherwise). Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D20885646 fbshipit-source-id: b8e3199c0eacc57a5be1481595cf97c84f972293 * Migrate deprecated frameInterval to preferredFramesPerSecond (#28675) Summary: [frameInterval](https://developer.apple.com/documentation/quartzcore/cadisplaylink/1621231-frameinterval) was deprecated in favor of [preferredFramesPerSecond](https://developer.apple.com/documentation/quartzcore/cadisplaylink/1648421-preferredframespersecond). This migrates the deprecated call over. ## Changelog [iOS] [Fixed] - Migrate frameInterval to preferredFramesPerSecond Pull Request resolved: https://github.com/facebook/react-native/pull/28675 Test Plan: Xcode should no longer throw warnings about the deprecated call. Differential Revision: D21109710 Pulled By: shergin fbshipit-source-id: 772b9f625d3e22cd4d8cd60bddad57ff8611af54 * Fabric: Fix case of Glog include in MountingTest.cpp (#28616) Summary: This pull request changes the include of Glog from `` to `` in `MountingTest.cpp`. This fixes building on a case-sensitive filesystem. ## Changelog [Internal] [Fixed] - Fabric: Fix case of Glog include in MountingTest.cpp Pull Request resolved: https://github.com/facebook/react-native/pull/28616 Test Plan: The `include` of Glog no longer causes issues with building `MountingTest.cpp` on a case-sensitive filesystem. Differential Revision: D21118085 Pulled By: shergin fbshipit-source-id: c958c54bf88333fd5001127779c855ce8c2666c3 * Fabric: Add Unicode prefix to AttachmentCharacter (#28617) Summary: This pull request adds a Unicode `u8` prefix to the string literal returned in `AttributedString.cpp`'s `Fragment::AttachmentCharacter()`. This fixes the following error when building on MSVC: ``` react\attributedstring\AttributedString.cpp(21): error C4566: character represented by universal-character-name '\uFFFC' cannot be represented in the current code page (1252) ``` ## Changelog [Internal] [Fixed] - Fabric: Add Unicode prefix to AttachmentCharacter Pull Request resolved: https://github.com/facebook/react-native/pull/28617 Test Plan: The Fabric test suite has been ran on a Clang-based build of Fabric on macOS, and no regressions in it have been noted. Differential Revision: D21118078 Pulled By: shergin fbshipit-source-id: c105de5e4edb67fed97ce44153a75d9d380bf588 * Fabric: Fixed incorrect early-return in `UIView+ComponentViewProtocol::updateLayoutMetrics` Summary: Before the change, an incorrect (NaN or Inf) values in LayoutMetrics might force an early return in the `updateLayoutMetrics:oldMetrics:` method implementation. This was not correct because the rest of the method also didn't run in this case, so it might force some value to stale. E.g., imagine we have an instruction that contains NaN size and `display: none`. Previously, the function might just return right before applying sizes and progress the stored "already applied" value of LayoutMetrics which will cause the view being visible even if it should not. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21110644 fbshipit-source-id: 501319d7b1dcd5c18f27e0ceca3c8d207485c49b * Fix border-stroke drawing after resetting border-radius (#28356) Summary: This PR fixes incorrect drawing of the View borders on Android, after changing the border-radius back to 0 *(and when no background-color is defined)*. This happens because the `drawRoundedBackgroundWithBorders` function in ReactViewBackgroundDrawable changes the style on the Paint object to `STROKE`. This style is however never reverted back to `FILL`. This change ensures that the Paint style is set to `FILL` for the full execution of the `drawRectangularBackgroundWithBorders` function. ## Changelog `[Android] [Fixed] - Fix border-drawing when changing border-radius back to 0` Pull Request resolved: https://github.com/facebook/react-native/pull/28356 Test Plan: **Faulty situation:** ![ezgif com-video-to-gif](https://user-images.githubusercontent.com/6184593/77153163-9759b280-6a99-11ea-82bb-33a1e0a4934c.gif) **After the fix:** ![ezgif com-video-to-gif (1)](https://user-images.githubusercontent.com/6184593/77153825-c91f4900-6a9a-11ea-8e0c-a4280b9e72b8.gif) Differential Revision: D21124741 Pulled By: shergin fbshipit-source-id: 2044f8e8ad59a58df42b64d7ee8c4ad1d3b562f1 * Fabric: Using proper clock in MountingTelemetryTest Summary: Apparently, `std::this_thread::sleep_for` uses a different clock to measure time which causes ofter misalignment with the clock which Telemery uses which makes the test flaky. Using the same clock should fix it. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21116058 fbshipit-source-id: 52dde2e325776d365431a2a957dcc12dfe53f890 * Fix rounded border drawing when border-radius is smaller than border-width (#28358) Summary: This PR fixes the drawing of the border rounded edges when the border-radius is small than the border-width. The current implementation capped the possible border-radius making it impossible to set smaller border-radii when using thicker borders. After inspection it was found that the rounded-rect calculation is incorrect. ## Changelog `[Android] [Fixed] - Fix rounded border-drawing when border-radius is smaller than border-width` Pull Request resolved: https://github.com/facebook/react-native/pull/28358 Test Plan: **Faulty situation:** As you can see, when the border-radius becomes very low, the border is stuck at a minimum value. Only after setting the border-radius fully to 0 is it again rendered correctly. ![ezgif com-video-to-gif (2)](https://user-images.githubusercontent.com/6184593/77183540-c3435b00-6ace-11ea-950d-29a0ea1757bd.gif) **After the fix:** ![ezgif com-video-to-gif (3)](https://user-images.githubusercontent.com/6184593/77183619-e837ce00-6ace-11ea-93a5-910127d352b7.gif) Differential Revision: D21124739 Pulled By: shergin fbshipit-source-id: cefd1776b77b5b9fb335e95fd7fdd7f345579dc4 * Fabric: `ComponentDescriptor::cloneProps()` now never returns the base props objects Summary: The diff changes how the `empty raw props` optimization works in `ComponentDescriptor::cloneProps()`. Now it only fires only when the base `props` object is null, which is practically all production cases we have (and care about). (I tried, in a normal run there were no cases where the empty raw props were passed with non-null props.) From the other side, the old behavior that may return the same props objects previously several times created bugs and practically unexpected results and practically disallowed to clone props objects easily. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21110608 fbshipit-source-id: 884807cd8e9c5c3e6cc1c9e4c1f0227259cc21fb * Upgrade to Jest 25 Summary: This diff upgrades Jest to the latest version which fixes a bunch of issues with snapshots (therefore allowing me to enable the Pressable-test again). Note that this also affects Metro and various other tooling as they all depend on packages like `jest-worker`, `jest-haste-map` etc. Breaking changes: https://github.com/facebook/jest/blob/master/CHANGELOG.md This diff increases node_modules by 3 MiB, primarily because it causes more duplicates of `source-map` (0.8 MiB for each copy) and packages like `chalk` 3.x (vs 2.x). The base install was 15 MiB bigger and I reduced it to this size by playing around with various manual yarn.lock optimizations. However, D21085929 reduces node_modules by 11 MiB and the Babel upgrade reduced node_modules by 13 MiB. I will subsequently work on reducing the size through other packages as well and I'm working with the Jest folks to get rid of superfluous TypeScript stuff for Jest 26. Other changes in this diff: * Fixed Pressable-test * Blackhole node-notifier: It's large and we don't need it, and also the license may be problematic, see: https://github.com/facebook/jest/pull/8918 * Updated jest-junit (not a Jest package) but blackholed it internally because it is only used for open source CI. * Updated some API calls we use from Jest to account for breaking changes * Made two absolutely egrigious changes to existing product code tests to make them still pass as our match of async/await, fake timers and then/promise using `setImmediate` is tripping up `regenerator` with `Generator is already run` errors in Jest 25. These tests should probably be rewritten. * Locked everything to the same `resolve` version that we were already using, otherwise it was somehow pulling in 1.16 even though nothing internally uses it. Changelog: [General] Update Jest Reviewed By: rickhanlonii Differential Revision: D21064825 fbshipit-source-id: d0011a51355089456718edd84ea0af21fd923a58 * Apply placeholderColor to TextInput component Summary: Changelog: [Internal] TextInput's `placeholderTextColor` prop was being ignored. This diff fixes that. Reviewed By: JoshuaGross Differential Revision: D21064118 fbshipit-source-id: 33f148c355cee846db010153e0c65ea43155c3c9 * Fix mistake in swapping left/right layout properties Summary: Changelog: [Internal] We were assigned `undefined` value to incorrect edge, instead of `YGEdgeLeft` it should have been `YGEdgeRight`. If node has `YGEdgeRight` value, it needs to be reassigned to `YGEdgeEnd` and its original value set to undefined. Reviewed By: mdvacca Differential Revision: D21095234 fbshipit-source-id: fbecd9b7e6670742ad4a4bb097760aa10eec8685 * Fixed incorrect owner assignment in YGNode move constructor Summary: Assigning self as an owner makes a cycle which is obviously a bug. Changelog: [Internal] Small change in Yoga (should not affect RN). Reviewed By: SidharthGuglani Differential Revision: D21111423 fbshipit-source-id: 1835561c055ac827f5ce98a044f25aed0d1845a5 * Easy diff to add a TODO Summary: Easy diff to add a TODO to refactor `sendAccessibilityEvent` to use ViewCommands This was orginally added D17142507 changelog: [Internal] Internal change Reviewed By: JoshuaGross Differential Revision: D21137348 fbshipit-source-id: aff38ccad8dfbb222f83161e2bd5da82f543e5db * Add support for generating custom messages Summary: Until now we've generated scaffolding entirely based on the official devtools protocol spec. This diff adds support for defining custom domains in `custom.json` which will be merged with the upstream protocol JSON definition. ChangeLog: [Internal] Add support for Hermes-specific CDP messages Reviewed By: bestander Differential Revision: D20754605 fbshipit-source-id: a8075f81816a40114d1a3332192c7aa076b17848 * Implement Hermes.setPauseOnLoad Summary: This Hermes-specific mode is similar to Debugger.setPauseOnExceptions and lets the VM know that it should enter a Pause state whenever a new script is loaded/executed. The debugger can then take its time to parse the source map and update any breakpoints, before automatically continuing. Changelog: [Internal] Implement a Hermes.setPauseOnLoad CDP call Reviewed By: bestander Differential Revision: D20754604 fbshipit-source-id: 7f9d0638706c99e9dcb534699b633f658e364909 * Switch isPackagerRunning to a class method. Summary: This diff exports `isPackagerRunning` as a class method to be used without and instance. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D21094414 fbshipit-source-id: 44becb59e3c08d66e4992c4c1b32d6efcd4fe257 * Fabric: Fixed `getDirtied` vs `isDirty` in `YogaLayoutableShadowNode` Summary: This is quite a fateful mistake. `getDirtied()` returns the pointer to a function which is obviously a mistake here; we should use `isDirty()` instead. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D21028569 fbshipit-source-id: 95212b31f4e32d51c594d5209f295397af3f1252 * Fabric: More strict policies to dirty Yoga nodes in YogaLayoutableShadowNode Summary: Yoga uses a dirty flag to re-layout nodes. In normal, single-threaded approach the policy for dirtying is simple: if a node was changed, we need to dirty it. In the Concurrent Yoga approach, those rules are not so simple, and it seems we haven't formalized those rules yet. Investigating some layout issues that we have in Fabric, I tend to believe that we don't dirty as much we should. Hense this change adds mode dirtying. Reviewed By: JoshuaGross Differential Revision: D21092815 fbshipit-source-id: 4603c97ccb79efcdf5e6a4cc450ebe61b63effb3 * Allow iOS PlatformColor strings to be ObjC or Swift UIColor selectors (#28703) Summary: Per discussion in https://github.com/react-native-community/releases/issues/186 the iOS `PlatformColor()` function is documented to use the semantic color names provided by the system. The referenced HIG documentation itself links to the `UIColor` documentation for semantic colors names. However, these names differ depending on if you are viewing the new Swift API docs or the Objective C docs. The current Objective C implementation in react-native assumes Objective C UIColor selector names that are suffixed 'Color'. But in Swift, Apple provides a Swift Extension on UIColor that makes aliases without the the 'Color' suffix and then makes the original selectors invalid presumably via `NS_UNAVAILABLE_SWIFT`. Since both selector names are valid depending on if you are using Objective C or Swift, let's make both forms be legal for `PlatformColor()`. In `RCTConvert.m` there is a dictionary of legal selector names. The code already supports the ability to have names be aliases of other selectors via a RCTSelector metadata key. The change adds code to the initialization of the map: it iterates over the keys in the map, which are all ObjC style UIColor selectors, and creates aliases by duplicating the entries, creating key names by stripping off the ObjC "Color" suffix, adds the RCTSelector key referring to the original and then appends these new Swift aliases to the map. ## Changelog [iOS] [Changed] - Allow iOS PlatformColor strings to be ObjC or Swift UIColor selectors Pull Request resolved: https://github.com/facebook/react-native/pull/28703 Test Plan: The PlatformColorExample.js is updated to use the new, shorter Swift selector names. There are still other examples in the same file and in unit tests that exercise the ObjC selector names. PlatformColor Reviewed By: shergin Differential Revision: D21147404 Pulled By: TheSavior fbshipit-source-id: 0273ec855e426b3a7ba97a87645859e05bcd4126 * Update Differ test Summary: Update differ test so it passes again. Previously to D21111423 (I think) nodes were being incorrectly detected as updated even if they weren't different, so now there are fewer unnecessary Update mutations generated. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21148647 fbshipit-source-id: cab6e3ecd0a457e1ac3155b3468bcc56663dab0b * Enable Yoga logging in Fabric Debug Summary: This diff extends Fabric to support Yoga logging changeLog: [Internal] Internal changes in Fabric to enable yoga logging Reviewed By: JoshuaGross Differential Revision: D21150195 fbshipit-source-id: a2e8308a79a7b422bf9ecc3a65f822b305f02c5d * Easy diff to document in code how to enable logging of Shadow Tree instrospection Summary: Easy diff to document in code how to enable logging of Shadow Tree instrospection changeLog: [Internal] Internal change used on Fabric Reviewed By: JoshuaGross Differential Revision: D21150196 fbshipit-source-id: 8eb23ec3ea1d574b79b09333428ab52c851065dd * Flip text alignment in case layout direction is RTL Summary: Changelog: [Internal] Flip text alignment in case layout direction is RTL. Reviewed By: JoshuaGross, mdvacca Differential Revision: D21130371 fbshipit-source-id: cf56ca052c17a48e321803b0f99f8a4baaa0e67b * Daily `arc lint --take GOOGLEJAVAFORMAT` Reviewed By: zertosh Differential Revision: D21154707 fbshipit-source-id: 11956915c265f98e286638b91d66d51545e3a311 * Upgrade Flipper to 0.37.0 (#28545) Summary: Bump flipper to 0.37 for both iOS and Android ## Changelog [Android] [Changed] - Upgrade Flipper to 0.37.0 [iOS] [Changed] - Upgrade Flipper to 0.37.0 Pull Request resolved: https://github.com/facebook/react-native/pull/28545 Test Plan: RNTester build pass Reviewed By: rickhanlonii Differential Revision: D20930069 Pulled By: hramos fbshipit-source-id: a7cb719da3e51e6a42d27d5e64bc664398d0d3c5 * Upgrade babel-eslint in xplat/js Summary: `babel-eslint` is the parser you can supply to ESLint based off of Babel. `babel-eslint` 10.1.0 is the newest production version of `babel-eslint`. There are very few changes between 10.0.1 (the lowest previous version) and 10.1.0. There are only 3 non-version-bump commits: 2 bug fixes and enabling parsing of Flow enums. The only project that was on a lower version than 10.0.1 was `/xplat/js/RKJSModules/Libraries/Relay/oss/__github__` - test below Changelog: [Internal] Reviewed By: cpojer Differential Revision: D21055850 fbshipit-source-id: bae0d8af5c6d833a4dbb0ad775c8e5e78ead1051 * RN: Create `RootTag` Type Summary: Creates a `RootTag` type and refactors the `RootTagContext` module a bit. This creates space for eventually changing `RootTag` into an opaque type that is only created once by `AppContainer`, and only consumed by native abstractions. Changelog: [Internal] (Note: this ignores all push blocking failures!) Reviewed By: cpojer Differential Revision: D21127173 fbshipit-source-id: 60177a6e5e02d6308e87f76d12a271114f8f8fe0 * RN: Add `RootTag` Type to TurboModule Summary: Adds `RootTag` as a valid type for arguments and return types in TurboModules (on both Android and iOS). This will enable us to change `RootTag` into an opaque type. There are two compelling reasons to do this: - JavaScript will no longer be able to safely depend on `RootTag` being a number (which means we can change this in the future). - Call sites using `unstable_RootTagContext` will can get a `RootTag`, but call sites using the legacy `context.rootTag` will not. This means the opaque type will give us a strategy for migrating away from legacy context and eventually making `unstable_RootTagContext` the only way to access `RootTag`. Changelog: [Internal] (Note: this ignores all push blocking failures!) Reviewed By: RSNara Differential Revision: D21127170 fbshipit-source-id: baec9d7ad17b2f8c4527f1a84f604fc0d28b97eb * RN: Fix Codegen Schema Buck Dependency (#28719) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/28719 The Buck dependencies for the schema rule is missing the source files for the new codegen (and specifically, the parser). Changelog: [Internal] (Note: this ignores all push blocking failures!) Reviewed By: cpojer Differential Revision: D21162993 fbshipit-source-id: 4addb6f257134e245a5d86dd427ee2536ed6d658 * Flow 0.123.0 in xplat/js Summary: Changelog: [Internal] ## Sync of generated files Ran ``` js1 upgrade www-shared -p core_windowless ``` but had to manually revert ``` RKJSModules/Libraries/www-shared/core_windowless/logging/FBLoggerType.flow.js RKJSModules/Libraries/www-shared/core_windowless/logging/FBLogger.js ``` because they introduced more errors ## Flow version bump ``` ~/fbsource/fbcode/flow/facebook/deploy_xplat.sh 0.123.0 ``` Reviewed By: gkz Differential Revision: D21159821 fbshipit-source-id: e106fcb43e4fc525b9185f8fc8a246e6c3a6b14f * Remove outdated metro type definitions Summary: RN itself does not depend on Metro any longer, which is abstracted away into the CLI. I don't think we need those type definitions any longer as we have proper Metro definitions internally. I'm removing them because they keep showing up in biggrep when I look for things. Changelog: [Internal] Reviewed By: GijsWeterings Differential Revision: D21089924 fbshipit-source-id: 2845277af12dae0f0baefaf85adefffb6ef9f2a5 * Daily `arc lint --take CLANGFORMAT` Reviewed By: zertosh Differential Revision: D21175893 fbshipit-source-id: 101734c1b968ce241a15648efdcaeabbd789952d * remove tvOS from template (#28706) Summary: According to the [0.62 blog post](https://reactnative.dev/blog/2020/03/26/version-0.62), Apple TV support has moved to react-native-tvos. The template still contains info.plist for tvOS, so I've removed them for future releases. ## Changelog [General] [Removed] - Removed tvOS related files from the template Pull Request resolved: https://github.com/facebook/react-native/pull/28706 Test Plan: run `react-native init TestTemplate` and remove tvOS related files and verified that iOS and Android runs on emulator. Differential Revision: D21182211 Pulled By: hramos fbshipit-source-id: 41d2e19e5158d7ec103a37c01a93cf511fc1e4c9 * Fabric: `ConcreteShadowNode::initialStateData()` now accepts a `ShadowNodeFamilyFragment` instead of just a `SurfaceId` Summary: We need it to be able pass an `EventEmitter` object to constructed concrete State objects. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21169581 fbshipit-source-id: 3eef0310de7e2f061108aa85c1a39678a43fe85e * Fabric: Introducting `ShadowNodeFamilyFragment::Value` Summary: `ShadowNodeFamilyFragment::Value` is a value couter-part type for `ShadowNodeFamilyFragment`. We need that to be able safely copy data stored inside a `ShadowNodeFamilyFragment` object. Changelog: [Internal] Fabric-specific internal change. Reviewed By: kacieb Differential Revision: D21169580 fbshipit-source-id: 1a485e1b2ae47bc7da9476a60466934ac9d61366 * Overhaul RCTTurboModule creation and initialization Summary: ## Problems: In my investigation of T65656635, I realized that the TurboModule system has a number of problems: - In TurboModules, we use 1 lock to create n TurboModules. We should change this setup to n locks for n TurboModules. This way, two threads creating two different NativeModules don't compete for the same lock. Also, this is how it's done in Android (TurboModules & NativeModules), and iOS (NativeModules). - In TurboModules, we don't calculate "requires main queue setup" faithfully. In the legacy system, if a NativeModule has a custom `init` method or a custom `constantsToExport` method, it "requires main queue setup" with a warning. - In TurboModules, we don't create the NativeModule on the main queue, if "requires main queue setup" is true. Instead, the NativeModule is always created on the thread that requires it. - In TurboModules, we don't perform any concurrency control around `id` setup. We should. ## What this diff does In this diff, I fixed all the aforementioned issues by re-implementing `provideRCTTurboModule:`. **Algorithm Notes:** - **Gist:** When `n` threads race to create NativeModule `x`, only the first thread creates and sets up `x`. All others are told to wait. Once the creator thread finishes its job, it notifies all other waiting threads, which then wake up and return the newly created NativeModule. This algorithm was initially implemented in NativeModules for Android inside (ModuleHolder.java). I modified and implemented it for TurboModules for Android, and now this diff implements it for TurboModules for iOS. - The TurboModule cache is replace with a TurboModuleHolder map. A TurboModuleHolder manages the creation lifecycle of a TurboModule, and holds a condition variable and mutex for doing concurrency control around it. When the bridge invalidates, in TurboModuleManager, we set the `invalidating` flag to true, which prevents the insertion of new entries into the TurboModuleHolder map. - I added a `std::mutex` to serialize calls into the TurboModuleManagerDelegate, so we don't get races if the delegate isn't thread-safe. Changelog: [iOS][Fixed] - Re-implement RCTTurboModuleManager provideRCTTurboModule: Reviewed By: shergin Differential Revision: D21170099 fbshipit-source-id: 8792812c2237d3bfc80c9834c818e011de85b0ea * Fix folly::dynamic crash when attaching a debugger to Hermes Summary: folly_futures was compiled with and exported -DFOLLY_MOBILE=1, while folly_json did not. This flag disables fancy F14 data structures for folly::dynamic in favor of a simple std::unordered_map. This caused inlined/templated code from modules depending on folly_futures to disagree with the implementations in folly_json, leading to a crash. The only such libraries were libhermes-inspector and (transitively) libhermes-executor-debug, and these only use folly::dynamic for CDP serialization, which is why the problem was not more apparent. Changelog: [Internal] Fix crash when attaching a Hermes debugger Reviewed By: mhorowitz Differential Revision: D21193307 fbshipit-source-id: 2b795bb6f4f7f991e2adaacec62d62616117322b * Set black as default text color for on iOS (#28708) Summary: This is a follow-up pull request to https://github.com/facebook/react-native/issues/28280 (reviewed by shergin). This pull request tried to solve the problem of the default color in a TextInput in dark mode on iOS being white instead of black. I got suggested to solve the problem not on the level of RCTTextAttributes, but on the level of RCTUITextField. Setting `self.textColor = [UIColor black];` in the constructor did not work, because it gets overwritten by nil in `RCTBaseTextInputView.m`. There I implemented the logic that if NSForegroundColorAttributeName color is nil then the color is being set to black. I think the `defaultTextAttributes` property confuses here, because it ends up being the effective text attributes, e.g. if I unconditionally set the default text color to black, it cannot be changed in React Native anymore. So I put the nil check in. ## Changelog [iOS] [Fixed] - TextInput color has the same default (#000) on iOS whether in light or dark mode Pull Request resolved: https://github.com/facebook/react-native/pull/28708 Test Plan: I have manually tested the following: - The default text color in light mode is black - The default text color in dark mode is black - The color can be changed using the `style.color` attribute - Setting the opacity to 0.5 results in the desired behavior, the whole TextInput becoming half the opacity. – Setting the `style.color` to rgba(0, 0, 0, 0.5) works as intended, creating a half-opaque text color. Differential Revision: D21186579 Pulled By: shergin fbshipit-source-id: ea6405ac6a0243c96677335169b214a2bb9ccc29 * Daily `arc lint --take CLANGFORMAT` Reviewed By: zertosh Differential Revision: D21202121 fbshipit-source-id: 6acb53e6ca941e465b11aeac4215533c16067eed * RN: Rename `{ => Event}ObjectPropertyType` in Codegen Summary: Straightforward rename to clarify the purpose of this type. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21160790 fbshipit-source-id: eaf5e8c9f51e16134e153a6321857234be1aa338 * RN: Rename `{NativePrimitive => ReservedProp}TypeAnnotation` in Codegen Summary: Straightforward rename to clarify the purpose of this type. The current naming made more sense before the codegen also produced code for NativeModules. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21160793 fbshipit-source-id: 6787ef298e32ff1b4d506afd831af96764f5af6f * RN: Rename `{ => NativeModule}MethodTypeShape` in Codegen Summary: Straightforward rename to clarify the purpose of this type. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21160791 fbshipit-source-id: 422d09243edda0660815eb2f0ce51f7e56134983 * RN: Add `RootTag` Codegen Parser Test (and Cleanup) Summary: Adds a `RootTag` parser test for the new codegen for NativeModules/TurboModules. I'm doing this in a prerequisite commit in order to make the diff of the diff clearer when I implement proper support for `RootTag`. This also fixes some of the minor typos and mistakes that I noticed. I also wanted to land these benign snapshot changes independent of the upcoming behavior changes. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21160792 fbshipit-source-id: 5f29f34035da30d7afa2369dbc19e95954553e88 * RN: Add `RootTag` to New NativeModule Codegen Summary: Adds support for `RootTag` in the new codegen for NativeModules/TurboModules. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21160788 fbshipit-source-id: 952189f6e8bc8fde8b403d4c0e77b5d66b3f03e4 * RN: Add `RootTag` to New Commands Codegen Summary: Adds support for `RootTag` in the new codegen for Native Component Commands. Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21169371 fbshipit-source-id: 3b25433f3328e9c04cfe45bb176fc06d63559f14 * BackHandler: specify function return type for handler (#28192) Summary: Following the comment https://github.com/DefinitelyTyped/DefinitelyTyped/pull/42618#discussion_r384584159 Modify the flowtype of BackHandler function to have more specific return type. ## Changelog [General] [Changed] - Changed type of BackHandler to be more specific. Pull Request resolved: https://github.com/facebook/react-native/pull/28192 Test Plan: No flow error in RNTester Reviewed By: TheSavior Differential Revision: D20771113 Pulled By: hramos fbshipit-source-id: 5ca65e2a2b3f8726b8fb4606473d8fad5b0ce730 * Fabric: Simplifying Yoga and Fabric integration Summary: The integration with Yoga was pretty complex from day one. The first attempt to make it simpler was in D19963353 when we removed a bunch of layers of indirection. This is the second iteration that aimed to simplify the structure of methods and their responsibilities. The only conceptual change (that I am aware of) in this diff is that now we don't support (imaginary) case where a non-leaf YogaLayoutableShadowNode can have a non-YogaLayoutableShadowNode child. In the previous version, it was a no-op, now it's not supported and an assert will fire. Alongside with refactoring, this diff implements several helper functions that verify the invariants important for the Concurrent Layout in debug mode. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21198222 fbshipit-source-id: cc085904948056f861562af5bd2571de45a743b9 * Clean up comments about null state wrappers Summary: Updating state with a null wrapper is neither desirable, nor possible. The underlying task was closed, just cleaning up comments. Changelog: [Internal] comments only Reviewed By: mdvacca Differential Revision: D21186545 fbshipit-source-id: d14ddd59d42e8fd91c6e7fd50037311d4e8d0b60 * Modal: disable view flattening explicitly for the children of Modal, the content wrappers Summary: I noticed that in ModalHostShadowNode.java (not used in Fabric), there's an assumption that the Modal will have exactly one child on the native side; this child is explicitly specified in Modal.js. However, in Fabric, these views are flattened and so the Modal will actually have N children - whatever children the product code passes into the Modal. In *theory* this should be fine, but might be causing issues. Not sure. This is an experiment and shouldn't be landed until we verify that (1) this actually matters, (2) that it fixes an issue with Modal on iOS or Android. Changelog: [Internal] Change to make Fabric consistent with non-Fabric Modal Reviewed By: mdvacca Differential Revision: D21191822 fbshipit-source-id: 9d65f346387fd056649d4063d70220f637ba8828 * Support `contentOffset` property in Android's ScrollView and HorizontalScrollView Summary: For a very long time, iOS has supported the `contentOffset` property but Android has not: https://github.com/facebook/react-native/issues/6849 This property can be used, primarily, to autoscroll the ScrollView to a starting position when it is first rendered, to avoid "jumps" that occur by asynchronously scrolling to a start position. Changelog: [Android][Changed] ScrollView now supports `contentOffset` Reviewed By: mdvacca Differential Revision: D21198236 fbshipit-source-id: 2b0773569ba42120cb1fcf0f3847ca98af2285e7 * RN: Fix Text Layout Ignoring Parent Bounds Summary: Fixes text layout so that the parent bounds are correctly respected. This fixes two bugs: - **Parent width is not respected.** This was caused by the recent change to shrink-wrap text layout. - **Parent height is not respected.** This has always been a bug. After this change, Android will behave like iOS. Changelog: [Android] [Fixed] - Text layout no longer ignores parent bounds Reviewed By: mdvacca Differential Revision: D21199030 fbshipit-source-id: cc072bdcff64167db1f79b7bf965e57a7396cdf4 * Remove unnecessary cast to int in TextInlineView measure functions Summary: This diff removes unnecessary (int) casts in the calculation of layout for TextInlineViews changeLog: [Internal][Android] Internal optimization on the calculation of layout for TextInlineViews Reviewed By: JoshuaGross Differential Revision: D21211532 fbshipit-source-id: 920c1f88d042f3e1f6bfd0f560371f7482a62064 * Use RTL in RTLExample when Platform != android (#28742) Summary: This change upstreams a small change we did in react-native-windows to allow the RTLExample RNTester page to function correctly on Windows. The change is part of this Pr: https://github.com/microsoft/react-native-windows/pull/4683 Currently the direction property is gated behind a check for Platform == 'iOS', which means it only works on iOS. Windows supports direction = 'rtl' so I've chanced this check to Platform != 'android'. ## Changelog [Internal] [Changed] - Changed RTLExample RNTester page to use direction = 'rtl' when Platform is not Android. Pull Request resolved: https://github.com/facebook/react-native/pull/28742 Test Plan: Confirmed this change works correctly in RNTester on Windows. Have not confirmed iOS as I don't have Mac hardware. Differential Revision: D21235579 Pulled By: shergin fbshipit-source-id: 47ab93c2bcd0dbc8347c6746081ae3c64f88faa5 * Add Dark Mode support to the App template and NewAppScreen components (#28711) Summary: This PR adds support for the dark mode and dynamic theme changing to the default App template and to the related `NewAppScreen` components. Using `useColorScheme` hook forced me to refactor a bit main `App.js` file, but I think those changes are step in the right direction according to way in which React Native is used in larger apps, so new `Section` component has been extracted to reduce code redundancy/repetition inside `App`. Additional color `darker` has been added to the `Colors` statics from `NewAppScreen` because `dark` was too bright for the Dark Mode backgrounds. Also main `StoryBoard` on iOS has been updated to use theme based colors instead of static or hardcoded ones. There was also an unused, empty `Label` which I have removed. ~~I'm not so much experienced with Android. If someone could also update Android splash screen (if Android requires such change) it will be nice. I want to look at this later using simulator.~~ > I have updated the Android splash screen and tested this change on the Android emulator. If you have any comment or corrections feel free to post them out, I would like to put more work into this PR if it's needed. Dark Mode this days is a part of near every OS, so it could be considered as a standard feature. I hope those changes helps people which struggle with the basic theming implementation (+ there is now an example of hook and `children` prop usage in the template). ## Changelog [Internal] [Added] - Add dark mode support to the default app template Pull Request resolved: https://github.com/facebook/react-native/pull/28711 Test Plan: I have tested the App from the template on the iOS device and in Android emulator with RN `0.63.0-rc`. Screen recording on iOS (demonstarates both modes, both splash screens and transition): ![ezgif-6-e24ee8e839c9](https://user-images.githubusercontent.com/719641/80025923-a04b0300-84e1-11ea-824a-b4363db48892.gif) Screenshot of iOS app in Dark Mode: ![IMG_6542](https://user-images.githubusercontent.com/719641/79885748-c98f6480-83f7-11ea-8c73-1351a721d5d6.PNG) Screenshot of iOS app splash screen in Dark Mode: ![IMG_6544](https://user-images.githubusercontent.com/719641/79960431-add29f80-8485-11ea-985c-b39176024ffa.PNG) Screenshot of Android app in the emulator: ![Screenshot_1587566100](https://user-images.githubusercontent.com/719641/79995454-88f72000-84b7-11ea-810b-dfb70de03c2a.png) Differential Revision: D21236148 Pulled By: shergin fbshipit-source-id: 0c8a9534d3a3f8f8099af939243a889ac4df6cda * Allow use of std::tuple<> with decorators directly Summary: Previously, a derived class, WithTuple, was used. This ran into bugs in MSVC (see https://github.com/microsoft/STL/issues/121). Instead, use specialization to get the same result using std::tuple directly. This avoids the bug, and is a cleaner API. Changelog: [Internal] Reviewed By: dulinriley Differential Revision: D21233677 fbshipit-source-id: 1d75991847164e525b4ba70f65a90627e5f8cd56 * Fabric: Added assert in ShadowNode Summary: It's not allowed to return nullptr from the callback. The assert ensures it which is helpful during development. Probably, we should consider using `gsl::not_null<>` here. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D21149891 fbshipit-source-id: a5f77b35029f22b499491721036405682f812a38 * Fabric: Test for State Reconciliation mechanism Summary: It's not immediately obvious from the UI/UX when/if this mechanism breaks, so it's good to have a test. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21184718 fbshipit-source-id: 25432a1398cff3ce61f62cf433e3cb73d7a7a93f * ScrollView, HorizontalScrollView: support `null` contentOffset Summary: According to the Flow types, `contentOffset` is nullable. Support that. Changelog: [Internal] Fix to (1) support null contentOffset in ScrollView and HorizontalScrollView, added on Android after the last release. (2) Correctly add support for contentOffset in ScrollView (I missed that when adding it to HorizontalScrollView in the previous diff). Reviewed By: alsun2001 Differential Revision: D21243028 fbshipit-source-id: ebef9a9054a3e4dd88556739e836b7ece48fda12 * All `measure*` calls should use the latest committed version of a ShadowNode Summary: Because of StateReconciliation (?) it is possible, even likely, that eventually the ShadowNode that ReactJS holds onto will not be the latest ShadowNode, and will not contain the latest LayoutMetrics. This fixes the problem by always resolving the latest committed version of the ShadowNode before measuring it. Changelog: [Internal] Fabric measure bugfix Reviewed By: sammy-SC, mdvacca Differential Revision: D21248472 fbshipit-source-id: a4f034c36d89a91a804f3b4cdf35e7ae748a1b91 * chore: remove tvOS from the e2e CI tests (#28743) Summary: Refs https://github.com/facebook/react-native/issues/28706 This small PR removes `tvOS` platform and `HelloWorld-tvOS` references from the e2e CI tests script. Also a small typo in comment has been fixed. CC: dlowder-salesforce ## Changelog [Internal] [Removed] - remove tvOS from the e2e CI tests Pull Request resolved: https://github.com/facebook/react-native/pull/28743 Test Plan: Exec during `node ./scripts/run-ci-e2e-tests.js --ios` was successful. Differential Revision: D21252185 Pulled By: shergin fbshipit-source-id: 56981f2c5c3038412e9f37a81084de87e296d7d2 * Fix calculating View position within a Window in split-screen mode on Android (#28449) Summary: On Android, when using split-screen mode, the Window-relative position of a native View is not calculated properly when the app is running on the right (or bottom) half of the screen. The coordinates are currently calculated only based on View.getLocationOnScreen() with subtracting status bar height. Scenarios, where the window does not fill the entire screen (such as split-screen mode) are not supported. We need to use a more general solution to subtract the actual position of the window from position of the view within the screen. This PR fixes the issue by subtracting coordinates of the Window retrieved from View.getWindowVisibleDisplayFrame(), which covers all scenarios when Window can be in a different position than the screen (incl. status bar offset). ## Changelog [Android] [Fixed] - Calculating view position within the window in split-screen mode Pull Request resolved: https://github.com/facebook/react-native/pull/28449 Test Plan: 1. Run an app in split-screen mode on the right half of the screen 2. Call UIManagerModule.measureInWindow() from JS to fetch a position of a View within a Window 3. Observe the wrong coordinates returned 4. Try the same with the fix Reviewed By: mdvacca Differential Revision: D21246297 Pulled By: shergin fbshipit-source-id: 1f54b1a5d6610be17bf05521200304db2ba263ab * Fix image instrumentation internal lifecycle Reviewed By: fkgozali Differential Revision: D20980822 fbshipit-source-id: d0a4a031046509425fbf6662471246ed2ab48a4c * Calling Paper TextInput setTextAndSelection view command now dirties layout Summary: Changelog: [Internal] Previously `setTextAndSelection` was not dirtying layout. This would cause an issue where `setTextAndSelection` causes layout change. For example calling setTextAndSelection with empty string on a multiline auto expanding text input. I changed one example in TextInputSharedExamples.js, "Live Re-Write (no spaces allowed) and clear" example is now multiline. This allows to test whether `setTextAndSelection` dirties layout. Enter multiline string to to the example text input and press clear. Observe that the text input shrinks to single line height. Reviewed By: shergin Differential Revision: D21182990 fbshipit-source-id: de8501ea0b97012cf4cdf8d5f658649139f92da6 * Blur image in Image component if blurRadius prop is provided Summary: Apply `blurRadius` prop once image is loaded. Changelog: [Internal][iOS] Reviewed By: mdvacca Differential Revision: D21227536 fbshipit-source-id: 241aa45f253a06d61e861f6719f14fabf3467b56 * Fabric: Marking TextInput as a leaf Yoga node Summary: TextInput must have `LeafYogaNode` trait to be able contain non-yoga nodes. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D21252322 fbshipit-source-id: 820f3ae4811cb475550419af501739c57c7164e1 * Move RuntimeExecutor to its own BUCK module (#28730) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/28730 Moving RuntimeExecutor out of react/utils and into its own subdir of ReactCommon. I'm doing this because I'm going to be pulling this into CatalystInstance on Android, and I don't want to pull in all the files we don't need there; also, this should hopefully make the OSS NDK stuff easier (this uses the react/utils prefix to export, and I'm not sure if you can include a '/' in a gradle module name?) Changelog: [Internal] Reviewed By: shergin, mdvacca Differential Revision: D21098528 fbshipit-source-id: 9fbd72901ece522b1caec3ec34fafb8f9b327275 * Send key when onKeyPress event is fired from TextInput Summary: Changelog: [Internal] In `onKeyPress` event, we were not returning `key` property. This diff adds `key` property to `onKeyPress` event and removes other, redundant properties from `onKeyPress` event. The implementation has been translated from Paper. Reviewed By: shergin Differential Revision: D21250411 fbshipit-source-id: f1e31381667acb9dec02d0b33883df8f8f5b2a4b * Do not send events for changes coming from JavaScript Summary: Changelog: [Internal] When there is a change coming from javascript, avoid triggering `onChange ` and `onSelectionChange` events since JavaScript already has these changes. This is only necessary for multiline text. For changes coming through view commands, do not increment `_mostRecentEventCount`. Reviewed By: shergin Differential Revision: D21255228 fbshipit-source-id: e972dab0eb3dd21f611ee5c71d755bab593ae9cc * Fabric: Increasing threshold for MountingTelemetryTest Summary: We neede that to make the test less flaky. Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D21261487 fbshipit-source-id: afec45e03be10ba071a5ab808ce13f95b5f475e3 * iOS: Fix refreshControl layouting (#28236) Summary: In `react-native-navigation` we allow the usage of native iOS navigationBar **largeTitle** which cause the title to "jump" when pulling to refresh. We found that the layout calculations of the refreshControl element mess up the system behaviour. ## Changelog [iOS] [Fixed] - Fix refreshControl messes up navigationBar largeTitles Pull Request resolved: https://github.com/facebook/react-native/pull/28236 Test Plan: ### Before the fix: ![before](https://user-images.githubusercontent.com/10794586/75991307-f7c7ec00-5efe-11ea-8cd9-ab8c3fbe1dc1.gif) ### And after: ![after](https://user-images.githubusercontent.com/10794586/75990618-d9152580-5efd-11ea-8c72-5deb6d83a840.gif) ### How it looks like with react-native init app after the fix: ![ezgif com-video-to-gif (4)](https://user-images.githubusercontent.com/10794586/77253369-54970680-6c62-11ea-9ad6-3265e23044e6.gif) Differential Revision: D20587945 Pulled By: shergin fbshipit-source-id: 94f560b17e367f4ef5e789f40c052396949b51a3 * Fix rounding error using double instead of float Summary: Changelog: [Internal] [Yoga] Use double instead of float during rounding process to prevent loss of precision. Reviewed By: mdvacca Differential Revision: D21227565 fbshipit-source-id: 380b57535a356624cda8dc2017871a4ef3c882d1 * Fix broken touches on all Fabric surfaces Reviewed By: shergin Differential Revision: D21261996 fbshipit-source-id: f42c19295ac127eca653631faad0ced4900f4758 * Move ART Android files to FB internal Summary: ## Changelog: [General] [Changed] - Moves ART android files from RN to internal react shell. Reviewed By: cpojer Differential Revision: D21261077 fbshipit-source-id: 1d3dc404313192540d64991911e3599e3e86351b * Check en0..en8 when generating ip.txt for iOS debug builds (#28764) Summary: When generating ip.txt in an iOS debug build, search en0 through en8 for an IP address rather than only checking en0 and en1. For example, on my Mac, the IP address I needed to use was on en5 and the IP address actually detected was a private network of one of my Parallels virtual machines (interface vnic0). ## Changelog [iOS] [Fixed] - Search en0 through en8 for the Metro Bundler's IP address when generating iOS debug builds Pull Request resolved: https://github.com/facebook/react-native/pull/28764 Test Plan: Should make no difference to users for whom react-native-xcode.sh already worked. On a Mac with multiple virtual machines installed, should prevent ip.txt getting the private IP address of a virtual machine. Differential Revision: D21280671 Pulled By: shergin fbshipit-source-id: e6fe9c8344146626df96129968981462463201f7 * Part 1: Make CatalystInstanceImpl.getNativeModule Nullable Summary: ## Description When the TurboModule and the NativeModule systems are alive at the same time, after RN cleanup, if a TurboModule is required, we return `null` from TurboModuleManager. This causes `CatalystInstanceImpl.getNativeModule` to do a lookup on NativeModule registry, which throws an `AssertionError`, because the TurboModule isn't found. Instead of throwing an `AssertionError` from `CatalystInstanceImpl.getNativeModule`, this diff instead has that method return `null` in this particular case. ## Rationale This should eliminate the crashes we're seeing in T46487253. ## Future action In the future, we should guard `CatalystInstanceImpl.getNativeModule` with an `if (mDestroyed) return null;` statement. This'll ensure that if NativeModules are required after React Native has started cleanup, they'll be returned as `null`. Right now, we either return the destroyed NativeModule object, or create/initialize the NativeMoulde and return it, which is wrong. Changelog: [Android][Changed] - Make CatalystInstance.getNativeModule nullable Reviewed By: JoshuaGross Differential Revision: D21272029 fbshipit-source-id: 099ad9ab9fa2146299df4cf7f86ae7a8e526bb15 * Part 2: Make CatalystInstanceImpl.getNativeModule Nullable Summary: This is the codemod portion of the parent diff. I modified all call-sites to `ReactContext.getNativeModule` to do a null check on the returned NativeModule. Changelog: [Android][Fixed] - Check if NativeModules returned from CatalystInstanceImpl.getNativeModule are null before using them. Reviewed By: JoshuaGross Differential Revision: D21272028 fbshipit-source-id: 6bd16c6bf30605f2dfdf4c481352063712965342 * Revert D20587945: iOS: Fix refreshControl layouting Differential Revision: D20587945 Original commit changeset: 94f560b17e36 fbshipit-source-id: e8ec95b2ea8632ef09e132351a1458cf97671206 * Back out "Control concurrent calls into TMMDelegate from TMM" Summary: Original commit changeset: d22c4abfe87f This synchronization is redundant. See D21025965. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D21283284 fbshipit-source-id: dae737fe08bbc8f60913baa6c6a58228611257ef * Resolve RNTester Xcode warnings (#28676) Summary: Resolve RNTester Xcode warnings. ## Changelog [Internal] [iOS] - Resolve RNTester Xcode warnings Pull Request resolved: https://github.com/facebook/react-native/pull/28676 Test Plan: Building RNTester no longer shows project setting warnings Differential Revision: D21109702 Pulled By: hramos fbshipit-source-id: f7552d3a9857ee7415cd96622a0a79797a168698 * Update react.gradle (#28776) Summary: Running `./gradlew assembleRelease` fails as the path to the CLI contains a new line at the end. We don't run this command in `debug` mode, hence it passed the testing. My bad. Fixed, checked in both `debug` with `bundleInDebug: true` and `release`. Fixes https://github.com/facebook/react-native/issues/28700 ## Changelog [INTERNAL] [ANDROID] - Fix `React.gradle` to build Android apps in production Pull Request resolved: https://github.com/facebook/react-native/pull/28776 Test Plan: Running `./gradlew assembleRelease` works Reviewed By: hramos Differential Revision: D21287789 Pulled By: TheSavior fbshipit-source-id: dc3ec8eef7a919b072b562d2bd455e2f704bc083 * Fix cleanup bug Summary: This is the iOS analogue to D21290582. Changelog: [iOS][Fixed] - TurboModule cleanup Reviewed By: fkgozali Differential Revision: D21290852 fbshipit-source-id: c0975a1f320ad4ad4ef16eec82eca38389c71a0a * Fix cleanup bug Summary: When I initially made TurboModuleManager.getModule thread-safe, I unintentionally broken TurboModule cleanup. This diff fixes that mistake. ## Mistake ``` Override public void onCatalystInstanceDestroy() { synchronized (mTurboModuleCleanupLock) { mTurboModuleCleanupStarted = true; } final Set turboModuleNames = new HashSet<>(mTurboModuleHolders.keySet()); for (final String moduleName : turboModuleNames) { // Retrieve the TurboModule, possibly waiting for it to finish instantiating. final TurboModule turboModule = getModule(moduleName); // ERROR! if (turboModule != null) { // TODO(T48014458): Rename this to invalidate() ((NativeModule) turboModule).onCatalystInstanceDestroy(); } } ``` Before calling `getModule(moduleName)`, I set `mTurboModuleCleanupStarted = true`. This assignment makes all calls to `getModule` return `null`, which means that none of the TurboModules were having their `onCatalystInstanceDestroy()` method invoked. Changelog: [Android][Fixed] - TurboModule cleanup Reviewed By: fkgozali Differential Revision: D21290582 fbshipit-source-id: 3645b9a4f8c6f41498ebd9d51f9b5775edf2dbd7 * Create JRuntimeExecutor (#28779) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/28779 Creating a JNI wrapper class for RuntimeExecutor so we can pass it to Fabric and TurboModules in Java. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D21049385 fbshipit-source-id: f833004225d9837acf6ffafd3988f89748cf12aa * refine invariant error message at scrollToIndex (#28464) Summary: I refined the error message of scrollToIndex. When I used scrollToIndex with `index:0` and data that length is 0, I met the odd error message `Invariant Violation scrollToIndex out of range: requested index 0 but maximum is -1`. Next, I thought that scrollToIndex with `index:-1` meant scrollToTop without checking data length. I met `Invariant Violation: scrollToIndex out of range: requested index -1 but maximum is -1` Finally, I wondered what will happen to use scrollToIndex with `index:-1` and data that length is `5`. The result is `Invariant Violation: scrollToIndex out of range: requested index -1 but maximum is 5` The above error messages will confuse us. I clarified the boudaries and separated the error messages ## Changelog [General] [Fixed] - Clarified the boundaries in error message of scrollToIndex Pull Request resolved: https://github.com/facebook/react-native/pull/28464 Test Plan: I added 3 test cases to cover the new error messages for VirtualizedList. Run `yarn test` and confirm it passes. Reviewed By: cpojer Differential Revision: D21140133 Pulled By: TheSavior fbshipit-source-id: 9a7a704f7ec599d833d2ed3ca2be059d950539b5 * Reject promise when if an error occurs while processing prefetching result Summary: This diff rejects the promise when if an error occurs while processing prefetching result, it applies the same concept as other methods in this class (e.g. see getSizeWithHeaders) changelog: [internal][Android] Internal change in RN Image prefetching Reviewed By: JoshuaGross Differential Revision: D21295612 fbshipit-source-id: c3675e5f2d9c8e38094a538b388ff63a6ea18360 * Add hostname to loading banner on iOS Summary: This diff adds a hostname to the loading banner on iOS so it's clear which server you're loading from. Changelog: [Added] [iOS] Added hostname to loading banner. Reviewed By: PeteTheHeat Differential Revision: D21280252 fbshipit-source-id: d7733c056f5fb63e32b247a4fa1476ab42c7da17 * Update loading banner text and colors Summary: This diff updates the loading banner text and color on iOS for better UX. Flow before: - Loading from localhost:8081... - Loading 20% (1000/5000)... - Downloading JavaScript Bundle 20% (10/50) - Downloading JavaScript Bundle... After: - Loading from Metro... - Bundling 20%... - Downloading 20%... - Downloading... Changelog: [Added] [iOS] Updated loading banner messages and color Reviewed By: PeteTheHeat Differential Revision: D21279939 fbshipit-source-id: fd7d90f85e25ce175a87087dfccf2180d49e3e98 * Do not update loading banner message while hiding Summary: This diff fixes an issue where the loading banner message could update while the banner hide animation is going, catching your eye for no reason. Changelog: [Fixed] [iOS] Do not update loading banner message while hiding Reviewed By: PeteTheHeat Differential Revision: D21280786 fbshipit-source-id: a10b33cd72f263d08eea6d8e94963514affbe24d * Delay loading banner inital message by 200ms to prevent flashing Summary: This diff fixes an issue where the initial "Loading from Metro..." message is flashed for a few milliseconds before the download progress kicks in. It's just jarring enough to be noticed and is ~600ms too fast to be read. This diff adds a delay so that if the loading progress starts within 200ms we go straight to the progress. Changelog: [Fixed] [iOS] Delay loading banner message to prevent flashing messages Reviewed By: PeteTheHeat Differential Revision: D21281870 fbshipit-source-id: d28c1eae01c2ac9d79f356f1870f17dbb22a9d84 * Speed up loading banner animations Summary: This diff reduces the minimum loading banner time and animation time to make the locating banner faster. Changelog: [General] [iOS] Speed up loading banner animations Reviewed By: PeteTheHeat Differential Revision: D21290517 fbshipit-source-id: 111dff41df53b0246548e1da1db80c2188498a9c * Guard all debug logs behind an MC Reviewed By: PeteTheHeat Differential Revision: D21292280 fbshipit-source-id: 1701a945f126f35a53417b57e3162372d39e75f1 * Don't allow download percentage to exceed expectations Summary: This diff updates the loading banner to protect against showing percentages over 100% Changelog: [Fixed] [iOS] Cap loading bar percentage at 100% Reviewed By: shergin Differential Revision: D21295809 fbshipit-source-id: 343f53acafa126800367444562730eff4ae67af4 * cleanup unused TODO Summary: Task is closed, I'm removing the TODO. I verified that the soft error is not being triggered changelog:[Internal][Android] Internal cleanup of fabric android Reviewed By: sammy-SC Differential Revision: D21303999 fbshipit-source-id: 11d4a14c71d27ffc70a6d3b955a21085dd11859b * Move DevSettingsActivity from main to debug (#28770) Summary: As described in DevSettingsActivity, it should be added to the apps debug/ instead of main/ manifest. ## Changelog Android Changed - Move DevSettingsActivity from `main` to `debug` manifest Pull Request resolved: https://github.com/facebook/react-native/pull/28770 Test Plan: Tested locally by building example app Differential Revision: D21281922 Pulled By: shergin fbshipit-source-id: ec4dc7c0ac54367aa38cca5b4146ef71cf18b73b * Delete .clang-tidy for jscallinvoker Summary: `JSCallInvoker` doesn't exist anymore, because it was renamed to `CallInvoker`. So, this `.clang-tidy` dotfile isn't necessary. Changelog: [Internal] Reviewed By: PeteTheHeat Differential Revision: D21318061 fbshipit-source-id: 8098eef670cae35bf3c027c91f18f45eb7bcd33a * Enable Animated in Venice Summary: This diff extends venice app to render an Animation example test changelog: [Internal][Android] Internal change to enable Animated in RN Bridgless mode Reviewed By: PeteTheHeat Differential Revision: D21317630 fbshipit-source-id: 9726fea9baba86191e63df909639d1d47ef5f359 * Fabric: Changes in State reconciliation Summary: I spent the last several days thinking about state reconciliation issues, some crashes (T65586949) that suspiciously happen somewhere inside, and a bunch of issues that might be connected to that (possibly, some of T65516263 sub-task). I cannot see some obvious problems in the current state reconciliation algorithm that might cause the crash (because of some use-after-free or other pure C++ issues), but I suspect some of the problems we experience might be caused by some details of how we reconcile states. In the current approach, we rank all states based on the "hierarchical" history of their creation (state version is being calculated based on the version of the base tree). That's usually fine but in some cases when trees are being constructed concurrently, a logical version of a based tree does not correspond to the local version of a committed tree. In other words, the linear history of commits does not always correspond to the "hierarchical" history of trees generation that was done by different parties (e.g. React vs native state update pipeline). In this diff, I tried to change the approach to change the algorithm to follow this logic: If some state is `obsolete` (already been committed and then replaced with newer one), we replace that with the most recent one. This change does not introduce the `obsolete` flag; is already used by State infra to avoid cloning nodes with an outdated state. Interestingly, it fixes the issue with an empty BottomSheet on Android (T66177144). See the attached video. The hope is that it's also will This change theoretically might affect all things that use State, so it hard to predict what can break and how. So, if we don't see obvious problems here, I would set up a GK/QE and run the experiment in prod. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross Differential Revision: D21295137 fbshipit-source-id: e5613218d3e11a56623cab9bbf2540495b2b24e8 * Fabric: Gating for new state reconciliation Summary: The change is gated by two QEs (iOS and Android). Changelog: [Internal] Fabric-specific internal change. Reviewed By: mdvacca Differential Revision: D21317797 fbshipit-source-id: 34bfd9546600d9cb3467bddfc61363a16683f81f * Replace duplicate code in AndroidInfoModule with call to AndroidInfoHelpers (#28756) Summary: The AndroidInfoModule class defines a `getServerHost()` method that duplicates the logic in `AndroidInfoHelpers.getServerHost(context)`. This commit makes AndroidInfoModule call into AndroidInfoHelpers so that potential future changes to `AndroidInfoHelpers.getServerHost` don't need to be duplicated in `AndroidInfoModule.getServerHost`. ## Changelog [Android] [Changed] - Internal change to make `PlatformConstants` use the same method to determine `ServerHost` as other code paths Pull Request resolved: https://github.com/facebook/react-native/pull/28756 Test Plan: Tested by running the RNTester app and editing the root component to print out `NativeModules.PlatformConstants.getConstants()` and verified one of the properties was: `"ServerHost": "10.0.2.2:8081"`. Differential Revision: D21252158 Pulled By: shergin fbshipit-source-id: b460197e5f1d972a5b91991c32a929294e358d9f * Daily `arc lint --take GOOGLEJAVAFORMAT` Reviewed By: zertosh Differential Revision: D21325542 fbshipit-source-id: d4c70da59c67c1f7dfcd36f06bbfe0eec5d4e824 * Set contentView's frame in setter Summary: In D20836890 we no longer set `_contentView.frame` inside `layoutSubviews`. This doesn't work well with component views that set their `contentView` after `updateLayoutMetrics` is called. For Example legacy interop which sets its contentView in the `finalizeUpdates` method. Other component views that set their contentView during initialisation are fine. Changelog: [Internal] Reviewed By: shergin Differential Revision: D21302108 fbshipit-source-id: 5adcf489e4e650ac04b84c836a8f8d6f55a77267 * Smaller loading bar based on feedback Summary: This diff removes the hostname from the loading bar and shrinks it down so it's inside the margins of the safe area view, never blocking app content inside the safe area. Changelog: [General] [iOS] Shrink loading bar down to not cover safe area. Reviewed By: shergin Differential Revision: D21339480 fbshipit-source-id: e8416af63b7e06bcc21c7b6277d5d01d61eb3f73 * Reduce exposure of UIManagerModule in the NativeAnimatedNodesManager class Summary: This diff reduces exposure of UIManagerModule in the NativeAnimatedNodesManager class, this is necessary to enable NativeDriverAnimations in Venice changelog: [Internal][Android] Internal change to enable native driver animations in RN bridgless mode Reviewed By: ejanzer Differential Revision: D21317629 fbshipit-source-id: 81cd4ade296de4757acefe566e1466154d6b4e4b * Cleanup scheduleMountItem method Summary: scheduleMountItem supports multi threading now, cleanning up TODO changelog: [Internal][Android] Internal cleanup Reviewed By: JoshuaGross Differential Revision: D21318108 fbshipit-source-id: dffac4d541bc2d0f781ddcb8f17f5d1b7e44b79b * Cleanup ReactRootView Summary: This diff removes the variable 'useSurface' which wasn't beeing used in ReactRootView anymore changelog: [Internal][Android] Internal cleanup of ReactRootView Reviewed By: JoshuaGross Differential Revision: D21318109 fbshipit-source-id: f850b27811608d16b22b6a3964455b172705c4c7 * Set layout metrics during initial render of Fabric Summary: This diff refactors the initial render of Fabric in order to set the layout metrics as we start the surface. This prevents to create an additional fabric commit during initial render. Also this migth help fixing T63495589 (I wasn't able to repro T63495589 again when using this diff) changelog: [Internal][Android] Internal change to reduce the amount of commits during initial render of Fabric Reviewed By: JoshuaGross Differential Revision: D21330072 fbshipit-source-id: 758c49b52ea4c12d5623b7c7d68c7318f4a6cd83 * Use InteropLayer for ReactART Summary: Changelog: [Internal] Use InteropLayer to bridge ReactART into Fabric. Reviewed By: shergin Differential Revision: D21302151 fbshipit-source-id: 46deb381389c6fa87ecad296f616fbaccb29fe30 * fix duration calculation for RCTUIImageViewAnimated Summary: ## Changelog: [iOS] [Fixed] - Fix duration calculation for RCTUIImageViewAnimated Reviewed By: p-sun, shergin Differential Revision: D21321089 fbshipit-source-id: 7464231bbc3b90e70d3ba95288fd90707d3d24af * Update cocoapods, fix RNTester Summary: Updating pods and fixing an issue in the RN podfile. Changelog: [iOS][Fixed] Update podfile for RNTester Reviewed By: PeteTheHeat Differential Revision: D21336180 fbshipit-source-id: 4d51f53466ec2d432cf7a5775cb4d69d47423077 * Bump @react-native-community/eslint-config in new app template Summary: Changelog: [Changed][General] Update react-native-community/eslint-config to 1.1.0, adding the new color rule Reviewed By: rickhanlonii Differential Revision: D21342153 fbshipit-source-id: ac1367353d4d3e69b6df29dc16f9fcb60cde3519 * Fabric: Fixing `executeSynchronouslyOnSameThread_CAN_DEADLOCK` Summary: In D20551411 we (I) replaced `std::mutex` with `std::recursive_mutex` in `executeSynchronouslyOnSameThread_CAN_DEADLOCK` in order to support synchronous `RuntimeExecutor`. It turned out that the idea was cool but totally incorrect. Quite obviously, double locking recursive mutex on the same thread does nothing, so the whole setup does not work at all. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D21328072 fbshipit-source-id: 7f1f81de61c36adb167fe624ada3bd71913bdf7c * Revert D21336180: Update cocoapods, fix RNTester Differential Revision: D21336180 Original commit changeset: 4d51f53466ec fbshipit-source-id: 5519bc0457f14060e793d2da454489b77fce923f * Refactor ReactCallerContextFactory to recive surfaceID as a parameter Summary: This diff refactors the ReactCallerContextFactory class to recive surfaceID as a parameter instead of ThemedReactContext This is necessary for the next diff of the stack changelog: [Internal][Android] Reviewed By: fkgozali Differential Revision: D21362265 fbshipit-source-id: d0079788049fe86d2873eb6aa4bf1115b33457af * Inject Fresco.ImagePipeline into ImageLoaderModule Summary: This diff injects Fresco.ImagePipeline into ImageLoaderModule in order to ensure prefetching uses the same ImagePipeline than ReactImageView changelog: [internal][Android] Reviewed By: fkgozali Differential Revision: D21362267 fbshipit-source-id: d6f55cffb6be6a012c2afb4ad5db2072bc7100ec * Extend logging of image prefetching to include react_native contextChain Summary: This diff extends the logging of image prefetching to include react_native ID in the ContextChain of the Fresco logger. This is necesary to properly assign pre-fetching of RN Android images to the react_native ID changelog: [Internal][Android] Reviewed By: fkgozali Differential Revision: D21362266 fbshipit-source-id: ff64f0ebd12f61b713996558eb2d962f96ad8d94 * Fix Fb4aReactPackageTest.testGetNativeModulesByName test Summary: This diff refactors the ImageLoaderModule class in order to prevent early execution of Fresco.getImagePipeline method when prefetching MC is disabled (see stack D21362266) changelog: [Internal][Android] Reviewed By: shergin Differential Revision: D21368516 fbshipit-source-id: 53f99cd3c3f4848364182cb954a8d34821cb6d9e * Remove `docs` from `jscodeshift` Summary: I removed 1 MiB from `jscodeshift` as it was shipping with docs: https://github.com/facebook/jscodeshift/commit/5885662920ed7a3077da22beed4a8f76743dd19c Changelog: [Internal] Reviewed By: yungsters Differential Revision: D21368889 fbshipit-source-id: 452fd4cedcc749d972adbb69df5c95117dd55b15 * iOS: when the bridge has been invalidated, NativeModule lookup should just return nil Summary: There's a corner case where: * The bridge gets invalidated, and native modules are cleaning up themselves (but not done yet) * Something asks for a NativeModule instance - ideally it should just get nil at this point * If TM Manager is invalidating, we get nil correctly, but we continue thru the old NativeModule lookup logic * The latter will fail anyway, and would throw a redbox (RCTLogError). So, if the bridge is invalidated, if TM Manager returns nil, we should just return nil for old NativeModule lookup. The module of interest is RCTImageLoader, which was requested by RCTImageView on deallocation. The problem is RCTImageView got dealloc'ed **after** the bridge has been invalidated, so the lookup would always fail... Bonus: RCTImageView should just keep a weak ref to the RCTImageLoader, so that: * if the imageLoader is still alive on image dealloc, it can still access them (last minute "meaningless" cleanup) * if the imageLoader is gone, then the image deallocation doesn't do anything Changelog: [iOS] [Fixed] - Fix module lookup race condition on bridge invalidation. Reviewed By: p-sun, sammy-SC Differential Revision: D21371845 fbshipit-source-id: 862dc07de18ddbfb90e87e24b8dbd001147ddce4 * Fix invalid type annotations Summary: Our parsers accept these but they are invalid. This fixes them. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D21373812 fbshipit-source-id: 6084757b9f842644fe629ae5e6d85baec611588d * Fixes TextInput shaking when typing Chinese (#28805) Summary: Fixes https://github.com/facebook/react-native/issues/28488. ## Changelog [iOS] [Fixed] - Fixes TextInput shaking when typing Chinese Pull Request resolved: https://github.com/facebook/react-native/pull/28805 Test Plan: Demo see https://github.com/facebook/react-native/issues/28488. Differential Revision: D21376803 Pulled By: shergin fbshipit-source-id: b1fe6cc5f67d42ef98a6c12b8ab9990feac0e2a7 * VirtualizedList: Migrate to React.Context Summary: Migrates `VirtualizedList` off legacy context by creating `VirtualizedListContext`. Changelog: [General][Changed] - Migrated `virtualizedList` legacy context to `React.Context`. Reviewed By: TheSavior Differential Revision: D21370882 fbshipit-source-id: 2fa99ee0bc0e6b747a2d3fe7c66ee402c6b9c5af * VirtualizedList: Remove `PropTypes` Dependency Summary: Removes `PropTypes` as a dependency of `VirtualizedList` by no longer validating the return value of `getItemLayout`. Changelog: [Internal] Reviewed By: TheSavior, cpojer Differential Revision: D21370890 fbshipit-source-id: 966db3557b714987aa91179c7654a5ebf27818ad * Remove `@babel/preset-env` Summary: `babel/preset-env` pulls in a number of unused deps, like `caniuse-lite` (3 MiB) that knows about which browsers support certain features. We do not ship to browsers and always know which version of node we are using, so we don't need to pull this in. I changed `jscodeshift` to optionally depend on `babel/preset-env` instead of always pulling it in. This reduces node_modules by 7 MiB. Changelog: [Internal] Reviewed By: yungsters Differential Revision: D21374475 fbshipit-source-id: 6f55e96e990ec0ca12f17bb3657bfa5429796b93 * Add prepareForReuse to RCTSafeAreaViewComponentView Summary: Changelog: [internal] As part of recycle, we should delete state. This is a common pattern used in other components as well. Reviewed By: shergin Differential Revision: D21348782 fbshipit-source-id: a5dee2f4ccee9b19498db31dab1983d8879dca71 * chore: remove Kotlin version from the default template (#28626) Summary: The default application requires Kotlin version that is not supported by the Gradle plugin (should be at least `1.3.10`). However, instead of upgrading, we should remove it entirely. Here's why. This commit https://github.com/facebook/react-native/commit/29d3dfbd196176af98c9727c82ff2668e697d78e introduced Detox for RNTester Android application. Since the commit doesn't mention Detox for the default application and there are no Detox tests present by default in the default application, I believe that this addition was performed by a mistake. The best way is to remove Kotlin from the default template. This step is described in the Detox documentation and all users that are integrating Detox will be asked to perform it anyway. No need to do it for them. ## Changelog [ANDROID] [INTERNAL] - remove Kotlin from the default template Pull Request resolved: https://github.com/facebook/react-native/pull/28626 Test Plan: Building a brand new project with `master` should work Differential Revision: D21388961 Pulled By: shergin fbshipit-source-id: 92666aa67f92b29f4e7f9c036b332bd058cdd49e * Fix Optimized Differ (was generating extraneous Create mutations) Summary: When we call `.erase` on the TinyMap, it sets the key of the element to 0. When we call `.begin()` later, TinyMap will sometimes, but not always, clean up the underlying Vector. This means that *most* of the time, underlying erased elements will be removed from the Vector; but sometimes erased elements will still be there when iterating over it. This was causing us to generate extra "Create" mutations. To fix this, for now we just check for zeroed-out elements when iterating over the vector. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21389371 fbshipit-source-id: 1e641050987d40a3f3e31499dcb373cfb28ae6f8 * Add warning when scrollRef does not have a scrollTo method Summary: Add a `console.warn()` call when calling `_scrollRef.scrollTo`, because `scrollTo` is not guaranteed to exist on `_scrollRef`. Context: `VirtualizedList` holds `_scrollRef`, which is usually a reference to a `ScrollView` component. However, there are several cases where it holds a `View` or other type of component instead. A custom component can be passed in to `renderScrollComponent`, and then `_scrollRef` will point to that custom component. Additionally, if two VirtualizedLists are nested with the same orientation, `_defaultRenderScrollComponent` will return a View instead of a ScrollView. Due to these possibilities, `_scrollRef` is not guaranteed to have a `scrollTo` method. Changelog: [General] [Added] - Add warning when scrollRef does not have a scrollTo method Reviewed By: JoshuaGross, TheSavior Differential Revision: D21386842 fbshipit-source-id: 01e167e0ae0edea8f29853e8b242ce88a5103b49 * Don't use #import in C++ Code (#28825) Summary: While #import is common in Objective C, it's a vendor specific extension in C++, only supported by GCC/Clang, and only when -pedantic is off. Its use causes build breaks with MSVC. Replace it with the standard #include. ## Changelog [Internal] [Fixed] - Don't use #import in C++ Code Pull Request resolved: https://github.com/facebook/react-native/pull/28825 Test Plan: We've ben running this change within react-native-windows for some time. Differential Revision: D21391233 Pulled By: shergin fbshipit-source-id: c0f94f314c46d6ac24067bbdcd5aaaeec9da283f * Fix unit test compilation on Android Summary: Before, compilation fails with P130281113. After fixing BUCK target, fails with P130281201. After all changes, the tests succeed. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21390996 fbshipit-source-id: c85aa43b3ef7fc9642d226ae706c937b2a5a408d * Support calling LayoutAnimation APIs in Fabric from JS Summary: Call Fabric's LayoutAnimation APIs from JS. Changelog: [Internal] A step towards supporting LayoutAnimations on Fabric Reviewed By: shergin, mdvacca Differential Revision: D21297975 fbshipit-source-id: 6d530b01d8152e7c803a7c0299b918a32fb39dc0 * Differ: fix TinyMap to prevent possible crashes in `find()` and `begin()`, and prevent erased elements from being iterated over Summary: The core issue solved in D21389371 was that erased elements of a TinyMap were being iterated over, because TinyMap has somewhat-complicated logic around cleaning out the underlying vector. In some very marginal cases, vectors were not being cleaned and an iterator pointing at erased elements was being returned. The diff prevents some possible crashes in `begin()` and `find()` while making it much less likely to iterate over erased elements. We also add a unit test to catch the case fixed in D21389371, in particular. We also are keeping the code added in D21389371 (for now) since it's a cheap check, and will be a safeguard until we have rigorous testing around TinyMap. To be clear that logic should noop currently, but will prevent crashes in case guarantees around TinyMap change in the future. Currently there is only one line of code that actually uses the TinyMap iterator, so this should be safe. Reviewed By: shergin Differential Revision: D21392762 fbshipit-source-id: 36dc998958c230fad01af93338974f8889cbcf55 * Allow passing partial contentOffset to ScrollView on Android (#28817) Summary: Since support for contentOffset was added to horizontal ScrollView on android (30cc158a875a0414cf53d4d5155410eea5d5aeea) I'm seeing a crash in my app because of a library. What happens is that it passes a partial object for contentOffset so something like `{x: 1}` which causes a crash on Android. According to the flow types the object should always contain both x and y but I think we should preserve the runtime behaviour and just use 0 like iOS does. ## Changelog [Android] [Fixed] - Allow passing partial contentOffset to ScrollView on Android Pull Request resolved: https://github.com/facebook/react-native/pull/28817 Test Plan: Tested that passing partial object for contentOffset does not crash. Reviewed By: JoshuaGross Differential Revision: D21396319 Pulled By: shergin fbshipit-source-id: 4b52c868e3bfe183ff7f68a76ac34d1abd5e1069 * Pass initial props to WrapperComponent Summary: `renderApplication` receives the root component that we need to render and an optional wrapper component. There are cases where we want to use the initial props passed to the root component in the wrapper component as well (e.g.: to provide a specific context to the root component), so this adds modifies `AppContainer` to accept the initial props and inject them into the wrapper component. Changelog: [General] [Added] - Modified `renderApplication` to forward `initialProps` to `WrapperComponent` Reviewed By: fkgozali Differential Revision: D21347486 fbshipit-source-id: 1c4f702a3875077630de1a44d3ac9ef2c80bc10c * Upgrade to Jest 26 Summary: * Brings performance improvements from 25.5.x * Reduces node_modules by 3 MiB, see https://github.com/facebook/jest/pull/9950/files?short_path=63580dd#diff-63580dd1e7078ce037f10f2fee7553b9 * Breaking changes: https://github.com/facebook/jest/blob/master/CHANGELOG.md Changelog: [Internal] Reviewed By: rubennorte Differential Revision: D21369069 fbshipit-source-id: 81a9d50f8e541293a85ce3957cb962930ca05b11 * Make column match fuzzy Summary: We are currently very strict about breakpoint location matching. This diff allows some fuzz in the column, but not in the line. Changelog: [Internal] Setting Hermes breakpoints no longer requires exact column match Reviewed By: avp Differential Revision: D21343198 fbshipit-source-id: a59786a9d63f9fe1ed576835ed660ba3343affe1 * Fix type of exported Touchables: ComponentType -> AbstractComponent (#28737) Summary: Fixes https://github.com/facebook/react-native/issues/28726 When importing TouchableOpacity, it is treated as any by Flow. Replacing ComponentType with AbstractComponent works. The [Flow documentation](https://flow.org/en/docs/react/types/#toc-react-componenttype) says the following about ComponentType: > Note: In 0.89.0+, React.ComponentType is an alias for React.AbstractComponent, which represents a component with config type Config and any instance type. So I'm thinking that since the instance type is treated as any with ComponentType, Flow treats TouchableOpacity as any as well. ## Changelog [General] [Fixed] - Fix Touchable{Opacity,Bounce,Highlight} being exported as `any` (Flow) Pull Request resolved: https://github.com/facebook/react-native/pull/28737 Test Plan: I have done the same changes to react-native in my project's node_modules and seen that the components TouchableOpacity went from any to AbstractComponent with some props. Now I have a bunch of errors because I'm sending in wrong props to some touchables, which is good! Reviewed By: cpojer Differential Revision: D21362601 Pulled By: TheSavior fbshipit-source-id: 5b98cc79eaef034eccdb7f47242f9f44be2ef2b8 * Import folly and adjust whitespace to match old codegen Summary: Import folly to handle optionals (`folly::Optional<__type__>`) Sort modules and indent generated code to match output from the old codegen. While not strictly necessary as these are generated files that should not be edited by hand, I found that matching the old codegen in this regard made it less of a chore when it came to comparing the output of both codebases. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D21395231 fbshipit-source-id: 289d617d7a2d93724456c80afea57a49c108cb9b * Update native module specs Summary: As titled. Reviewed By: fkgozali Differential Revision: D21417307 fbshipit-source-id: 7c6b0179f9f1a5108da241d181a24f707a083deb * Smoother scrolling in ScrollView, HorizontalScrollView Summary: Android ScrollView/HorizontalScrollView `smoothScrollTo` contains some logic that, if called multiple times in a short amount of time, will treat all calls as part of the same animation and will not lengthen the duration of the animation. This means that, for example, if the user is scrolling rapidly, multiple pages could be considered part of one animation, causing some page animations to be animated very rapidly - looking like they're not animated at all. We use a custom animation to perform `smoothScrollTo` to improve the UX. This resolves a longstanding issue in non-Fabric RN, as well as Fabric, since this code is shared between the platforms. Changelog: [Update] Android ScrollView/HorizontalScrollView scrolls using custom animations instead of default Android `smoothScrollTo` implementation, leading to smoother scrolls for paginated ScrollViews Reviewed By: mdvacca Differential Revision: D21416520 fbshipit-source-id: 6ebe63cb054a98336b6e81253d35623fe5522f89 * Cleanup unused dependencies Reviewed By: kassens Differential Revision: D21281288 fbshipit-source-id: cf566ad0628dc179b3753f2f25a11637c33dee24 * iOS: Animated image should animate at the same speed regardless of framerate Summary: In iOS 11, [CADisplayLink](https://developer.apple.com/documentation/quartzcore/cadisplaylink)'s frameInterval was deprecated in favor of preferredFramesPerSecond, but these two properties have different underlying assumptions. - set frameInterval to 2 for 30fps - set preferredFramesPerSecond to 30 for 30fps. When you use preferredFramesPerSecond, assume frameInterval is 1. This fix ensures gifs in component will animate at same speed regardless of framerate. Reviewed By: shergin Differential Revision: D21414014 fbshipit-source-id: 40ab23bab1990cf65d2802830b6835f350999537 * LogBox - Always display the first fatal error Summary: This diff fixes an off-by-one error probably caused by my font ligatures where when exactly two exceptions are thrown at the same time we would show the second exception instead of the first. If three or more were thrown, we would show the second. I also fixed some tests that had the wrong descriptions and wrong behavior enforced. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D21413186 fbshipit-source-id: 8e2940c89251dc042b10c6a2a2186089b6e7b53d * Rename error titles Summary: Based on feedback we're updating these titles to be more clear for their source. Changelog: [Internal] Reviewed By: cpojer Differential Revision: D21413486 fbshipit-source-id: c144e7f759a4ff263b7ec80fa643eeb8ffac741b * Moved some NativeModule JS specs to OSS Summary: For some reason the specs were internal, but the native impl is still in github. So let's move these to github for consistency. Changelog: [Internal] Reviewed By: hramos Differential Revision: D21419934 fbshipit-source-id: f2c4486edca43c4348f3a3c6ce98f76a322bab0b * Deploy Flow v0.124.0 to xplat/js Summary: Changelog: [Internal] allow-large-files Reviewed By: samwgoldman, cpojer Differential Revision: D21413059 fbshipit-source-id: f3d111b40bfb88c182eab022925f7ae2dc47bc6b * RN: Workaround Fabric + Virtual Text Press Bug Summary: Workaround for a bug with Fabric when pressing on virtual text. Changelog: [Internal] (Note: this ignores all push blocking failures!) Reviewed By: JoshuaGross Differential Revision: D21432793 fbshipit-source-id: fe20eeadd5365707fb71edae7a76d374e26b4c86 * Fabric: Backward-compatible behaviour of `measureInWindow` and `measure` Summary: Before this change, in case of incorrect measurements, Fabric's implementation of `measure` and `measureInWindow` incorrectly returned negative height and width. Now it returns zeros (as classic React Native does). Fabric: This does not fix `measureLayout` called for virtual nodes. This is not so trivially to fix and it will be done separately. Changelog: [Internal] Fabric-specific internal change. Reviewed By: JoshuaGross, yungsters, mdvacca Differential Revision: D21433239 fbshipit-source-id: fbaf5ee35c690506822c634daac4426542c2cdcf * Upgrade to Yargs 15 Summary: Only breaking changes appear to be dropped Node 6 support: https://github.com/yargs/yargs/blob/master/CHANGELOG.md. Deduplicates quite a few copies of Yargs, yay! Changelog: [Internal] (Note: this ignores all push blocking failures!) Reviewed By: motiz88 Differential Revision: D21426137 fbshipit-source-id: b091e29ac2d9464d6ce9a716a99f7ae156a91a01 * Ez Extend logging of Fabric Summary: Quick diff to log of content of UpdateState mount item. This is useful for debugging. Note this will ONLY be logged when the constant FabricUIManager.IS_DEVELOPMENT_ENVIRONMENT is set to true changelog: [Internal][Android] internal log for fabric android Reviewed By: JoshuaGross Differential Revision: D21428345 fbshipit-source-id: d000eb6dbdd39d15935fa2102072790e17372682 * Fix measureLayout function for Virtual Nodes Summary: This diff fixes a NullPointerException thrown when calling measureLayout function on a virtual node. changelog: [Android] Fix measureLayout function for VirtualTexts Reviewed By: JoshuaGross Differential Revision: D21435030 fbshipit-source-id: aba6d81f333464e49d2d769b111842e7ae8ce769 * Update cocoapods (#28833) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/28833 The checked-in RNTester podfile was generated using Cocoapods version 1.9.1. This doesn't match the version currently used in CircleCI, which is 1.8.4. In order to update the offline mirrors and land them without breaking CircleCI, it seems we need to switch back to 1.8.4. This diff updates the podfile back to 1.8.4 and updates the offline mirrors. Reviewed By: fkgozali Differential Revision: D21392989 fbshipit-source-id: b14aa6e2798175534e9416410ba9d6877fb718c0 * Fabric: Introducing `RunLoopObserver` Summary: `RunLoopObserver` is one of the core interfaces that bridge intrinsically platform-specific functionality to cross-platform React Native core. `RunLoopObserver` allows subscribing for notifications about changes in a run loop life cycle. Primarily it supposed to be used for observing UI (aka main) and JavaScript execution thread/run-loop. Having a `RunLoopObserver` implemented in a platform-specific manner allows building these components in a cross-platform manner: * Sync and async UI event delivery pipeline; * Timing for some animation engine; * Timers (probably additional features are required). Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D21341997 fbshipit-source-id: 7ef61fb51f550dd0f2e89c64af657e0f0de029aa * Fabric: Cross-platform implementation of `SynchronousEventBeat` and `AsynchronousEventBeat` Summary: `SynchronousEventBeat` and `AsynchronousEventBeat` are a cross-platform re-implementation of run loop related parts of `MainRunLoopEventBeat` and `RuntimeEventBeat` (iOS specific classes for now). In the future, they will replace iOS- and Android-specifc event beat classes. Changelog: [Internal] Fabric-specific internal change. Reviewed By: sammy-SC Differential Revision: D21341996 fbshipit-source-id: 8eda9a5df537cd666b7728e32212a8bb5ddb3ab7 * third-party | Move glog from xplat/third-party to third-party and create temporary redirect. Summary: Move and create an empty rule that redirects as well, to handle //arvr rules Need to do this way, since ovrsource sync rules are in different repo. allow_many_files allow-large-files Steps: - [X] Move glog from xplat/third-party to /third-party - [ ] Update references in ovrsource to translate to //third-party instead of //xplat/third-party - [ ] Get rid of temporary rule - [ ] Update fbsource/third-party/glog to 0.3.5 (what we have in ovrsource) Changelog: [Internal] Update reference for glog from xplat/third-party to /third-party. Reviewed By: yfeldblum Differential Revision: D21363584 fbshipit-source-id: c1ffe2dd615077170b03d98dcfb77121537793c9 * Fix Animated type Summary: - Fixed typing of Animated and fixed the callsites Changelog: [Internal] Reviewed By: kacieb Differential Revision: D21311870 fbshipit-source-id: 386fb496ab00ef7917273dc3eb65e1ed76a8dd33 * Add virtual destructor to JSError Summary: We consume Hermes through multiple .so's, which means we have multiple (weak) typeinfo definitions of facebook::jsi::JSError. Previously we were using gnustl, which would strcmp typeinfo to decide whether a certain exception handler applies, which meant this didn't cause any major issues. However since this is deprecated, we recently switched to libc++, which does not have this by behaviour (or it does, but behind a flag I'm not sure how to enable). This causes any JS exceptions to fall through from our exception handlers and fatal the app. This problem is actually documented in the common Android NDK problems page: https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md#rtti_exceptions-not-working-across-library-boundaries The suggested solution is to ensure that any exception types have a key function defined (a non-pure, out-of-line virtual function). The simplest one to add is a virtual destructor. This makes the object file that holds the implementation of the destructor export a non-weak typeinfo definition which will at load time override the other weak versions. I'm not sure why we're the first to hit this. RN's JSIExecutor doesn't explicitly reference JSError which probably helps (https://github.com/facebook/react-native/blob/master/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp#L256-L258) and they also don't use unguarded callbacks like we do. Changelog: [Internal] Reviewed By: mhorowitz Differential Revision: D21426524 fbshipit-source-id: 474284ada1ca2810045dc4402c420879447f9308 * Handle initialProps as optional in renderApplication Summary: Pass a default empty object to `AppContainer` if no `initialProps` were passed to `renderApplication`. This prevents issues on Android, where we do not pass a default empty `initialProps` from native, as we do on iOS. Changelog: [General] [Fixed] - Handle nullish `initialProps` correctly in `renderApplication` Reviewed By: motiz88 Differential Revision: D21448692 fbshipit-source-id: 9630bdc2414532999abf3bf9da25047f0482fcab * Enable with CocoaPods `:configuration` (#28796) Summary: ~~⚠️ Depends on https://github.com/facebook/flipper/pull/1086 and a new Flipper release.~~ Fixes https://github.com/facebook/react-native/commit/17f025bc26da13da795845a3f7daee65563420c0#commitcomment-38831234 Currently user’s are being told to add a definition of the `FB_SONARKIT_ENABLED` macro and examples, including those in stock React Native templates, set this for the user by making use of a `post_install` hook in the user’s `Podfile`. This leads to confusion, fragile code [when a user’s project dir structure deviates from vanilla], and is ultimately not necessary as CocoaPods already has dedicated mechanisms to: * specify build settings (through the `xcconfig` property); * and selectively include certain pods only in certain build configurations (e.g. debug). ## Changelog [iOS] [Changed] - Entirely control Flipper being enabled through inclusion in Podfile and optionally limiting to certain build configurations using the `:configuration` directive. Pull Request resolved: https://github.com/facebook/react-native/pull/28796 Test Plan: Tested using the changes of https://github.com/facebook/flipper/pull/1086 in a new app that uses RN `master`. Reviewed By: priteshrnandgaonkar Differential Revision: D21449754 Pulled By: passy fbshipit-source-id: 9ff7c7f4ffc32b364b1edd82b94e0b80c3997625 * Support excluding multiple platforms. Summary: Currently the schema only allows to exclude a single platform (iOS OR Android). There are cases where we need to exclude multiple. This change converts the previous `excludePlatform` string property into an `excludePlatforms` array. Changelog: [Internal][Changed] - Added support to exclude multiple platforms in Codegen. Reviewed By: sammy-SC Differential Revision: D21426950 fbshipit-source-id: eff36ffa207109274794b4b300bf6313f8286161 * Extend ParagraphAttribute to store the includeFontPadding prop Summary: This diff extends the ParagraphAttribute class to store the value of the includeFontPadding prop. Note that this is an Android only prop, I'm not creating android blocks to improve "cleanliness" of the code. changelog: [Internal][Fabric] Internal change in Fabric to support Text.includeFontPadding prop in fabric Reviewed By: shergin Differential Revision: D21446738 fbshipit-source-id: 0543e86aa18ce10f7a56bbaafe111cce0179ea86 * Extend Text measurement to support includeFontPadding prop Summary: This diff exposes the Text.includeFontPadding prop to java, then it uses the prop to calculate the height of Text components correctly. changelog: [Internal][Fabric] Internal change in Fabric to support Text.includeFontPadding prop in fabric Reviewed By: shergin Differential Revision: D21446737 fbshipit-source-id: efe73fb6b0d402c3275ac8c012fa8fa06b743bdd * Small refactor on text measure method Summary: Quick refactor of TextLayoutManager class changelog: [Internal] Reviewed By: shergin Differential Revision: D21446736 fbshipit-source-id: a32bdf534b167e128c8c0054cf6a126131fa740a * Handle optional return types/values Summary: Use folly to wrap optional return types and values as needed. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D21395439 fbshipit-source-id: a0e84e20717887e79a8565332a11fef42ebd3487 * Avoid redefining id when a property is named 'id' Summary: Handle properties named 'id' as a special case. An example of a native module that ran afoul of this is `ExceptionsManager`. Observe how the ExceptionsManager spec at `Libraries/Core/NativeExceptionsManager.js` defines the ExceptionData type as containing an `id` property: ``` export type ExceptionData = { message: string, originalMessage: ?string, name: ?string, componentStack: ?string, stack: Array, id: number, isFatal: boolean, // flowlint-next-line unclear-type:off extraData?: Object, ... }; ``` Prior to this change, the generated code would redefine id in the SpecReportExceptionData struct... ``` namespace JS { namespace NativeExceptionsManager { struct SpecReportExceptionData { // ...redacted... double id() const; <--- // ...redacted... SpecReportExceptionData(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } ``` ...which would result in a build time error: ``` inline double JS::NativeExceptionsManager::SpecReportExceptionData::id() const { id const p = _v[@"id"]; ^--- build time error here return RCTBridgingToDouble(p); } ``` Comparing the above example with the currently checked in `FBReactNativeSpec.h`, I see the expected output should be: ``` namespace JS { namespace NativeExceptionsManager { struct SpecReportExceptionData { // ...redacted... double id_() const; // ...redacted... SpecReportExceptionData(NSDictionary *const v) : _v(v) {} private: NSDictionary *_v; }; } } ``` ...and... ``` inline double JS::NativeExceptionsManager::SpecReportExceptionData::id_() const { id const p = _v[@"id"]; return RCTBridgingToDouble(p); } ``` Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D21395463 fbshipit-source-id: e412648013ff9f70ebd294b6f5f81f1faccb4604 * Eager initialize Fabric Android classes Summary: This diff eager initializes Fabric Android classes. This should help load all the Fabric classes at Bridge load time. changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D21460507 fbshipit-source-id: 4b8d5c4e2d19e3a7eb3077027071e64ff16f1cbd * Remove Hermes.setPauseOnLoad message Summary: This removes the Hermes.setPauseOnLoad. It will be replaced by the more standard Debugger.setInstrumentationBreakpoint's "beforeScriptExecution" event. ChangeLog: [Internal] Remove Hermes.setPauseOnLoad message (to be replaced) Reviewed By: mhorowitz Differential Revision: D21418219 fbshipit-source-id: 93c53801c23487f9336b322c2bd737663ec21b97 * Add support for Debugger.setInstrumentationBreakpoint Summary: This diff adds support for the "beforeScriptWithSourceMapExecution" instrumentation breakpoint via "Debugger.setInstrumentationBreakpoint". CDP describes it as a breakpoint, but we just set a flag in the inspector. A fake breakpoint ID is synthesized for optional removal later. Changelog: [Internal] Add Debugger.setInstrumentationBreakpoint to Hermes Inspector Reviewed By: mhorowitz Differential Revision: D21418218 fbshipit-source-id: 90fa49c0954980993815322d3a7effee416ed5db * label react-native-github targets Summary: For internal code attribution. Changelog: [Internal] Reviewed By: zlern2k Differential Revision: D21468924 fbshipit-source-id: 59cd2a52e0ae46bedbf54816820a5f40b684da8b * Add script to generate native modules specs with react-native-codegen Summary: Adds a script that uses `react-native-codegen` to generate FBReactNativeSpec. The generated output should not be considered ready for production use at this time. The goal of adding this script at this time is to demonstrate the current status of native modules specs code generation in open source. For example, the generated output may be used in RNTester, with some modifications due to some naming differences in react-native-codegen's output when compared to the FBReactNativeSpec files generated by the old codegen. Usage: ``` ./scripts/generate-native-modules-specs.sh ./codegen-out ``` Changelog: [Internal] Reviewed By: TheSavior Differential Revision: D21471004 fbshipit-source-id: 5ff3c57807d9ba2c91dc7fe32d227d218732b059 * Update .gitignore (#28789) Summary: When you profile your heap and memory allocations with Memory Profiler, files with *.hprof extension are created in /android folder that has big sizes (up to 600 MB for each). These files may be needed to add to gitignore. ## Changelog [Android] [Added] - Add *.hprof files to gitignore Pull Request resolved: https://github.com/facebook/react-native/pull/28789 Differential Revision: D21432927 Pulled By: hramos fbshipit-source-id: a20f12645de5ca0874c9130094e2f97fe16b2203 * Codegen: Add prepublish script to build Flow files (#28827) Summary: *This is a follow-up to https://github.com/facebook/react-native/issues/28645, redone using a build script based off of Metro's build script instead of using `flow-remove-types` and `flow-copy-source`.* This pull request adds a build step to `react-native-codegen` that builds the Flow-annotated JS files so that users of the NPM module `react-native-codegen` do not need to use require hooks to be able to import it. A new build script, `scripts/build.js` is added that builds every JS file in `src/` into a `lib/` folder, and also copies over the original Flow annotated files to `lib/` with a `.js.flow` extension, so users of `react-native-codegen` can still typecheck against it using Flow. The shell scripts in `src` are also copied over. It is based off of the [build script from Metro](https://github.com/facebook/metro/blob/00867816eb9b2f69c8af9cebb523e9e4d280671a/scripts/build.js) ## Changelog [General] [Added] - Codegen: Add prepublish script to build Flow files Pull Request resolved: https://github.com/facebook/react-native/pull/28827 Test Plan: I am able to make use of the Codegen scripts without needing to use the `flow-node` CLI or the `flow-remove-types/register` require hook. Reviewed By: cpojer Differential Revision: D21412173 Pulled By: hramos fbshipit-source-id: 26ae67cdd04652ca4700a069a234a25558773cb1 * Remove RCTLogError from RCTScrollViewManager.calculateChildFrames Summary: Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21483553 fbshipit-source-id: 0c681979a4988c36cfa6f05aa5bca896590f9e3d * Enable animations in bridgeless mode on iOS Reviewed By: ejanzer Differential Revision: D21465166 fbshipit-source-id: b34e8e97330b897e20d9a4b05dba1826df569e16 * Expose RuntimeExecutor on CatalystInstance (#28851) Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/28851 This diff creates a RuntimeExecutor that uses the bridge and exposes it on CatalystInstanceImpl. Changelog: [Internal] Reviewed By: mdvacca, RSNara Differential Revision: D21051949 fbshipit-source-id: b3977fc14fa19089f33e297d29cedba0d067526d * Inject ImagePipeline into FrescoModule Summary: This diff refactors the FrescoModule in order to receive an ImagePipeline as a parameter. This is necessary to ensure the same ImagePipeline is used by every RN module changelog: [Internal][Android] Reviewed By: JoshuaGross Differential Revision: D21428346 fbshipit-source-id: 70a6cc57c8585fe74b6d0b0d1fd86c539974ec23 * Fabric: Calling JSVM GC on memory pressure event on iOS Summary: This change is especially important for Fabric when a lot of objects (mostly `ShadowNode`s) have shared ownership. Without this change, JSVM could not know that bunch of natively allocated objects should be deallocated. Changelog: [Internal] Fabric-specific internal change. Reviewed By: dulinriley Differential Revision: D21484773 fbshipit-source-id: 46e32de0f108082e60df346884c9287023156149 * TextInput: Default `blurOnSubmit` in JS Summary: Consolidates the logic for the default value of `blurOnSubmit` on `TextInput` in the JavaScript component. This only materially impacts Fabric. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D21491482 fbshipit-source-id: 16d8aba32e7d0321a4583e87e03405ea587e35d4 * (Temporarily) remove droid-node-patching portions of Apple verification Co-authored-by: Mike Grabowski Co-authored-by: George Zahariev Co-authored-by: Scott Wolchok Co-authored-by: Radek Czemerys Co-authored-by: Lauren Tan Co-authored-by: Vojtech Novak Co-authored-by: Tom Underhill Co-authored-by: Kevin Gozali Co-authored-by: Frieder Bluemle Co-authored-by: Samuel Susla Co-authored-by: Valentin Shergin Co-authored-by: Will Holen Co-authored-by: Sidharth Guglani Co-authored-by: empyrical Co-authored-by: Joshua Gross Co-authored-by: Héctor Ramos Co-authored-by: Ramanpreet Nara Co-authored-by: Eli White Co-authored-by: Christoph Nakazawa Co-authored-by: Tommy Nguyen Co-authored-by: Rick Hanlon Co-authored-by: jeswinsimon Co-authored-by: Tim Yung Co-authored-by: Jesse Katsumata Co-authored-by: Pritesh Nandgaonkar Co-authored-by: Ryan Tremblay Co-authored-by: acton393 Co-authored-by: Zack Argyle Co-authored-by: Jason Safaiyeh Co-authored-by: Hein Rutjes Co-authored-by: Hein Rutjes Co-authored-by: David Vacca Co-authored-by: generatedunixname89002005287564 Co-authored-by: sunnylqm Co-authored-by: Panagiotis Vekris Co-authored-by: Jonny Burger Co-authored-by: Keith Melmon Co-authored-by: simek Co-authored-by: Marc Horowitz Co-authored-by: Jakub Kinst Co-authored-by: Paige Sun Co-authored-by: Emily Janzer Co-authored-by: yogevbd Co-authored-by: Lulu Wu Co-authored-by: Mark Lord Co-authored-by: Daiki Ihara Co-authored-by: Your Name Co-authored-by: James Ide Co-authored-by: Boyang Yu Co-authored-by: zhongwuzw Co-authored-by: Kacie Bawiec Co-authored-by: Nick Gerleman Co-authored-by: Janic Duplessis Co-authored-by: Rubén Norte Co-authored-by: Mats Byrkjeland Co-authored-by: Nat Mote Co-authored-by: Nikita Lutsenko Co-authored-by: Yuanzhe Bian Co-authored-by: Pieter De Baets Co-authored-by: Eloy Durán Co-authored-by: João Vieira Co-authored-by: Enes Co-authored-by: Peter Argany --- .ado/templates/apple-job-javascript.yml | 4 - .ado/templates/apple-job-react-native.yml | 4 - .eslintignore | 1 + .flowconfig | 2 +- .flowconfig.android | 2 +- .flowconfig.macos | 2 +- .gitignore | 5 + Libraries/ART/ARTGroup.m | 12 +- Libraries/ART/ARTNode.m | 6 +- Libraries/ART/ARTSurfaceView.m | 11 +- Libraries/Animated/src/Animated.js | 27 +- .../RCTDatePickerNativeComponent.js | 2 +- .../PullToRefreshViewNativeComponent.js | 2 +- .../Switch/SwitchNativeComponent.js | 2 +- Libraries/Components/TextInput/TextInput.js | 6 + .../__snapshots__/TextInput-test.js.snap | 2 + Libraries/Components/Touchable/Touchable.js | 2 +- .../Components/Touchable/TouchableBounce.js | 2 +- .../Touchable/TouchableHighlight.js | 2 +- .../Components/Touchable/TouchableOpacity.js | 2 +- Libraries/Image/NativeImageEditor.js | 51 + Libraries/Image/NativeImageStore.js | 41 + Libraries/Image/RCTImageLoader.mm | 4 +- Libraries/Image/RCTImageView.mm | 34 +- Libraries/Image/RCTUIImageViewAnimated.m | 16 +- Libraries/LayoutAnimation/LayoutAnimation.js | 57 +- Libraries/Lists/VirtualizedList.js | 301 +-- Libraries/Lists/VirtualizedListContext.js | 152 ++ .../Lists/__tests__/VirtualizedList-test.js | 48 + Libraries/LogBox/Data/LogBoxData.js | 12 +- .../LogBox/Data/__tests__/LogBoxData-test.js | 16 +- Libraries/LogBox/UI/LogBoxInspector.js | 8 +- Libraries/Modal/Modal.js | 29 +- Libraries/Pressability/Pressability.js | 11 +- Libraries/ReactNative/AppContainer.js | 2 + Libraries/ReactNative/FabricUIManager.js | 10 +- Libraries/ReactNative/renderApplication.js | 1 + Libraries/Renderer/shims/ReactNativeTypes.js | 33 + .../NativeTimePickerAndroid.js | 31 + Libraries/Utilities/LoadingView.ios.js | 13 +- Libraries/Utilities/codegenNativeComponent.js | 2 +- RNTester/Podfile.lock | 61 +- .../RNTesterPods.xcodeproj/project.pbxproj | 3 +- .../xcshareddata/xcschemes/RNTester.xcscheme | 2 +- .../RNTesterIntegrationTests.xcscheme | 2 +- .../xcschemes/RNTesterUnitTests.xcscheme | 2 +- .../js/examples/FlatList/FlatListExample.js | 8 +- .../PushNotificationIOSExample.js | 2 +- .../SectionList/SectionListExample.js | 5 +- React/Base/RCTJavaScriptLoader.mm | 12 +- React/CoreModules/RCTDevLoadingView.mm | 99 +- React/CxxBridge/RCTCxxBridge.mm | 26 + .../ART/RCTARTSurfaceShadowNode.cpp | 14 - .../ART/RCTARTSurfaceShadowNode.h | 27 - .../ART/RCTARTSurfaceViewComponentView.h | 15 - .../ART/RCTARTSurfaceViewComponentView.mm | 41 - .../ART/RCTARTSurfaceViewProps.cpp | 21 - .../ART/RCTARTSurfaceViewProps.h | 26 - .../Image/RCTImageComponentView.mm | 38 +- ...CTLegacyViewManagerInteropComponentView.mm | 12 +- .../RCTFabricComponentsPlugins.h | 1 - .../RCTFabricComponentsPlugins.mm | 1 - .../RCTSafeAreaViewComponentView.mm | 6 + .../TextInput/RCTTextInputComponentView.mm | 34 +- .../View/RCTViewComponentView.mm | 1 + React/Fabric/RCTSurfacePresenter.h | 2 +- .../RCTSurfacePresenterBridgeAdapter.mm | 2 +- React/Fabric/Utils/MainRunLoopEventBeat.h | 2 +- React/Fabric/Utils/RuntimeEventBeat.h | 2 +- React/Views/ScrollView/RCTScrollViewManager.m | 1 - .../com/facebook/react/testing/network/BUCK | 1 + .../testing/rule/ReactNativeTestRule.java | 5 + .../main/java/com/facebook/debug/holder/BUCK | 1 + .../main/java/com/facebook/debug/tags/BUCK | 1 + .../main/java/com/facebook/fbreact/specs/BUCK | 1 + .../com/facebook/hermes/instrumentation/BUCK | 2 + .../facebook/react/ReactInstanceManager.java | 85 +- .../com/facebook/react/ReactRootView.java | 82 +- .../java/com/facebook/react/animated/BUCK | 1 + .../react/animated/NativeAnimatedModule.java | 7 +- .../animated/NativeAnimatedNodesManager.java | 12 +- .../main/java/com/facebook/react/bridge/BUCK | 2 + .../react/bridge/CatalystInstance.java | 8 +- .../react/bridge/CatalystInstanceImpl.java | 25 +- .../facebook/react/bridge/ReactContext.java | 1 + .../react/bridge/RuntimeExecutor.java | 21 + .../com/facebook/react/bridge/UIManager.java | 10 + .../main/java/com/facebook/react/common/BUCK | 1 + .../com/facebook/react/common/network/BUCK | 1 + .../main/java/com/facebook/react/config/BUCK | 1 + .../react/config/ReactFeatureFlags.java | 3 + .../java/com/facebook/react/devsupport/BUCK | 2 + .../devsupport/DevSupportManagerBase.java | 27 +- .../main/java/com/facebook/react/fabric/BUCK | 1 + .../react/fabric/FabricJSIModuleProvider.java | 34 +- .../react/fabric/FabricUIManager.java | 16 +- .../java/com/facebook/react/fabric/jni/BUCK | 3 +- .../react/fabric/jni/EventBeatManager.h | 2 +- .../mountitems/UpdateStateMountItem.java | 2 +- .../java/com/facebook/react/jscexecutor/BUCK | 1 + .../main/java/com/facebook/react/jstasks/BUCK | 1 + .../facebook/react/module/annotations/BUCK | 1 + .../java/com/facebook/react/module/model/BUCK | 1 + .../com/facebook/react/module/processing/BUCK | 1 + .../react/modules/accessibilityinfo/BUCK | 1 + .../facebook/react/modules/appearance/BUCK | 1 + .../facebook/react/modules/appregistry/BUCK | 1 + .../com/facebook/react/modules/appstate/BUCK | 1 + .../java/com/facebook/react/modules/blob/BUCK | 1 + .../com/facebook/react/modules/blob/jni/BUCK | 1 + .../com/facebook/react/modules/camera/BUCK | 1 + .../com/facebook/react/modules/clipboard/BUCK | 1 + .../com/facebook/react/modules/common/BUCK | 1 + .../java/com/facebook/react/modules/core/BUCK | 1 + .../facebook/react/modules/datepicker/BUCK | 1 + .../com/facebook/react/modules/debug/BUCK | 2 + .../modules/debug/FpsDebugFrameCallback.java | 3 +- .../facebook/react/modules/deviceinfo/BUCK | 1 + .../com/facebook/react/modules/dialog/BUCK | 1 + .../com/facebook/react/modules/fabric/BUCK | 1 + .../com/facebook/react/modules/fresco/BUCK | 1 + .../react/modules/fresco/FrescoModule.java | 27 +- .../facebook/react/modules/i18nmanager/BUCK | 1 + .../com/facebook/react/modules/image/BUCK | 2 + .../modules/image/ImageLoaderModule.java | 37 +- .../com/facebook/react/modules/intent/BUCK | 1 + .../com/facebook/react/modules/network/BUCK | 1 + .../facebook/react/modules/permissions/BUCK | 1 + .../com/facebook/react/modules/share/BUCK | 1 + .../com/facebook/react/modules/sound/BUCK | 1 + .../com/facebook/react/modules/statusbar/BUCK | 1 + .../com/facebook/react/modules/storage/BUCK | 1 + .../modules/systeminfo/AndroidInfoModule.java | 14 +- .../facebook/react/modules/systeminfo/BUCK | 2 + .../facebook/react/modules/timepicker/BUCK | 1 + .../com/facebook/react/modules/toast/BUCK | 1 + .../com/facebook/react/modules/vibration/BUCK | 1 + .../com/facebook/react/modules/websocket/BUCK | 1 + .../facebook/react/packagerconnection/BUCK | 1 + .../java/com/facebook/react/processing/BUCK | 1 + .../main/java/com/facebook/react/shell/BUCK | 2 +- .../react/shell/MainReactPackage.java | 6 - .../main/java/com/facebook/react/surface/BUCK | 1 + .../main/java/com/facebook/react/touch/BUCK | 1 + .../com/facebook/react/turbomodule/core/BUCK | 2 + .../turbomodule/core/TurboModuleManager.java | 125 +- .../react/turbomodule/core/interfaces/BUCK | 1 + .../facebook/react/turbomodule/core/jni/BUCK | 2 + .../java/com/facebook/react/uimanager/BUCK | 2 + .../uimanager/NativeViewHierarchyManager.java | 16 +- .../facebook/react/uimanager/ReactRoot.java | 3 +- .../react/uimanager/UIImplementation.java | 2 +- .../react/uimanager/UIManagerModule.java | 11 + .../react/uimanager/UIViewOperationQueue.java | 13 +- .../facebook/react/uimanager/annotations/BUCK | 1 + .../com/facebook/react/uimanager/common/BUCK | 1 + .../com/facebook/react/uimanager/util/BUCK | 1 + .../main/java/com/facebook/react/util/BUCK | 1 + .../java/com/facebook/react/viewmanagers/BUCK | 1 + .../DatePickerManagerDelegate.java | 62 + .../DatePickerManagerInterface.java | 25 + .../PullToRefreshViewManagerDelegate.java | 51 + .../PullToRefreshViewManagerInterface.java | 21 + .../viewmanagers/SwitchManagerDelegate.java | 22 +- .../react/views/art/ARTGroupShadowNode.java | 76 - .../react/views/art/ARTGroupViewManager.java | 19 - .../views/art/ARTRenderableViewManager.java | 84 - .../react/views/art/ARTShapeShadowNode.java | 320 ---- .../react/views/art/ARTShapeViewManager.java | 19 - .../react/views/art/ARTSurfaceView.java | 19 - .../views/art/ARTSurfaceViewManager.java | 75 - .../views/art/ARTSurfaceViewShadowNode.java | 155 -- .../react/views/art/ARTTextShadowNode.java | 137 -- .../react/views/art/ARTTextViewManager.java | 19 - .../react/views/art/ARTVirtualNode.java | 109 -- .../java/com/facebook/react/views/art/BUCK | 21 - .../facebook/react/views/art/PropHelper.java | 48 - .../java/com/facebook/react/views/common/BUCK | 1 + .../java/com/facebook/react/views/drawer/BUCK | 1 + .../drawer/ReactDrawerLayoutManager.java | 9 +- .../java/com/facebook/react/views/image/BUCK | 2 + .../image/ReactCallerContextFactory.java | 8 +- .../react/views/image/ReactImageManager.java | 4 +- .../com/facebook/react/views/imagehelper/BUCK | 2 + .../java/com/facebook/react/views/modal/BUCK | 1 + .../views/modal/ReactModalHostManager.java | 8 +- .../react/views/modal/ReactModalHostView.java | 11 +- .../java/com/facebook/react/views/picker/BUCK | 1 + .../views/picker/ReactPickerManager.java | 10 +- .../com/facebook/react/views/progressbar/BUCK | 1 + .../java/com/facebook/react/views/scroll/BUCK | 1 + .../scroll/ReactHorizontalScrollView.java | 80 +- .../ReactHorizontalScrollViewManager.java | 4 +- .../react/views/scroll/ReactScrollView.java | 78 +- .../views/scroll/ReactScrollViewHelper.java | 47 + .../views/scroll/ReactScrollViewManager.java | 4 +- .../java/com/facebook/react/views/slider/BUCK | 1 + .../views/slider/ReactSliderManager.java | 34 +- .../facebook/react/views/swiperefresh/BUCK | 1 + .../com/facebook/react/views/switchview/BUCK | 1 + .../views/switchview/ReactSwitchManager.java | 10 +- .../java/com/facebook/react/views/text/BUCK | 1 + .../react/views/text/ReactTextView.java | 4 +- .../react/views/text/TextLayoutManager.java | 23 +- .../react/views/text/frescosupport/BUCK | 1 + .../com/facebook/react/views/textinput/BUCK | 1 + .../react/views/textinput/ReactEditText.java | 4 +- .../ReactEditTextInputConnectionWrapper.java | 5 +- .../textinput/ReactTextInputManager.java | 9 +- .../react/views/unimplementedview/BUCK | 1 + .../java/com/facebook/react/views/view/BUCK | 1 + .../react/views/view/ReactViewManager.java | 12 +- .../com/facebook/react/views/viewpager/BUCK | 1 + .../react/views/viewpager/ReactViewPager.java | 5 +- .../src/main/jni/react/jni/Android.mk | 3 +- ReactAndroid/src/main/jni/react/jni/BUCK | 5 +- .../jni/react/jni/CatalystInstanceImpl.cpp | 11 + .../main/jni/react/jni/CatalystInstanceImpl.h | 4 + .../main/jni/react/jni/JRuntimeExecutor.cpp | 13 +- .../src/main/jni/react/jni/JRuntimeExecutor.h | 30 + ReactCommon/better/BUCK | 3 +- ReactCommon/callinvoker/BUCK | 1 + ReactCommon/config/BUCK | 3 +- ReactCommon/cxxreact/Android.mk | 2 +- ReactCommon/cxxreact/BUCK | 8 +- ReactCommon/cxxreact/Instance.cpp | 4 + ReactCommon/cxxreact/Instance.h | 6 + ReactCommon/cxxreact/NativeToJsBridge.cpp | 17 + ReactCommon/cxxreact/NativeToJsBridge.h | 7 + ReactCommon/cxxreact/React-cxxreact.podspec | 1 + ReactCommon/fabric/attributedstring/BUCK | 3 +- .../attributedstring/ParagraphAttributes.cpp | 9 +- .../attributedstring/ParagraphAttributes.h | 9 +- .../fabric/attributedstring/conversions.h | 7 + ReactCommon/fabric/componentregistry/BUCK | 3 +- .../fabric/components/activityindicator/BUCK | 3 +- ReactCommon/fabric/components/image/BUCK | 3 +- .../components/image/ImageShadowNode.cpp | 11 +- .../fabric/components/image/ImageShadowNode.h | 2 +- .../fabric/components/image/ImageState.cpp | 4 + .../fabric/components/image/ImageState.h | 15 +- ...cyViewManagerInteropComponentDescriptor.mm | 6 + ReactCommon/fabric/components/modal/BUCK | 3 +- ReactCommon/fabric/components/picker/BUCK | 4 +- ReactCommon/fabric/components/root/BUCK | 3 +- ReactCommon/fabric/components/scrollview/BUCK | 3 +- ReactCommon/fabric/components/slider/BUCK | 3 +- ReactCommon/fabric/components/switch/BUCK | 3 +- ReactCommon/fabric/components/text/BUCK | 3 +- ReactCommon/fabric/components/textinput/BUCK | 3 +- .../AndroidTextInputShadowNode.h | 7 + .../components/textinput/iostextinput/BUCK | 2 +- .../iostextinput/TextInputShadowNode.h | 1 + .../fabric/components/unimplementedview/BUCK | 2 +- ReactCommon/fabric/components/view/BUCK | 3 +- ReactCommon/fabric/core/BUCK | 3 +- .../core/shadownode/ShadowNodeFamily.cpp | 9 + .../fabric/core/shadownode/ShadowNodeFamily.h | 9 + ReactCommon/fabric/core/state/State.cpp | 9 + ReactCommon/fabric/core/state/State.h | 6 + ReactCommon/fabric/debug/BUCK | 1 + ReactCommon/fabric/graphics/BUCK | 3 +- ReactCommon/fabric/imagemanager/BUCK | 3 +- ReactCommon/fabric/mapbuffer/BUCK | 2 +- ReactCommon/fabric/mounting/BUCK | 4 +- .../fabric/mounting/Differentiator.cpp | 26 +- ReactCommon/fabric/mounting/ShadowTree.cpp | 158 +- ReactCommon/fabric/mounting/ShadowTree.h | 9 + .../mounting/tests/MountingTelemetryTest.cpp | 4 +- .../fabric/mounting/tests/MountingTest.cpp | 38 + .../tests/ShadowTreeLifeCycleTest.cpp | 8 +- .../scheduler/AsynchronousEventBeat.cpp | 55 + .../fabric/scheduler/AsynchronousEventBeat.h | 41 + ReactCommon/fabric/scheduler/BUCK | 3 +- ReactCommon/fabric/scheduler/Scheduler.cpp | 10 + ReactCommon/fabric/scheduler/Scheduler.h | 3 +- .../fabric/scheduler/SchedulerToolbox.h | 2 +- .../fabric/scheduler/SynchronousEventBeat.cpp | 50 + .../fabric/scheduler/SynchronousEventBeat.h | 44 + ReactCommon/fabric/templateprocessor/BUCK | 3 +- ReactCommon/fabric/textlayoutmanager/BUCK | 3 +- ReactCommon/fabric/uimanager/BUCK | 5 +- ReactCommon/fabric/uimanager/UIManager.cpp | 24 +- ReactCommon/fabric/uimanager/UIManager.h | 10 +- .../fabric/uimanager/UIManagerBinding.cpp | 35 +- ReactCommon/hermes/inspector/BUCK | 10 +- ReactCommon/hermes/inspector/Inspector.cpp | 3 +- .../hermes/inspector/chrome/Connection.cpp | 143 +- .../hermes/inspector/chrome/MessageTypes.cpp | 80 +- .../hermes/inspector/chrome/MessageTypes.h | 42 +- .../chrome/tests/AsyncHermesRuntime.cpp | 4 + .../chrome/tests/AsyncHermesRuntime.h | 5 + .../chrome/tests/ConnectionTests.cpp | 118 ++ .../hermes/inspector/tools/message_types.txt | 2 +- ReactCommon/jsi/jsi/jsi.cpp | 6 + ReactCommon/jsi/jsi/jsi.h | 6 + ReactCommon/jsiexecutor/BUCK | 3 +- ReactCommon/jsinspector/BUCK | 1 + ReactCommon/microprofiler/BUCK | 1 + .../.clang-tidy | 0 ReactCommon/runtimeexecutor/Android.mk | 19 + ReactCommon/runtimeexecutor/BUCK | 53 + .../React-runtimeexecutor.podspec | 36 + .../ReactCommon}/RuntimeExecutor.h | 8 +- ReactCommon/turbomodule/core/BUCK | 3 +- .../platform/ios/RCTTurboModuleManager.mm | 39 +- ReactCommon/turbomodule/samples/BUCK | 2 + .../samples/SampleTurboCxxModule.cpp | 4 +- .../samples/SampleTurboCxxModule.h | 4 +- ReactCommon/utils/BUCK | 1 + ReactCommon/utils/RunLoopObserver.cpp | 62 + ReactCommon/utils/RunLoopObserver.h | 129 ++ ReactCommon/yoga/yoga/Yoga.cpp | 26 +- ReactCommon/yoga/yoga/Yoga.h | 4 +- package.json | 12 +- packages/react-native-codegen/.babelrc | 11 + packages/react-native-codegen/.prettierrc | 7 + packages/react-native-codegen/DEFS.bzl | 2 +- packages/react-native-codegen/package.json | 26 +- .../react-native-codegen/scripts/build.js | 117 ++ .../react-native-codegen/src/CodegenSchema.js | 6 +- .../components/GenerateComponentHObjCpp.js | 5 +- .../generators/components/GeneratePropsCpp.js | 5 +- .../generators/components/GeneratePropsH.js | 5 +- .../components/GeneratePropsJavaDelegate.js | 5 +- .../components/GeneratePropsJavaInterface.js | 5 +- .../components/__test_fixtures__/fixtures.js | 24 +- .../GenerateComponentDescriptorH-test.js.snap | 26 + .../GenerateComponentHObjCpp-test.js.snap | 21 + .../GenerateEventEmitterCpp-test.js.snap | 23 + .../GenerateEventEmitterH-test.js.snap | 24 + .../GeneratePropsCpp-test.js.snap | 24 + .../__snapshots__/GeneratePropsH-test.js.snap | 24 + .../GeneratePropsJavaDelegate-test.js.snap | 2 + .../GeneratePropsJavaInterface-test.js.snap | 2 + .../GenerateShadowNodeCpp-test.js.snap | 23 + .../GenerateShadowNodeH-test.js.snap | 33 + .../__snapshots__/GenerateTests-test.js.snap | 28 + .../GenerateViewConfigJs-test.js.snap | 32 + .../modules/GenerateModuleHObjCpp.js | 37 +- .../generators/modules/GenerateModuleMm.js | 39 +- .../modules/ObjCppUtils/GenerateStructs.js | 109 +- .../modules/__test_fixtures__/fixtures.js | 129 ++ .../GenerateModuleCpp-test.js.snap | 12 + .../GenerateModuleH-test.js.snap | 2 + .../GenerateModuleHObjCpp-test.js.snap | 291 ++- .../GenerateModuleMm-test.js.snap | 276 +-- .../components/__test_fixtures__/fixtures.js | 1 + .../component-parser-test.js.snap | 3 + .../src/parsers/flow/components/options.js | 8 +- scripts/generate-native-modules-specs.sh | 52 + scripts/react-native-xcode.sh | 10 +- scripts/react_native_pods.rb | 28 +- scripts/run-ci-e2e-tests.js | 28 +- template/_flowconfig | 2 +- .../android/app/src/debug/AndroidManifest.xml | 7 +- .../android/app/src/main/AndroidManifest.xml | 2 - yarn.lock | 1639 +++++++---------- 358 files changed, 5134 insertions(+), 3439 deletions(-) create mode 100644 Libraries/Image/NativeImageEditor.js create mode 100644 Libraries/Image/NativeImageStore.js create mode 100644 Libraries/Lists/VirtualizedListContext.js create mode 100644 Libraries/TimePickerAndroid/NativeTimePickerAndroid.js delete mode 100644 React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.cpp delete mode 100644 React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.h delete mode 100644 React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.h delete mode 100644 React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.mm delete mode 100644 React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.cpp delete mode 100644 React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.h create mode 100644 ReactAndroid/src/main/java/com/facebook/react/bridge/RuntimeExecutor.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerDelegate.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerInterface.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerDelegate.java create mode 100644 ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerInterface.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupViewManager.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTRenderableViewManager.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeViewManager.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceView.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextViewManager.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/BUCK delete mode 100644 ReactAndroid/src/main/java/com/facebook/react/views/art/PropHelper.java rename React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentDescriptor.h => ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.cpp (56%) create mode 100644 ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h create mode 100644 ReactCommon/fabric/scheduler/AsynchronousEventBeat.cpp create mode 100644 ReactCommon/fabric/scheduler/AsynchronousEventBeat.h create mode 100644 ReactCommon/fabric/scheduler/SynchronousEventBeat.cpp create mode 100644 ReactCommon/fabric/scheduler/SynchronousEventBeat.h rename ReactCommon/{jscallinvoker => runtimeexecutor}/.clang-tidy (100%) create mode 100644 ReactCommon/runtimeexecutor/Android.mk create mode 100644 ReactCommon/runtimeexecutor/BUCK create mode 100644 ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec rename ReactCommon/{utils => runtimeexecutor/ReactCommon}/RuntimeExecutor.h (93%) create mode 100644 ReactCommon/utils/RunLoopObserver.cpp create mode 100644 ReactCommon/utils/RunLoopObserver.h create mode 100644 packages/react-native-codegen/.babelrc create mode 100644 packages/react-native-codegen/.prettierrc create mode 100644 packages/react-native-codegen/scripts/build.js create mode 100755 scripts/generate-native-modules-specs.sh diff --git a/.ado/templates/apple-job-javascript.yml b/.ado/templates/apple-job-javascript.yml index ccdf9a3ce1f2c8..2568873ba8f318 100644 --- a/.ado/templates/apple-job-javascript.yml +++ b/.ado/templates/apple-job-javascript.yml @@ -12,10 +12,6 @@ steps: slice_name: ${{ parameters.slice_name }} xcode_version: ${{ parameters.xcode_version }} - - template: apple-droid-node-patching.yml - parameters: - apply_office_patches: $(apply_office_patches) - - script: 'yarn install' displayName: 'yarn install' diff --git a/.ado/templates/apple-job-react-native.yml b/.ado/templates/apple-job-react-native.yml index c74069067a08e4..b0ece761841b4f 100644 --- a/.ado/templates/apple-job-react-native.yml +++ b/.ado/templates/apple-job-react-native.yml @@ -24,10 +24,6 @@ steps: slice_name: ${{ parameters.slice_name }} xcode_version: ${{ parameters.xcode_version }} - - template: apple-droid-node-patching.yml - parameters: - apply_office_patches: $(apply_office_patches) - - task: CmdLine@2 displayName: yarn install inputs: diff --git a/.eslintignore b/.eslintignore index 479b10a7655330..a2034a6d58600b 100644 --- a/.eslintignore +++ b/.eslintignore @@ -14,3 +14,4 @@ pr-inactivity-bookmarklet.js question-bookmarklet.js bots/node_modules android-patches/ +packages/react-native-codegen/lib diff --git a/.flowconfig b/.flowconfig index 4f2c3a82108575..4af17e66aefe84 100644 --- a/.flowconfig +++ b/.flowconfig @@ -90,4 +90,4 @@ untyped-import untyped-type-import [version] -^0.123.0 +^0.124.0 diff --git a/.flowconfig.android b/.flowconfig.android index 4094bb40f10b78..db4bff3b3cfbc9 100644 --- a/.flowconfig.android +++ b/.flowconfig.android @@ -93,4 +93,4 @@ untyped-import untyped-type-import [version] -^0.123.0 +^0.124.0 diff --git a/.flowconfig.macos b/.flowconfig.macos index f681b53b53182d..9cf5a7d0dcb5bd 100644 --- a/.flowconfig.macos +++ b/.flowconfig.macos @@ -89,4 +89,4 @@ untyped-import untyped-type-import [version] -^0.123.0 +^0.124.0 diff --git a/.gitignore b/.gitignore index b316422451ca77..4459b963e4d744 100644 --- a/.gitignore +++ b/.gitignore @@ -102,9 +102,14 @@ RNTester/Pods/* !RNTester/Pods/__offline_mirrors # react-native-codegen +/packages/react-native-codegen/lib /ReactCommon/fabric/components/rncore/ +/schema-native-modules.json /schema-rncore.json # Visual studio .vscode .vs + +# Android memory profiler files +*.hprof diff --git a/Libraries/ART/ARTGroup.m b/Libraries/ART/ARTGroup.m index 692d03035bcfcb..8a863f74c2a6c0 100644 --- a/Libraries/ART/ARTGroup.m +++ b/Libraries/ART/ARTGroup.m @@ -11,13 +11,19 @@ @implementation ARTGroup - (void)renderLayerTo:(CGContextRef)context { - if (!CGRectIsEmpty(self.clipping)) { CGContextClipToRect(context, self.clipping); } - for (ARTNode *node in self.subviews) { - [node renderTo:context]; + for (RCTPlatformView *subview in self.subviews) { // TODO(macOS GH#774) + if ([subview respondsToSelector:@selector(renderTo:)]) { + [(ARTNode *)subview renderTo:context]; + } else { + // This is needed for legacy interop layer. Legacy interop layer + // is superview of the view that it is bridging, that's why we need + // to grab its first subview. + [(ARTNode *)subview.subviews.firstObject renderTo:context]; + } } } diff --git a/Libraries/ART/ARTNode.m b/Libraries/ART/ARTNode.m index f94e87c8e9c85c..9b96d16bcc1938 100644 --- a/Libraries/ART/ARTNode.m +++ b/Libraries/ART/ARTNode.m @@ -43,8 +43,10 @@ - (void)setTransform:(CGAffineTransform)transform - (void)invalidate { - id container = (id)self.superview; - [container invalidate]; + if ([self.superview respondsToSelector:@selector(invalidate)]) { + id container = (id)self.superview; + [container invalidate]; + } } - (void)renderTo:(CGContextRef)context diff --git a/Libraries/ART/ARTSurfaceView.m b/Libraries/ART/ARTSurfaceView.m index 2e557b948103fa..92c8836b57ceb0 100644 --- a/Libraries/ART/ARTSurfaceView.m +++ b/Libraries/ART/ARTSurfaceView.m @@ -49,8 +49,15 @@ - (void)drawRect:(CGRect)rect { [super drawRect:rect]; CGContextRef context = UIGraphicsGetCurrentContext(); - for (ARTNode *node in self.subviews) { - [node renderTo:context]; + for (RCTPlatformView *subview in self.subviews) { + if ([subview respondsToSelector:@selector(renderTo:)]) { + [(ARTNode *)subview renderTo:context]; + } else { + // This is needed for legacy interop layer. Legacy interop layer + // is superview of the view that it is bridging, that's why we need + // to grab its first subview. + [(ARTNode *)subview.subviews.firstObject renderTo:context]; + } } } diff --git a/Libraries/Animated/src/Animated.js b/Libraries/Animated/src/Animated.js index 450fc1c0264f13..0891d75a3f3649 100644 --- a/Libraries/Animated/src/Animated.js +++ b/Libraries/Animated/src/Animated.js @@ -11,38 +11,37 @@ 'use strict'; import Platform from '../../Utilities/Platform'; -const View = require('../../Components/View/View'); -const React = require('react'); -import type {AnimatedComponentType} from './createAnimatedComponent'; +import typeof AnimatedFlatList from './components/AnimatedFlatList'; +import typeof AnimatedImage from './components/AnimatedImage'; +import typeof AnimatedScrollView from './components/AnimatedScrollView'; +import typeof AnimatedSectionList from './components/AnimatedSectionList'; +import typeof AnimatedText from './components/AnimatedText'; +import typeof AnimatedView from './components/AnimatedView'; const AnimatedMock = require('./AnimatedMock'); const AnimatedImplementation = require('./AnimatedImplementation'); -//TODO(T57411659): Remove the bridgeless check when Animated perf regressions are fixed. -const Animated = ((Platform.isTesting || global.RN$Bridgeless +const Animated = ((Platform.isTesting ? AnimatedMock : AnimatedImplementation): typeof AnimatedMock); module.exports = { - get FlatList(): any { + get FlatList(): AnimatedFlatList { return require('./components/AnimatedFlatList'); }, - get Image(): any { + get Image(): AnimatedImage { return require('./components/AnimatedImage'); }, - get ScrollView(): any { + get ScrollView(): AnimatedScrollView { return require('./components/AnimatedScrollView'); }, - get SectionList(): any { + get SectionList(): AnimatedSectionList { return require('./components/AnimatedSectionList'); }, - get Text(): any { + get Text(): AnimatedText { return require('./components/AnimatedText'); }, - get View(): AnimatedComponentType< - React.ElementConfig, - React.ElementRef, - > { + get View(): AnimatedView { return require('./components/AnimatedView'); }, ...Animated, diff --git a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js index b569ae2bea5515..99e5d92c051e17 100644 --- a/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js +++ b/Libraries/Components/DatePicker/RCTDatePickerNativeComponent.js @@ -56,5 +56,5 @@ export const Commands: NativeCommands = codegenNativeCommands({ export default (codegenNativeComponent('DatePicker', { paperComponentName: 'RCTDatePicker', - excludedPlatform: 'android', + excludedPlatforms: ['android'], }): HostComponent); diff --git a/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js b/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js index adf8ba966db1bf..7f97db35b6120f 100644 --- a/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js +++ b/Libraries/Components/RefreshControl/PullToRefreshViewNativeComponent.js @@ -61,5 +61,5 @@ export const Commands: NativeCommands = codegenNativeCommands({ export default (codegenNativeComponent('PullToRefreshView', { paperComponentName: 'RCTRefreshControl', - excludedPlatform: 'android', + excludedPlatforms: ['android'], }): HostComponent); diff --git a/Libraries/Components/Switch/SwitchNativeComponent.js b/Libraries/Components/Switch/SwitchNativeComponent.js index 89f757b87db64b..06c89a9a7bae1b 100644 --- a/Libraries/Components/Switch/SwitchNativeComponent.js +++ b/Libraries/Components/Switch/SwitchNativeComponent.js @@ -55,5 +55,5 @@ export const Commands: NativeCommands = codegenNativeCommands({ export default (codegenNativeComponent('Switch', { paperComponentName: 'RCTSwitch', - excludedPlatform: 'android', + excludedPlatforms: ['android'], }): ComponentType); diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 874046ba7f27e4..dd82eaf0a7027f 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -1092,6 +1092,10 @@ function InternalTextInput(props: Props): React.Node { // This is a hack to let Flow know we want an exact object |} = {...null}; + // The default value for `blurOnSubmit` is true for single-line fields and + // false for multi-line fields. + const blurOnSubmit = props.blurOnSubmit ?? !props.multiline; + if ( Platform.OS === 'ios' || Platform.OS === 'macos' /* TODO(macOS GH#774) */ @@ -1111,6 +1115,7 @@ function InternalTextInput(props: Props): React.Node { 0 || t > 0 || w > 0 || h > 0 || globalX > 0 || globalY > 0)) { return; } this.state.touchable.positionOnActivate && diff --git a/Libraries/Components/Touchable/TouchableBounce.js b/Libraries/Components/Touchable/TouchableBounce.js index d2365d977e3dc8..ab76580a76f912 100644 --- a/Libraries/Components/Touchable/TouchableBounce.js +++ b/Libraries/Components/Touchable/TouchableBounce.js @@ -246,4 +246,4 @@ class TouchableBounce extends React.Component { module.exports = (React.forwardRef((props, hostRef) => ( -)): React.ComponentType<$ReadOnly<$Diff>>); +)): React.AbstractComponent<$ReadOnly<$Diff>>); diff --git a/Libraries/Components/Touchable/TouchableHighlight.js b/Libraries/Components/Touchable/TouchableHighlight.js index f4c85089a0904d..71a21f7045de6f 100644 --- a/Libraries/Components/Touchable/TouchableHighlight.js +++ b/Libraries/Components/Touchable/TouchableHighlight.js @@ -413,4 +413,4 @@ class TouchableHighlight extends React.Component { module.exports = (React.forwardRef((props, hostRef) => ( -)): React.ComponentType<$ReadOnly<$Diff>>); +)): React.AbstractComponent<$ReadOnly<$Diff>>); diff --git a/Libraries/Components/Touchable/TouchableOpacity.js b/Libraries/Components/Touchable/TouchableOpacity.js index 98aadf8d225516..44d5ff2cc9dd44 100644 --- a/Libraries/Components/Touchable/TouchableOpacity.js +++ b/Libraries/Components/Touchable/TouchableOpacity.js @@ -359,4 +359,4 @@ class TouchableOpacity extends React.Component { module.exports = (React.forwardRef((props, hostRef) => ( -)): React.ComponentType<$ReadOnly<$Diff>>); +)): React.AbstractComponent<$ReadOnly<$Diff>>); diff --git a/Libraries/Image/NativeImageEditor.js b/Libraries/Image/NativeImageEditor.js new file mode 100644 index 00000000000000..ff334b897771a2 --- /dev/null +++ b/Libraries/Image/NativeImageEditor.js @@ -0,0 +1,51 @@ +/** + * (c) Facebook, Inc. and its affiliates. Confidential and proprietary. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {TurboModule} from '../TurboModule/RCTExport'; +import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; + +type Options = {| + +offset: {| + +x: number, + +y: number, + |}, + +size: {| + +width: number, + +height: number, + |}, + +displaySize?: ?{| + +width: number, + +height: number, + |}, + /** + * Enum with potential values: + * - cover + * - contain + * - stretch + * - center + * - repeat + */ + +resizeMode?: ?string, + +allowExternalStorage?: boolean, +|}; + +export interface Spec extends TurboModule { + +getConstants: () => {||}; + +cropImage: ( + uri: string, + // eslint-disable-next-line lint/react-native-modules + cropData: Options, + successCallback: (uri: string) => void, + errorCallback: (error: string) => void, + ) => void; +} + +export default (TurboModuleRegistry.getEnforcing( + 'ImageEditingManager', +): Spec); diff --git a/Libraries/Image/NativeImageStore.js b/Libraries/Image/NativeImageStore.js new file mode 100644 index 00000000000000..196b328f7464e6 --- /dev/null +++ b/Libraries/Image/NativeImageStore.js @@ -0,0 +1,41 @@ +/** + * (c) Facebook, Inc. and its affiliates. Confidential and proprietary. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {TurboModule} from '../TurboModule/RCTExport'; +import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; + +export interface Spec extends TurboModule { + +getConstants: () => {||}; + // Common + +getBase64ForTag: ( + uri: string, + successCallback: (base64ImageData: string) => void, + + /** + * On Android, the failure callback is called with a string. + * On iOS, the failure callback is called with an error object. + * + * TODO(T47527939) Unify this inconsistency + */ + errorCallback: (error: {|message: string|} | string) => void, + ) => void; + + // iOS-only + +hasImageForTag: (uri: string, callback: (hasImage: boolean) => void) => void; + +removeImageForTag: (uri: string) => void; + +addImageFromBase64: ( + base64ImageData: string, + successCallback: (uri: string) => void, + errorCallback: (error: {|message: string|}) => void, + ) => void; +} + +export default (TurboModuleRegistry.getEnforcing( + 'ImageStoreManager', +): Spec); diff --git a/Libraries/Image/RCTImageLoader.mm b/Libraries/Image/RCTImageLoader.mm index ecde0c638fd44e..88ed783c52c1e7 100644 --- a/Libraries/Image/RCTImageLoader.mm +++ b/Libraries/Image/RCTImageLoader.mm @@ -635,7 +635,7 @@ - (RCTImageURLLoaderRequest *)_loadImageOrDataWithURLRequest:(NSURLRequest *)req } } }); - + return [[RCTImageURLLoaderRequest alloc] initWithRequestId:requestId imageURL:request.URL cancellationBlock:^{ BOOL alreadyCancelled = atomic_fetch_or(cancelled.get(), 1); if (alreadyCancelled) { @@ -856,6 +856,7 @@ - (void)trackURLImageContentDidSetForRequest:(RCTImageURLLoaderRequest *)loaderR return; } + // This delegate method is Fabric-only id loadHandler = [self imageURLLoaderForURL:loaderRequest.imageURL]; if ([loadHandler respondsToSelector:@selector(trackURLImageContentDidSetForRequest:)]) { [(id)loadHandler trackURLImageContentDidSetForRequest:loaderRequest]; @@ -879,6 +880,7 @@ - (void)trackURLImageDidDestroy:(RCTImageURLLoaderRequest *)loaderRequest if (!loaderRequest) { return; } + id loadHandler = [self imageURLLoaderForURL:loaderRequest.imageURL]; if ([loadHandler respondsToSelector:@selector(trackURLImageDidDestroy:)]) { [(id)loadHandler trackURLImageDidDestroy:loaderRequest]; diff --git a/Libraries/Image/RCTImageView.mm b/Libraries/Image/RCTImageView.mm index 3f5fc18b310479..e41c45cc10cbb4 100644 --- a/Libraries/Image/RCTImageView.mm +++ b/Libraries/Image/RCTImageView.mm @@ -114,6 +114,9 @@ @implementation RCTImageView // Weak reference back to the bridge, for image loading __weak RCTBridge *_bridge; + // Weak reference back to the active image loader. + __weak id _imageLoader; + // The image source that's currently displayed RCTImageSource *_imageSource; @@ -123,9 +126,6 @@ @implementation RCTImageView // Size of the image loaded / being loaded, so we can determine when to issue a reload to accommodate a changing size. CGSize _targetSize; - // A block that can be invoked to cancel the most recent call to -reloadImage, if any - RCTImageLoaderCancellationBlock _reloadImageCancellationBlock; - // Whether the latest change of props requires the image to be reloaded BOOL _needsReload; @@ -135,6 +135,8 @@ @implementation RCTImageView // Whether observing changes to the window's backing scale BOOL _subscribedToWindowBackingNotifications; #endif // [TODO(macOS GH#774) + + RCTImageURLLoaderRequest *_loaderRequest; } - (instancetype)initWithBridge:(RCTBridge *)bridge @@ -317,12 +319,11 @@ - (void)setResizeMode:(RCTResizeMode)resizeMode - (void)cancelImageLoad { - RCTImageLoaderCancellationBlock previousCancellationBlock = _reloadImageCancellationBlock; - if (previousCancellationBlock) { - previousCancellationBlock(); - _reloadImageCancellationBlock = nil; + if (_loaderRequest.cancellationBlock) { + _loaderRequest.cancellationBlock(); } + _loaderRequest = nil; _pendingImageSource = nil; } @@ -440,11 +441,13 @@ - (void)reloadImage [weakSelf imageLoaderLoadedImage:loadedImage error:error forImageSource:source partial:NO]; }; - id imageLoader = [_bridge moduleForName:@"ImageLoader" - lazilyLoadIfNecessary:YES]; - RCTImageURLLoaderRequest *loaderRequest = [imageLoader loadImageWithURLRequest:source.request - size:imageSize - scale:imageScale + if (!_imageLoader) { + _imageLoader = [_bridge moduleForName:@"ImageLoader" lazilyLoadIfNecessary:YES]; + } + + RCTImageURLLoaderRequest *loaderRequest = [_imageLoader loadImageWithURLRequest:source.request + size:imageSize + scale:imageScale clipped:NO resizeMode:_resizeMode priority:RCTImageLoaderPriorityImmediate @@ -455,7 +458,7 @@ - (void)reloadImage progressBlock:progressHandler partialLoadBlock:partialLoadHandler completionBlock:completionHandler]; - _reloadImageCancellationBlock = loaderRequest.cancellationBlock; + _loaderRequest = loaderRequest; } else { [self clearImage]; } @@ -653,4 +656,9 @@ - (void)setTintColor:(NSColor *)tintColor } } #endif // ]TODO(macOS GH#774) + +- (void)dealloc { + [_imageLoader trackURLImageDidDestroy:_loaderRequest]; +} + @end diff --git a/Libraries/Image/RCTUIImageViewAnimated.m b/Libraries/Image/RCTUIImageViewAnimated.m index ade3659a0fcd58..40661daf6531b7 100644 --- a/Libraries/Image/RCTUIImageViewAnimated.m +++ b/Libraries/Image/RCTUIImageViewAnimated.m @@ -187,9 +187,18 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink { #if TARGET_OS_UIKITFORMAC // TODO: `displayLink.frameInterval` is not available on UIKitForMac - NSTimeInterval duration = displayLink.duration; + NSTimeInterval durationToNextRefresh = displayLink.duration; #else - NSTimeInterval duration = displayLink.duration * displayLink.preferredFramesPerSecond; + // displaylink.duration -- time interval between frames, assuming maximumFramesPerSecond + // displayLink.preferredFramesPerSecond (>= iOS 10) -- Set to 30 for displayDidRefresh to be called at 30 fps + // displayLink.frameInterval (< iOS 10) -- # of frames that must pass before each displayDidRefresh. After iOS 10, when this is set to 2, preferredFramesPerSecond becomes 30 fps. + // durationToNextRefresh -- Time interval to the next time displayDidRefresh is called + NSTimeInterval durationToNextRefresh; + if (@available(iOS 10.0, *)) { + durationToNextRefresh = displayLink.targetTimestamp - displayLink.timestamp; + } else { + durationToNextRefresh = displayLink.duration * displayLink.frameInterval; + } #endif NSUInteger totalFrameCount = self.totalFrameCount; NSUInteger currentFrameIndex = self.currentFrameIndex; @@ -197,13 +206,14 @@ - (void)displayDidRefresh:(CADisplayLink *)displayLink // Check if we have the frame buffer firstly to improve performance if (!self.bufferMiss) { // Then check if timestamp is reached - self.currentTime += duration; + self.currentTime += durationToNextRefresh; NSTimeInterval currentDuration = [self.animatedImage animatedImageDurationAtIndex:currentFrameIndex]; if (self.currentTime < currentDuration) { // Current frame timestamp not reached, return return; } self.currentTime -= currentDuration; + // nextDuration - duration to wait before displaying next image NSTimeInterval nextDuration = [self.animatedImage animatedImageDurationAtIndex:nextFrameIndex]; if (self.currentTime > nextDuration) { // Do not skip frame diff --git a/Libraries/LayoutAnimation/LayoutAnimation.js b/Libraries/LayoutAnimation/LayoutAnimation.js index ba4632eb712404..159b2b96c785ad 100644 --- a/Libraries/LayoutAnimation/LayoutAnimation.js +++ b/Libraries/LayoutAnimation/LayoutAnimation.js @@ -11,52 +11,45 @@ 'use strict'; const UIManager = require('../ReactNative/UIManager'); +import type {Spec as FabricUIManagerSpec} from '../ReactNative/FabricUIManager'; +import type { + LayoutAnimationConfig as LayoutAnimationConfig_, + LayoutAnimationType, + LayoutAnimationProperty, +} from '../Renderer/shims/ReactNativeTypes'; import Platform from '../Utilities/Platform'; -type Type = - | 'spring' - | 'linear' - | 'easeInEaseOut' - | 'easeIn' - | 'easeOut' - | 'keyboard'; - -type Property = 'opacity' | 'scaleX' | 'scaleY' | 'scaleXY'; - -type AnimationConfig = $ReadOnly<{| - duration?: number, - delay?: number, - springDamping?: number, - initialVelocity?: number, - type?: Type, - property?: Property, -|}>; - -export type LayoutAnimationConfig = $ReadOnly<{| - duration: number, - create?: AnimationConfig, - update?: AnimationConfig, - delete?: AnimationConfig, -|}>; +// Reexport type +export type LayoutAnimationConfig = LayoutAnimationConfig_; function configureNext( config: LayoutAnimationConfig, onAnimationDidEnd?: Function, ) { if (!Platform.isTesting) { - UIManager.configureNextLayoutAnimation( - config, - onAnimationDidEnd ?? function() {}, - function() {} /* unused onError */, - ); + if (UIManager?.configureNextLayoutAnimation) { + UIManager.configureNextLayoutAnimation( + config, + onAnimationDidEnd ?? function() {}, + function() {} /* unused onError */, + ); + } + const FabricUIManager: FabricUIManagerSpec = global?.nativeFabricUIManager; + if (FabricUIManager?.configureNextLayoutAnimation) { + global?.nativeFabricUIManager?.configureNextLayoutAnimation( + config, + onAnimationDidEnd ?? function() {}, + function() {} /* unused onError */, + ); + } } } function create( duration: number, - type: Type, - property: Property, + type: LayoutAnimationType, + property: LayoutAnimationProperty, ): LayoutAnimationConfig { return { duration, diff --git a/Libraries/Lists/VirtualizedList.js b/Libraries/Lists/VirtualizedList.js index 84228d4dcece4d..dcc524da53ca06 100644 --- a/Libraries/Lists/VirtualizedList.js +++ b/Libraries/Lists/VirtualizedList.js @@ -13,8 +13,6 @@ const Batchinator = require('../Interaction/Batchinator'); const FillRateHelper = require('./FillRateHelper'); const Platform = require('../Utilities/Platform'); // TODO(macOS GH#774) -const PropTypes = require('prop-types'); -const React = require('react'); const ReactNative = require('../Renderer/shims/ReactNative'); const RefreshControl = require('../Components/RefreshControl/RefreshControl'); const ScrollView = require('../Components/ScrollView/ScrollView'); @@ -29,6 +27,7 @@ const warning = require('fbjs/lib/warning'); const {computeWindowedRenderLimits} = require('./VirtualizeUtils'); +import * as React from 'react'; import type {ScrollResponderType} from '../Components/ScrollView/ScrollView'; import type {ViewStyleProp} from '../StyleSheet/StyleSheet'; import type { @@ -37,6 +36,13 @@ import type { ViewabilityConfigCallbackPair, } from './ViewabilityHelper'; import type {ScrollEvent} from '../Types/CoreEventTypes'; // TODO(macOS GH#774) +import { + VirtualizedListCellContextProvider, + VirtualizedListContext, + VirtualizedListContextProvider, + type ChildListState, + type ListDebugInfo, +} from './VirtualizedListContext.js'; type Item = any; @@ -351,21 +357,6 @@ type DefaultProps = {| let _usedIndexForKey = false; let _keylessItemComponentName: string = ''; -type Frame = { - offset: number, - length: number, - index: number, - inLayout: boolean, - ... -}; - -type ChildListState = { - first: number, - last: number, - frames: {[key: number]: Frame, ...}, - ... -}; - type State = { first: number, last: number, @@ -373,18 +364,6 @@ type State = { ... }; -// Data propagated through nested lists (regardless of orientation) that is -// useful for producing diagnostics for usage errors involving nesting (e.g -// missing/duplicate keys). -type ListDebugInfo = { - cellKey: string, - listKey: string, - parent: ?ListDebugInfo, - // We include all ancestors regardless of orientation, so this is not always - // identical to the child's orientation. - horizontal: boolean, -}; - /** * Base implementation for the more convenient [``](https://reactnative.dev/docs/flatlist.html) * and [``](https://reactnative.dev/docs/sectionlist.html) components, which are also better @@ -414,7 +393,7 @@ type ListDebugInfo = { * */ class VirtualizedList extends React.PureComponent { - props: Props; + static contextType: typeof VirtualizedListContext = VirtualizedListContext; // scrollToEnd may be janky without getItemLayout prop scrollToEnd(params?: ?{animated?: ?boolean, ...}) { @@ -464,8 +443,18 @@ class VirtualizedList extends React.PureComponent { } = this.props; const {animated, index, viewOffset, viewPosition} = params; invariant( - index >= 0 && index < getItemCount(data), - `scrollToIndex out of range: requested index ${index} but maximum is ${getItemCount( + index >= 0, + `scrollToIndex out of range: requested index ${index} but minimum is 0`, + ); + invariant( + getItemCount(data) >= 1, + `scrollToIndex out of range: item length ${getItemCount( + data, + )} but minimum is 1`, + ); + invariant( + index < getItemCount(data), + `scrollToIndex out of range: requested index ${index} is out of 0 to ${getItemCount( data, ) - 1}`, ); @@ -655,111 +644,8 @@ class VirtualizedList extends React.PureComponent { windowSize: 21, // multiples of length }; - static contextTypes: - | any - | {| - virtualizedCell: {| - cellKey: React$PropType$Primitive, - |}, - virtualizedList: {| - getScrollMetrics: React$PropType$Primitive, - horizontal: React$PropType$Primitive, - getOutermostParentListRef: React$PropType$Primitive, - getNestedChildState: React$PropType$Primitive, - registerAsNestedChild: React$PropType$Primitive, - unregisterAsNestedChild: React$PropType$Primitive, - debugInfo: {| - listKey: React$PropType$Primitive, - cellKey: React$PropType$Primitive, - |}, - |}, - |} = { - virtualizedCell: PropTypes.shape({ - cellKey: PropTypes.string, - }), - virtualizedList: PropTypes.shape({ - getScrollMetrics: PropTypes.func, - horizontal: PropTypes.bool, - getOutermostParentListRef: PropTypes.func, - getNestedChildState: PropTypes.func, - registerAsNestedChild: PropTypes.func, - unregisterAsNestedChild: PropTypes.func, - debugInfo: PropTypes.shape({ - listKey: PropTypes.string, - cellKey: PropTypes.string, - }), - }), - }; - - static childContextTypes: - | any - | {| - getScrollMetrics: React$PropType$Primitive, - horizontal: React$PropType$Primitive, - getOutermostParentListRef: React$PropType$Primitive, - getNestedChildState: React$PropType$Primitive, - registerAsNestedChild: React$PropType$Primitive, - unregisterAsNestedChild: React$PropType$Primitive, - |} = { - virtualizedList: PropTypes.shape({ - getScrollMetrics: PropTypes.func, - horizontal: PropTypes.bool, - getOutermostParentListRef: PropTypes.func, - getNestedChildState: PropTypes.func, - registerAsNestedChild: PropTypes.func, - unregisterAsNestedChild: PropTypes.func, - }), - }; - - getChildContext(): {| - virtualizedList: { - getScrollMetrics: () => { - contentLength: number, - dOffset: number, - dt: number, - offset: number, - timestamp: number, - velocity: number, - visibleLength: number, - ... - }, - horizontal: ?boolean, - getOutermostParentListRef: Function, - getNestedChildState: string => ?ChildListState, - registerAsNestedChild: ({ - cellKey: string, - key: string, - ref: VirtualizedList, - parentDebugInfo: ListDebugInfo, - ... - }) => ?ChildListState, - unregisterAsNestedChild: ({ - key: string, - state: ChildListState, - ... - }) => void, - debugInfo: ListDebugInfo, - ... - }, - |} { - return { - virtualizedList: { - getScrollMetrics: this._getScrollMetrics, - horizontal: this.props.horizontal, - getOutermostParentListRef: this._getOutermostParentListRef, - getNestedChildState: this._getNestedChildState, - registerAsNestedChild: this._registerAsNestedChild, - unregisterAsNestedChild: this._unregisterAsNestedChild, - debugInfo: this._getDebugInfo(), - }, - }; - } - _getCellKey(): string { - return ( - (this.context.virtualizedCell && this.context.virtualizedCell.cellKey) || - 'rootList' - ); + return this.context?.cellKey || 'rootList'; } _getListKey(): string { @@ -771,9 +657,7 @@ class VirtualizedList extends React.PureComponent { listKey: this._getListKey(), cellKey: this._getCellKey(), horizontal: !!this.props.horizontal, - parent: this.context.virtualizedList - ? this.context.virtualizedList.debugInfo - : null, + parent: this.context?.debugInfo, }; } @@ -787,7 +671,7 @@ class VirtualizedList extends React.PureComponent { _getOutermostParentListRef = () => { if (this._isNestedWithSameOrientation()) { - return this.context.virtualizedList.getOutermostParentListRef(); + return this.context.getOutermostParentListRef(); } else { return this; } @@ -847,8 +731,8 @@ class VirtualizedList extends React.PureComponent { state: State; - constructor(props: Props, context: Object) { - super(props, context); + constructor(props: Props) { + super(props); invariant( // $FlowFixMe !props.onScroll || !props.onScroll.__isNative, @@ -892,9 +776,7 @@ class VirtualizedList extends React.PureComponent { }; if (this._isNestedWithSameOrientation()) { - const storedState = this.context.virtualizedList.getNestedChildState( - this._getListKey(), - ); + const storedState = this.context.getNestedChildState(this._getListKey()); if (storedState) { initialState = storedState; this.state = storedState; @@ -907,7 +789,7 @@ class VirtualizedList extends React.PureComponent { componentDidMount() { if (this._isNestedWithSameOrientation()) { - this.context.virtualizedList.registerAsNestedChild({ + this.context.registerAsNestedChild({ cellKey: this._getCellKey(), key: this._getListKey(), ref: this, @@ -915,14 +797,14 @@ class VirtualizedList extends React.PureComponent { // the parent's props. This is why we explicitly propagate debugInfo // "down" via context and "up" again via this method call on the // parent. - parentDebugInfo: this.context.virtualizedList.debugInfo, + parentDebugInfo: this.context.debugInfo, }); } } componentWillUnmount() { if (this._isNestedWithSameOrientation()) { - this.context.virtualizedList.unregisterAsNestedChild({ + this.context.unregisterAsNestedChild({ key: this._getListKey(), state: { first: this.state.first, @@ -1022,7 +904,7 @@ class VirtualizedList extends React.PureComponent { } _isNestedWithSameOrientation(): boolean { - const nestedContext = this.context.virtualizedList; + const nestedContext = this.context; return !!( nestedContext && !!nestedContext.horizontal === !!this.props.horizontal ); @@ -1063,7 +945,7 @@ class VirtualizedList extends React.PureComponent { ); cells.push( - { element } - , + , ); } const itemCount = this.props.getItemCount(data); @@ -1218,7 +1100,7 @@ class VirtualizedList extends React.PureComponent { ); cells.push( - { element } - , + , ); } const scrollProps = { @@ -1257,14 +1139,29 @@ class VirtualizedList extends React.PureComponent { this._hasMore = this.state.last < this.props.getItemCount(this.props.data) - 1; - const innerRet = React.cloneElement( - (this.props.renderScrollComponent || this._defaultRenderScrollComponent)( - scrollProps, - ), - { - ref: this._captureScrollRef, - }, - cells, + const innerRet = ( + + {React.cloneElement( + ( + this.props.renderScrollComponent || + this._defaultRenderScrollComponent + )(scrollProps), + { + ref: this._captureScrollRef, + }, + cells, + )} + ); let ret = innerRet; if (__DEV__) { @@ -1275,7 +1172,7 @@ class VirtualizedList extends React.PureComponent { scrollContext != null && !scrollContext.horizontal === !this.props.horizontal && !this._hasWarned.nesting && - this.context.virtualizedList == null + this.context == null ) { // TODO (T46547044): use React.warn once 16.9 is sync'd: https://github.com/facebook/react/pull/15170 console.warn( @@ -1499,7 +1396,7 @@ class VirtualizedList extends React.PureComponent { // We are assuming that getOutermostParentListRef().getScrollRef() // is a non-null reference to a ScrollView this._scrollRef.measureLayout( - this.context.virtualizedList.getOutermostParentListRef().getScrollRef(), + this.context.getOutermostParentListRef().getScrollRef(), (x, y, width, height) => { this._offsetFromParentVirtualizedList = this._selectOffset({x, y}); this._scrollMetrics.contentLength = this._selectLength({ @@ -1507,7 +1404,7 @@ class VirtualizedList extends React.PureComponent { height, }); const scrollMetrics = this._convertParentScrollMetrics( - this.context.virtualizedList.getScrollMetrics(), + this.context.getScrollMetrics(), ); this._scrollMetrics.visibleLength = scrollMetrics.visibleLength; this._scrollMetrics.offset = scrollMetrics.offset; @@ -2077,19 +1974,6 @@ class VirtualizedList extends React.PureComponent { if (!frame || frame.index !== index) { if (getItemLayout) { frame = getItemLayout(data, index); - if (__DEV__) { - const frameType = PropTypes.shape({ - length: PropTypes.number.isRequired, - offset: PropTypes.number.isRequired, - index: PropTypes.number.isRequired, - }).isRequired; - PropTypes.checkPropTypes( - {frame: frameType}, - {frame}, - 'frame', - 'VirtualizedList.getItemLayout', - ); - } } } /* $FlowFixMe(>=0.63.0 site=react_native_fb) This comment suppresses an @@ -2167,12 +2051,6 @@ class CellRenderer extends React.Component< }, }; - static childContextTypes = { - virtualizedCell: PropTypes.shape({ - cellKey: PropTypes.string, - }), - }; - static getDerivedStateFromProps( props: CellRendererProps, prevState: CellRendererState, @@ -2185,14 +2063,6 @@ class CellRenderer extends React.Component< }; } - getChildContext() { - return { - virtualizedCell: { - cellKey: this.props.cellKey, - }, - }; - } - // TODO: consider factoring separator stuff out of VirtualizedList into FlatList since it's not // reused by SectionList and we can keep VirtualizedList simpler. _separators = { @@ -2307,18 +2177,15 @@ class CellRenderer extends React.Component< : horizontal ? [styles.row, inversionStyle] : inversionStyle; - if (!CellRendererComponent) { - return ( - /* $FlowFixMe(>=0.89.0 site=react_native_fb) This comment suppresses an - * error found when Flow v0.89 was deployed. To see the error, delete - * this comment and run Flow. */ - - {element} - {itemSeparator} - - ); - } - return ( + const result = !CellRendererComponent ? ( + /* $FlowFixMe(>=0.89.0 site=react_native_fb) This comment suppresses an + * error found when Flow v0.89 was deployed. To see the error, delete + * this comment and run Flow. */ + + {element} + {itemSeparator} + + ) : ( ); - } -} - -class VirtualizedCellWrapper extends React.Component<{ - cellKey: string, - children: React.Node, - ... -}> { - static childContextTypes = { - virtualizedCell: PropTypes.shape({ - cellKey: PropTypes.string, - }), - }; - getChildContext() { - return { - virtualizedCell: { - cellKey: this.props.cellKey, - }, - }; - } - - render() { - return this.props.children; + return ( + + {result} + + ); } } diff --git a/Libraries/Lists/VirtualizedListContext.js b/Libraries/Lists/VirtualizedListContext.js new file mode 100644 index 00000000000000..130315a1b08d57 --- /dev/null +++ b/Libraries/Lists/VirtualizedListContext.js @@ -0,0 +1,152 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type VirtualizedList from './VirtualizedList.js'; +import * as React from 'react'; +import {useMemo, useContext} from 'react'; + +type Frame = $ReadOnly<{ + offset: number, + length: number, + index: number, + inLayout: boolean, +}>; + +export type ChildListState = $ReadOnly<{ + first: number, + last: number, + frames: {[key: number]: Frame}, +}>; + +// Data propagated through nested lists (regardless of orientation) that is +// useful for producing diagnostics for usage errors involving nesting (e.g +// missing/duplicate keys). +export type ListDebugInfo = $ReadOnly<{ + cellKey: string, + listKey: string, + parent: ?ListDebugInfo, + // We include all ancestors regardless of orientation, so this is not always + // identical to the child's orientation. + horizontal: boolean, +}>; + +type Context = $ReadOnly<{ + cellKey: ?string, + getScrollMetrics: () => { + contentLength: number, + dOffset: number, + dt: number, + offset: number, + timestamp: number, + velocity: number, + visibleLength: number, + }, + horizontal: ?boolean, + getOutermostParentListRef: () => VirtualizedList, + getNestedChildState: string => ?ChildListState, + registerAsNestedChild: ({ + cellKey: string, + key: string, + ref: VirtualizedList, + parentDebugInfo: ListDebugInfo, + }) => ?ChildListState, + unregisterAsNestedChild: ({ + key: string, + state: ChildListState, + }) => void, + debugInfo: ListDebugInfo, +}>; + +export const VirtualizedListContext: React.Context = React.createContext( + null, +); + +/** + * Resets the context. Intended for use by portal-like components (e.g. Modal). + */ +export function VirtualizedListContextResetter({ + children, +}: { + children: React.Node, +}): React.Node { + return ( + + {children} + + ); +} + +/** + * Sets the context with memoization. Intended to be used by `VirtualizedList`. + */ +export function VirtualizedListContextProvider({ + children, + value, +}: { + children: React.Node, + value: Context, +}): React.Node { + // Avoid setting a newly created context object if the values are identical. + const context = useMemo( + () => ({ + cellKey: null, + getScrollMetrics: value.getScrollMetrics, + horizontal: value.horizontal, + getOutermostParentListRef: value.getOutermostParentListRef, + getNestedChildState: value.getNestedChildState, + registerAsNestedChild: value.registerAsNestedChild, + unregisterAsNestedChild: value.unregisterAsNestedChild, + debugInfo: { + cellKey: value.debugInfo.cellKey, + horizontal: value.debugInfo.horizontal, + listKey: value.debugInfo.listKey, + parent: value.debugInfo.parent, + }, + }), + [ + value.getScrollMetrics, + value.horizontal, + value.getOutermostParentListRef, + value.getNestedChildState, + value.registerAsNestedChild, + value.unregisterAsNestedChild, + value.debugInfo.cellKey, + value.debugInfo.horizontal, + value.debugInfo.listKey, + value.debugInfo.parent, + ], + ); + return ( + + {children} + + ); +} + +/** + * Sets the `cellKey`. Intended to be used by `VirtualizedList` for each cell. + */ +export function VirtualizedListCellContextProvider({ + cellKey, + children, +}: { + cellKey: string, + children: React.Node, +}): React.Node { + const context = useContext(VirtualizedListContext); + return ( + + {children} + + ); +} diff --git a/Libraries/Lists/__tests__/VirtualizedList-test.js b/Libraries/Lists/__tests__/VirtualizedList-test.js index e99215a2d867d1..271fad276fe55e 100644 --- a/Libraries/Lists/__tests__/VirtualizedList-test.js +++ b/Libraries/Lists/__tests__/VirtualizedList-test.js @@ -456,4 +456,52 @@ describe('VirtualizedList', () => { console.error.mockRestore(); } }); + + it('throws if using scrollToIndex with index less than 0', () => { + const component = ReactTestRenderer.create( + } + getItem={(data, index) => data[index]} + getItemCount={data => data.length} + />, + ); + const instance = component.getInstance(); + + expect(() => instance.scrollToIndex({index: -1})).toThrow( + 'scrollToIndex out of range: requested index -1 but minimum is 0', + ); + }); + + it('throws if using scrollToIndex when item length is less than 1', () => { + const component = ReactTestRenderer.create( + } + getItem={(data, index) => data[index]} + getItemCount={data => data.length} + />, + ); + const instance = component.getInstance(); + + expect(() => instance.scrollToIndex({index: 1})).toThrow( + 'scrollToIndex out of range: item length 0 but minimum is 1', + ); + }); + + it('throws if using scrollToIndex when requested index is bigger than or equal to item length', () => { + const component = ReactTestRenderer.create( + } + getItem={(data, index) => data[index]} + getItemCount={data => data.length} + />, + ); + const instance = component.getInstance(); + + expect(() => instance.scrollToIndex({index: 3})).toThrow( + 'scrollToIndex out of range: requested index 3 is out of 0 to 2', + ); + }); }); diff --git a/Libraries/LogBox/Data/LogBoxData.js b/Libraries/LogBox/Data/LogBoxData.js index 1076d26661f448..9d35132a490f3a 100644 --- a/Libraries/LogBox/Data/LogBoxData.js +++ b/Libraries/LogBox/Data/LogBoxData.js @@ -135,17 +135,15 @@ function handleUpdate(): void { } function appendNewLog(newLog) { - // We don't want to store these logs because they trigger a - // state update whenever we add them to the store, which is - // expensive to noisy logs. If we later want to display these - // we will store them in a different state object. + // Don't want store these logs because they trigger a + // state update when we add them to the store. if (isMessageIgnored(newLog.message.content)) { return; } // If the next log has the same category as the previous one - // then we want to roll it up into the last log in the list - // by incrementing the count (simar to how Chrome does it). + // then roll it up into the last log in the list by incrementing + // the count (similar to how Chrome does it). const lastLog = Array.from(logs).pop(); if (lastLog && lastLog.category === newLog.category) { lastLog.incrementCount(); @@ -161,7 +159,7 @@ function appendNewLog(newLog) { let addPendingLog = () => { logs.add(newLog); - if (_selectedIndex <= 0) { + if (_selectedIndex < 0) { setSelectedLog(logs.size - 1); } else { handleUpdate(); diff --git a/Libraries/LogBox/Data/__tests__/LogBoxData-test.js b/Libraries/LogBox/Data/__tests__/LogBoxData-test.js index bd5e0c99056177..b0dfc3074aa079 100644 --- a/Libraries/LogBox/Data/__tests__/LogBoxData-test.js +++ b/Libraries/LogBox/Data/__tests__/LogBoxData-test.js @@ -275,7 +275,7 @@ describe('LogBoxData', () => { expect(selectedLogIndex()).toBe(-1); }); - it('sets the selectedLogIndex to the last fatal error (after symbolication)', () => { + it('sets the selectedLogIndex to the first fatal error (after symbolication)', () => { addFatalErrors(['A']); // Order maters for symbolication before timeout. @@ -291,10 +291,14 @@ describe('LogBoxData', () => { flushLogs(); jest.runAllTimers(); - expect(selectedLogIndex()).toBe(2); + // This should still be 0 (the first fatal exception) + // becuase it is the most likely source of the error. + // If there are more exceptions after this, they + // are likely caused by this original exception. + expect(selectedLogIndex()).toBe(0); }); - it('sets the selectedLogIndex to the last fatal error (hitting timeout limit)', () => { + it('sets the selectedLogIndex to the first fatal error (hitting timeout limit)', () => { addFatalErrors(['A']); // Order maters for timeout before symbolication. @@ -310,7 +314,11 @@ describe('LogBoxData', () => { jest.runAllTimers(); flushLogs(); - expect(selectedLogIndex()).toBe(2); + // This should still be 0 (the first fatal exception) + // becuase it is the most likely source of the error. + // If there are more exceptions after this, they + // are likely caused by this original exception. + expect(selectedLogIndex()).toBe(0); }); it('sets the selectedLogIndex to the last syntax error', () => { diff --git a/Libraries/LogBox/UI/LogBoxInspector.js b/Libraries/LogBox/UI/LogBoxInspector.js index 9c2983264b04b7..68c591f11e37de 100644 --- a/Libraries/LogBox/UI/LogBoxInspector.js +++ b/Libraries/LogBox/UI/LogBoxInspector.js @@ -87,11 +87,11 @@ function LogBoxInspector(props: Props): React.Node { } const headerTitleMap = { - warn: 'Warning', - error: 'Error', - fatal: 'Exception', + warn: 'Console Warning', + error: 'Console Error', + fatal: 'Uncaught Error', syntax: 'Syntax Error', - component: 'Component Exception', + component: 'Render Error', }; function LogBoxInspectorBody(props) { diff --git a/Libraries/Modal/Modal.js b/Libraries/Modal/Modal.js index 0dfe53ab1db7bf..c25cb8ff986eb3 100644 --- a/Libraries/Modal/Modal.js +++ b/Libraries/Modal/Modal.js @@ -25,6 +25,7 @@ import type {ViewProps} from '../Components/View/ViewPropTypes'; import type {DirectEventHandler} from '../Types/CodegenTypes'; import type EmitterSubscription from '../vendor/emitter/EmitterSubscription'; import RCTModalHostView from './RCTModalHostViewNativeComponent'; +import {VirtualizedListContextResetter} from '../Lists/VirtualizedListContext.js'; const ModalEventEmitter = Platform.OS === 'ios' && NativeModalManager != null @@ -168,20 +169,6 @@ class Modal extends React.Component { this._identifier = uniqueModalIdentifier++; } - static childContextTypes: - | any - | {|virtualizedList: React$PropType$Primitive|} = { - virtualizedList: PropTypes.object, - }; - - getChildContext(): {|virtualizedList: null|} { - // Reset the context so VirtualizedList doesn't get confused by nesting - // in the React tree that doesn't reflect the native component hierarchy. - return { - virtualizedList: null, - }; - } - componentDidMount() { if (ModalEventEmitter) { this._eventSubscription = ModalEventEmitter.addListener( @@ -258,11 +245,15 @@ class Modal extends React.Component { onStartShouldSetResponder={this._shouldSetResponder} supportedOrientations={this.props.supportedOrientations} onOrientationChange={this.props.onOrientationChange}> - - - {innerChildren} - - + + + + {innerChildren} + + + ); } diff --git a/Libraries/Pressability/Pressability.js b/Libraries/Pressability/Pressability.js index ad1259af343380..38ebe26f2a515a 100644 --- a/Libraries/Pressability/Pressability.js +++ b/Libraries/Pressability/Pressability.js @@ -787,7 +787,16 @@ export default class Pressability { } _measureCallback = (left, top, width, height, pageX, pageY) => { - if (!left && !top && !width && !height && !pageX && !pageY) { + if ( + !( + left > 0 || + top > 0 || + width > 0 || + height > 0 || + pageX > 0 || + pageY > 0 + ) + ) { return; } this._responderRegion = { diff --git a/Libraries/ReactNative/AppContainer.js b/Libraries/ReactNative/AppContainer.js index 93c83fba66350b..2c2b0fc157fd94 100644 --- a/Libraries/ReactNative/AppContainer.js +++ b/Libraries/ReactNative/AppContainer.js @@ -24,6 +24,7 @@ type Props = $ReadOnly<{| children?: React.Node, fabric?: boolean, rootTag: number, + initialProps?: {...}, showArchitectureIndicator?: boolean, WrapperComponent?: ?React.ComponentType, internal_excludeLogBox?: ?boolean, @@ -119,6 +120,7 @@ class AppContainer extends React.Component { if (Wrapper != null) { innerView = ( ; type NodeProps = {...}; type InstanceHandle = {...}; -type Spec = {| +export type Spec = {| +createNode: ( reactTag: number, viewName: string, @@ -49,6 +50,13 @@ type Spec = {| onFail: () => void, onSuccess: MeasureLayoutOnSuccessCallback, ) => void, + +configureNextLayoutAnimation: ( + config: LayoutAnimationConfig, + callback: () => void, // check what is returned here + // This error isn't currently called anywhere, so the `error` object is really not defined + // $FlowFixMe + errorCallback: (error: Object) => void, + ) => void, |}; const FabricUIManager: ?Spec = global.nativeFabricUIManager; diff --git a/Libraries/ReactNative/renderApplication.js b/Libraries/ReactNative/renderApplication.js index c5bd0e024cdd85..7d7b3b4409b1f7 100644 --- a/Libraries/ReactNative/renderApplication.js +++ b/Libraries/ReactNative/renderApplication.js @@ -41,6 +41,7 @@ function renderApplication( fabric={fabric} showArchitectureIndicator={showArchitectureIndicator} WrapperComponent={WrapperComponent} + initialProps={initialProps ?? Object.freeze({})} internal_excludeLogBox={isLogBox}> diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index ec68139ab57208..f6b9e3c2b91829 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -213,3 +213,36 @@ export type ReactFaricEvent = { target: number, ... }; + +// +// Imperative LayoutAnimation API types +// +export type LayoutAnimationType = + | 'spring' + | 'linear' + | 'easeInEaseOut' + | 'easeIn' + | 'easeOut' + | 'keyboard'; + +export type LayoutAnimationProperty = + | 'opacity' + | 'scaleX' + | 'scaleY' + | 'scaleXY'; + +export type LayoutAnimationAnimationConfig = $ReadOnly<{| + duration?: number, + delay?: number, + springDamping?: number, + initialVelocity?: number, + type?: LayoutAnimationType, + property?: LayoutAnimationProperty, +|}>; + +export type LayoutAnimationConfig = $ReadOnly<{| + duration: number, + create?: LayoutAnimationAnimationConfig, + update?: LayoutAnimationAnimationConfig, + delete?: LayoutAnimationAnimationConfig, +|}>; diff --git a/Libraries/TimePickerAndroid/NativeTimePickerAndroid.js b/Libraries/TimePickerAndroid/NativeTimePickerAndroid.js new file mode 100644 index 00000000000000..46594ffdc3196e --- /dev/null +++ b/Libraries/TimePickerAndroid/NativeTimePickerAndroid.js @@ -0,0 +1,31 @@ +/** + * (c) Facebook, Inc. and its affiliates. Confidential and proprietary. + * + * @flow strict-local + * @format + */ + +'use strict'; + +import type {TurboModule} from '../TurboModule/RCTExport'; +import * as TurboModuleRegistry from '../TurboModule/TurboModuleRegistry'; + +export type TimePickerOptions = {| + hour?: number, + minute?: number, + is24Hour?: boolean, + mode?: string, +|}; + +export type TimePickerResult = {| + action: string, + hour: number, + minute: number, +|}; + +export interface Spec extends TurboModule { + // eslint-disable-next-line lint/react-native-modules + +open: (options: TimePickerOptions) => Promise; +} + +export default (TurboModuleRegistry.get('TimePickerAndroid'): ?Spec); diff --git a/Libraries/Utilities/LoadingView.ios.js b/Libraries/Utilities/LoadingView.ios.js index e8f7d133f5caf3..ad2caad48310ea 100644 --- a/Libraries/Utilities/LoadingView.ios.js +++ b/Libraries/Utilities/LoadingView.ios.js @@ -16,20 +16,19 @@ import NativeDevLoadingView from './NativeDevLoadingView'; module.exports = { showMessage(message: string, type: 'load' | 'refresh') { if (NativeDevLoadingView) { - const green = processColor('#005a00'); - const blue = processColor('#2584e8'); + const loadColor = processColor('#404040'); + const refreshColor = processColor('#2584e8'); const white = processColor('#ffffff'); NativeDevLoadingView.showMessage( message, - // Use same colors as iOS "Personal Hotspot" bar. typeof white === 'number' ? white : null, type && type === 'load' - ? typeof green === 'number' - ? green + ? typeof loadColor === 'number' + ? loadColor : null - : typeof blue === 'number' - ? blue + : typeof refreshColor === 'number' + ? refreshColor : null, ); } diff --git a/Libraries/Utilities/codegenNativeComponent.js b/Libraries/Utilities/codegenNativeComponent.js index 8c1a9d0b4d66ab..c790495c5e41c6 100644 --- a/Libraries/Utilities/codegenNativeComponent.js +++ b/Libraries/Utilities/codegenNativeComponent.js @@ -20,7 +20,7 @@ type Options = $ReadOnly<{| interfaceOnly?: boolean, paperComponentName?: string, paperComponentNameDeprecated?: string, - excludedPlatform?: 'iOS' | 'android', + excludedPlatforms?: $ReadOnlyArray<'iOS' | 'android'>, |}>; export type NativeComponentType = HostComponent; diff --git a/RNTester/Podfile.lock b/RNTester/Podfile.lock index f1cc9b2f5fd073..a5767ec8323f91 100644 --- a/RNTester/Podfile.lock +++ b/RNTester/Podfile.lock @@ -236,6 +236,7 @@ PODS: - RCT-Folly (= 2020.01.13.00) - React-callinvoker (= 1000.0.0) - React-jsinspector (= 1000.0.0) + - React-runtimeexecutor (= 1000.0.0) - React-jsi (1000.0.0): - boost-for-react-native (= 1.63.0) - DoubleConversion @@ -318,6 +319,8 @@ PODS: - React-Core/RCTVibrationHeaders (= 1000.0.0) - React-jsi (= 1000.0.0) - ReactCommon/turbomodule/core (= 1000.0.0) + - React-runtimeexecutor (1000.0.0): + - React-jsi (= 1000.0.0) - React-TurboModuleCxx-RNW (1000.0.0): - RCT-Folly (= 2020.01.13.00) - React-callinvoker (= 1000.0.0) @@ -402,6 +405,7 @@ DEPENDENCIES: - React-RCTTest (from `./RCTTest`) - React-RCTText (from `../Libraries/Text`) - React-RCTVibration (from `../Libraries/Vibration`) + - React-runtimeexecutor (from `../ReactCommon/runtimeexecutor`) - React-TurboModuleCxx-RNW (from `../ReactTurboModuleCxx/React-TurboModuleCxx-RNW.podspec`) - React-TurboModuleCxx-WinRTPort (from `../ReactTurboModuleCxx`) - ReactCommon/turbomodule/core (from `../ReactCommon`) @@ -479,6 +483,8 @@ EXTERNAL SOURCES: :path: "../Libraries/Text" React-RCTVibration: :path: "../Libraries/Vibration" + React-runtimeexecutor: + :path: "../ReactCommon/runtimeexecutor" React-TurboModuleCxx-RNW: :podspec: "../ReactTurboModuleCxx/React-TurboModuleCxx-RNW.podspec" React-TurboModuleCxx-WinRTPort: @@ -493,8 +499,8 @@ SPEC CHECKSUMS: CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845 CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f DoubleConversion: 2b45d0f8e156a5b02354c8a4062de64d41ccb4e0 - FBLazyVector: 2a6caf53223741f5f28ef26a4af1b6e8300ce387 - FBReactNativeSpec: 62c59cc87734b32894837cf83de694fa3875783d + FBLazyVector: 98b5ed9e2c8215c32630adabb6c6ae8fd88b4808 + FBReactNativeSpec: a5a59afb795ccab0596667e248b5cdcb05cf86e2 Flipper: be611d4b742d8c87fbae2ca5f44603a02539e365 Flipper-DoubleConversion: 38631e41ef4f9b12861c67d17cb5518d06badc41 Flipper-Folly: c12092ea368353b58e992843a990a3225d4533c3 @@ -505,32 +511,33 @@ SPEC CHECKSUMS: glog: 789873d01e4b200777d0a09bc23d548446758699 OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355 RCT-Folly: 55d0039b24e192081ec0b2257f7bd9f42e382fb7 - RCTRequired: 37458b93b9cd9fba3ab51dd2e458dbb9cb47520d - RCTTypeSafety: 519c014f622af9b169ecfa216bedfab393ff5912 - React: 4fd7e473044e7648f405920f016929540d34e982 - React-ART: bcf223c5eff9012d960831ff1e769bb122b4f885 - React-callinvoker: 5b05b9e59fb30f90bc0725d4af7e1192ba26c481 - React-Core: 11c6182b2c0f066654cb15aa79cbded57491d6d6 - React-CoreModules: 3ee9b5c78248c356a40d1756848ff3e54643d507 - React-cxxreact: aa5a9272ad44004b38e168e23c89d3975ee89f8c - React-jsi: 2168becebc7c1f9da7db0e87128441ce5658276a - React-jsiexecutor: 910d40b16b39c7bf016ce531ecebe96775dc66df - React-jsinspector: f372dd2f90f35ca9f4ed414f02155cc32f092f21 - React-RCTActionSheet: d732c93288db766d84e9050b503fc573b20d4f0f - React-RCTAnimation: 82920521aa45e1d1497e4d8c489ecee47a7daf90 - React-RCTBlob: 075b73cf6d1d45d90ab49656234d5dc8de9de2ed - React-RCTImage: e13823a64d4dbdda8e6f995dd0e9f49cdd5441e7 - React-RCTLinking: f235950225543ebcdda86caa8fa4d9c61ac568b6 - React-RCTNetwork: 740884e7e2bad762f1678799c9d00805f562e333 - React-RCTPushNotification: 937bbbe82f700cbeaa1d5a3b1e9b13df48145c96 - React-RCTSettings: d79eaace2fed3bf317df17fa97355222cca052c5 - React-RCTTest: 66c38e03b6e5aa3c2721b0b1f5ff3e3895d2ede9 - React-RCTText: 8df41e7b83bbce2a8a55594b3e1663c177954eb1 - React-RCTVibration: 1c1755a5ed06d469f100d32c4cd28789b92f0a3c + RCTRequired: cd124a69447b4db403af1f4dc1d7c7cb617185a0 + RCTTypeSafety: 83da012f103c272792343e635da1b72936067b96 + React: e7aaeceb4fee9ffc841301330e753a1bd3e57437 + React-ART: 114994073be3e1257406f49d629222d94f5361bd + React-callinvoker: ebde245fca99f1f324793be8783dd6def592627c + React-Core: 4775366e8e941f063ee8463f86bf41613ec1a7b2 + React-CoreModules: ca9df8e2a54ccbaad588ffa772f71fbc8ba19279 + React-cxxreact: cfba7c9e9bd2d23b97af6467d5ecf390e932676d + React-jsi: b0857c300ffbf312d1b15e60a060ad7f5a2f978d + React-jsiexecutor: 93e0bb19579e3002775bc3efc0cbd81f20943be8 + React-jsinspector: 3526475c50fc3d942d6cdc02618f72a5f5510935 + React-RCTActionSheet: 23ed110450142634ede6b88ccbd2fb69aa892c52 + React-RCTAnimation: 383e388d729b39d0087b4986f0ebb728bac7eb02 + React-RCTBlob: 53fcb292e073976d7f6867841eee402770bfbf84 + React-RCTImage: 3ea30c5c2fd33f042aa768e6a1688046bbf59bda + React-RCTLinking: cb77eeacb78c1b3cd1c579c6597ea2bbe424945e + React-RCTNetwork: a34eabaa807c9163af30d4e4623b20e3136659bc + React-RCTPushNotification: 9f0a55cbaeccb9a10252d468fa73c7281aef680c + React-RCTSettings: 149f8ea51af3afb60f4a3a262698b94a0a9209aa + React-RCTTest: 7d56585d7cc88320631522ae29ffba082e12c377 + React-RCTText: 9b42805a9082c6e6df5b0deab2bdba14f1db0e3a + React-RCTVibration: c834fb5115f6d341b68a9595905bf253b617ab1d + React-runtimeexecutor: 576ce90cf13a65e00b35c3cbcdbe65aaddea8351 React-TurboModuleCxx-RNW: 18bb71af41fe34c8b12a56bef60aae7ee32b0817 - React-TurboModuleCxx-WinRTPort: c1adb8fead6510128bd0203ab4a39ac9b14d9242 - ReactCommon: 94af7b71fd77b1f670215637147f79872ec95835 - Yoga: 190421d13b42fd56a19bea15f2a5b03f98e21911 + React-TurboModuleCxx-WinRTPort: d4886bfcdff8fb04d407e6a3b7ee8feb7cc2ad40 + ReactCommon: 4ae7a0aa58b93673a204fdd12ff4f8b079baf20e + Yoga: dd900352619ba7f891e6e505ceee59afc0012115 YogaKit: f782866e155069a2cca2517aafea43200b01fd5a PODFILE CHECKSUM: 7d43a928a9b9ad27329da110adbfadd923a39ba8 diff --git a/RNTester/RNTesterPods.xcodeproj/project.pbxproj b/RNTester/RNTesterPods.xcodeproj/project.pbxproj index 825f54b636aa8e..b7a8859d7683d5 100644 --- a/RNTester/RNTesterPods.xcodeproj/project.pbxproj +++ b/RNTester/RNTesterPods.xcodeproj/project.pbxproj @@ -847,7 +847,7 @@ 83CBB9F71A601CBA00E9B192 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 1130; + LastUpgradeCheck = 1140; ORGANIZATIONNAME = Facebook; TargetAttributes = { 387847D0245631D80035033A = { @@ -1511,6 +1511,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = 98233960D1D6A1977D1C7EAF /* Pods-RNTester.debug.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_CXX_LANGUAGE_STANDARD = "c++14"; CODE_SIGN_ENTITLEMENTS = RNTester/RNTester.entitlements; diff --git a/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme b/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme index aa5eb07b7a0e40..938a25682dbd5c 100644 --- a/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme +++ b/RNTester/RNTesterPods.xcodeproj/xcshareddata/xcschemes/RNTester.xcscheme @@ -1,6 +1,6 @@ { }; _onChangeScrollToIndex = text => { - this._listRef - .getNode() - .scrollToIndex({viewPosition: 0.5, index: Number(text)}); + this._listRef.scrollToIndex({viewPosition: 0.5, index: Number(text)}); }; _scrollPos = new Animated.Value(0); @@ -97,7 +95,7 @@ class FlatListExample extends React.PureComponent { ); componentDidUpdate() { - this._listRef.getNode().recordInteraction(); // e.g. flipping logViewable switch + this._listRef.recordInteraction(); // e.g. flipping logViewable switch } render(): React.Node { @@ -249,7 +247,7 @@ class FlatListExample extends React.PureComponent { } }; _pressItem = (key: string) => { - this._listRef.getNode().recordInteraction(); + this._listRef && this._listRef.recordInteraction(); pressItem(this, key); }; _listRef: React.ElementRef; diff --git a/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js b/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js index 93127afb755999..c32bacefef2cc8 100644 --- a/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js +++ b/RNTester/js/examples/PushNotificationIOS/PushNotificationIOSExample.js @@ -196,7 +196,7 @@ class NotificationPermissionExample extends React.Component< ); this._checkPermissions(); }, - (onReject?) => { + () => { this._showAlert('Error requesting permissions'); this._checkPermissions(); }, diff --git a/RNTester/js/examples/SectionList/SectionListExample.js b/RNTester/js/examples/SectionList/SectionListExample.js index d3b895e6362950..56d7067550c1ff 100644 --- a/RNTester/js/examples/SectionList/SectionListExample.js +++ b/RNTester/js/examples/SectionList/SectionListExample.js @@ -92,13 +92,14 @@ class SectionListExample extends React.PureComponent<{...}, $FlowFixMeState> { {useNativeDriver: true}, ); - _sectionListRef: React.ElementRef; + _sectionListRef: ?React.ElementRef = null; _captureRef = ref => { this._sectionListRef = ref; }; _scrollToLocation(sectionIndex: number, itemIndex: number) { - this._sectionListRef.getNode().scrollToLocation({sectionIndex, itemIndex}); + this._sectionListRef && + this._sectionListRef.scrollToLocation({sectionIndex, itemIndex}); } render(): React.Node { diff --git a/React/Base/RCTJavaScriptLoader.mm b/React/Base/RCTJavaScriptLoader.mm index 8c8e5fad02ff17..d15738c549eabe 100755 --- a/React/Base/RCTJavaScriptLoader.mm +++ b/React/Base/RCTJavaScriptLoader.mm @@ -50,10 +50,14 @@ @implementation RCTLoadingProgress - (NSString *)description { NSMutableString *desc = [NSMutableString new]; - [desc appendString:_status ?: @"Loading"]; + [desc appendString:_status ?: @"Bundling"]; - if ([_total integerValue] > 0) { - [desc appendFormat:@" %ld%% (%@/%@)", (long)(100 * [_done integerValue] / [_total integerValue]), _done, _total]; + if ([_total integerValue] > 0 && [_done integerValue] > [_total integerValue]) { + [desc appendFormat:@" %ld%%", (long)100]; + } else if ([_total integerValue] > 0) { + [desc appendFormat:@" %ld%%", (long)(100 * [_done integerValue] / [_total integerValue])]; + } else { + [desc appendFormat:@" %ld%%", (long)0]; } [desc appendString:@"\u2026"]; return desc; @@ -346,7 +350,7 @@ static void attemptAsynchronousLoadOfBundleAtURL( static RCTLoadingProgress *progressEventFromDownloadProgress(NSNumber *total, NSNumber *done) { RCTLoadingProgress *progress = [RCTLoadingProgress new]; - progress.status = @"Downloading JavaScript bundle"; + progress.status = @"Downloading"; // Progress values are in bytes transform them to kilobytes for smaller numbers. progress.done = done != nil ? @([done integerValue] / 1024) : nil; progress.total = total != nil ? @([total integerValue] / 1024) : nil; diff --git a/React/CoreModules/RCTDevLoadingView.mm b/React/CoreModules/RCTDevLoadingView.mm index 88a385c3275bae..da8c928f315da1 100644 --- a/React/CoreModules/RCTDevLoadingView.mm +++ b/React/CoreModules/RCTDevLoadingView.mm @@ -39,6 +39,8 @@ @implementation RCTDevLoadingView { NSTextField *_label; #endif // ]TODO(macOS GH#774) NSDate *_showDate; + BOOL _hiding; + dispatch_block_t _initialMessageBlock; } @synthesize bridge = _bridge; @@ -73,9 +75,54 @@ - (void)setBridge:(RCTBridge *)bridge } } +- (void)clearInitialMessageDelay +{ + if (self->_initialMessageBlock != nil) { + dispatch_block_cancel(self->_initialMessageBlock); + self->_initialMessageBlock = nil; + } +} + +- (void)showInitialMessageDelayed:(void (^)())initialMessage +{ + self->_initialMessageBlock = dispatch_block_create(static_cast(0), initialMessage); + + // We delay the initial loading message to prevent flashing it + // when loading progress starts quickly. To do that, we + // schedule the message to be shown in a block, and cancel + // the block later when the progress starts coming in. + // If the progress beats this timer, this message is not shown. + dispatch_after( + dispatch_time(DISPATCH_TIME_NOW, 0.2 * NSEC_PER_SEC), dispatch_get_main_queue(), self->_initialMessageBlock); +} + +#if 0 // TODO(macOS GH#774) +// Blocked out because -[(NS|UI)Color getHue:saturation:brightness:alpha:] has +// different return values on macOS and iOS. +// The call to dimColor: was removed with f0dfd35108dd3f092d46b65e77560c35477bf6ba, +// and we don't use it anywhere else, so we should probably remove this upstream too. +- (RCTUIColor *)dimColor:(RCTUIColor *)c +{ + // Given a color, return a slightly lighter or darker color for dim effect. + CGFloat h, s, b, a; + if ([c getHue:&h saturation:&s brightness:&b alpha:&a]) + return [RCTUIColor colorWithHue:h saturation:s brightness:b < 0.5 ? b * 1.25 : b * 0.75 alpha:a]; + return nil; +} +#endif // TODO(macOS GH#774) + +- (NSString *)getTextForHost +{ + if (self->_bridge.bundleURL == nil || self->_bridge.bundleURL.fileURL) { + return @"React Native"; + } + + return [NSString stringWithFormat:@"%@:%@", self->_bridge.bundleURL.host, self->_bridge.bundleURL.port]; +} + - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColor:(RCTUIColor *)backgroundColor // TODO(OSS Candidate ISS#2710739) { - if (!RCTDevLoadingViewGetEnabled()) { + if (!RCTDevLoadingViewGetEnabled() || self->_hiding) { return; } @@ -88,18 +135,16 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo if (@available(iOS 11.0, *)) { UIWindow *window = RCTSharedApplication().keyWindow; self->_window = - [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, window.safeAreaInsets.top + 30)]; - self->_label = [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top, screenSize.width, 30)]; + [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, window.safeAreaInsets.top + 10)]; + self->_label = + [[UILabel alloc] initWithFrame:CGRectMake(0, window.safeAreaInsets.top - 10, screenSize.width, 20)]; } else { - self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, 22)]; + self->_window = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, screenSize.width, 20)]; self->_label = [[UILabel alloc] initWithFrame:self->_window.bounds]; } [self->_window addSubview:self->_label]; -#if TARGET_OS_TV - self->_window.windowLevel = UIWindowLevelNormal + 1; -#else + self->_window.windowLevel = UIWindowLevelStatusBar + 1; -#endif // set a root VC so rotation is supported self->_window.rootViewController = [UIViewController new]; @@ -129,6 +174,7 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo #if !TARGET_OS_OSX // TODO(macOS GH#774) self->_label.text = message; self->_label.textColor = color; + self->_window.backgroundColor = backgroundColor; self->_window.hidden = NO; #else // [TODO(macOS GH#774) @@ -162,7 +208,11 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo return; } + // Cancel the initial message block so it doesn't display later and get stuck. + [self clearInitialMessageDelay]; + dispatch_async(dispatch_get_main_queue(), ^{ + self->_hiding = true; const NSTimeInterval MIN_PRESENTED_TIME = 0.6; NSTimeInterval presentedTime = [[NSDate date] timeIntervalSinceDate:self->_showDate]; NSTimeInterval delay = MAX(0, MIN_PRESENTED_TIME - presentedTime); @@ -178,6 +228,7 @@ - (void)showMessage:(NSString *)message color:(RCTUIColor *)color backgroundColo self->_window.frame = windowFrame; self->_window.hidden = YES; self->_window = nil; + self->_hiding = false; }]; #elif TARGET_OS_OSX // [TODO(macOS GH#774) dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ @@ -198,20 +249,23 @@ - (void)showWithURL:(NSURL *)URL RCTUIColor *backgroundColor; // TODO(macOS GH#774) NSString *message; if (URL.fileURL) { - // If dev mode is not enabled, we don't want to show this kind of notification + // If dev mode is not enabled, we don't want to show this kind of notification. #if !RCT_DEV return; #endif color = [RCTUIColor whiteColor]; //TODO(OSS Candidate ISS#2710739) UIColor -> RCTUIColor backgroundColor = [RCTUIColor blackColor]; // TODO(OSS Candidate ISS#2710739) message = [NSString stringWithFormat:@"Connect to %@ to develop JavaScript.", RCT_PACKAGER_NAME]; + [self showMessage:message color:color backgroundColor:backgroundColor]; } else { color = [RCTUIColor whiteColor]; // TODO(OSS Candidate ISS#2710739) - backgroundColor = [RCTUIColor colorWithHue:1. / 3 saturation:1 brightness:.35 alpha:1]; // TODO(OSS Candidate ISS#2710739) - message = [NSString stringWithFormat:@"Loading from %@:%@...", URL.host, URL.port]; - } + backgroundColor = [RCTUIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1]; // TODO(OSS Candidate ISS#2710739) + message = [NSString stringWithFormat:@"Loading from %@\u2026", RCT_PACKAGER_NAME]; - [self showMessage:message color:color backgroundColor:backgroundColor]; + [self showInitialMessageDelayed:^{ + [self showMessage:message color:color backgroundColor:backgroundColor]; + }]; + } } - (void)updateProgress:(RCTLoadingProgress *)progress @@ -219,12 +273,27 @@ - (void)updateProgress:(RCTLoadingProgress *)progress if (!progress) { return; } + + // Cancel the initial message block so it's not flashed before progress. + [self clearInitialMessageDelay]; + dispatch_async(dispatch_get_main_queue(), ^{ + if (self->_window == nil) { + // If we didn't show the initial message, then there's no banner window. + // We need to create it here so that the progress is actually displayed. + RCTUIColor *color = [RCTUIColor whiteColor]; + RCTUIColor *backgroundColor = [RCTUIColor colorWithHue:105 saturation:0 brightness:.25 alpha:1]; + [self showMessage:[progress description] color:color backgroundColor:backgroundColor]; + } else { + // This is an optimization. Since the progress can come in quickly, + // we want to do the minimum amount of work to update the UI, + // which is to only update the label text. #if !TARGET_OS_OSX // TODO(macOS GH#774) - self->_label.text = [progress description]; + self->_label.text = [progress description]; #else // [TODO(macOS GH#774) - self->_label.stringValue = [progress description]; + self->_label.stringValue = [progress description]; #endif // ]TODO(macOS GH#774) + } }); } diff --git a/React/CxxBridge/RCTCxxBridge.mm b/React/CxxBridge/RCTCxxBridge.mm index d860fc0bf495ff..a996fda0b6fab9 100644 --- a/React/CxxBridge/RCTCxxBridge.mm +++ b/React/CxxBridge/RCTCxxBridge.mm @@ -258,10 +258,24 @@ - (instancetype)initWithParentBridge:(RCTBridge *)bridge _moduleDataByID = [NSMutableArray new]; [RCTBridge setCurrentBridge:self]; + +#if !TARGET_OS_OSX // TODO(macOS GH#774) + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(handleMemoryWarning) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; +#endif // TODO(macOS GH#774) } return self; } +#if !TARGET_OS_OSX // TODO(macOS GH#774) +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} +#endif // TODO(macOS GH#774) + + (void)runRunLoop { @autoreleasepool { @@ -295,6 +309,13 @@ - (void)_tryAndHandleError:(dispatch_block_t)block } } +- (void)handleMemoryWarning +{ + if (_reactInstance) { + _reactInstance->handleMemoryPressure(15 /* TRIM_MEMORY_RUNNING_CRITICAL */); + } +} + /** * Ensure block is run on the JS thread. If we're already on the JS thread, the block will execute synchronously. * If we're not on the JS thread, the block is dispatched to that thread. Any errors encountered while executing @@ -514,6 +535,11 @@ - (id)moduleForName:(NSString *)moduleName lazilyLoadIfNecessary:(BOOL)lazilyLoa } // Module may not be loaded yet, so attempt to force load it here. + // Do this only if the bridge is still valid. + if (_didInvalidate) { + return nil; + } + const BOOL result = [self.delegate respondsToSelector:@selector(bridge:didNotFindModule:)] && [self.delegate bridge:self didNotFindModule:moduleName]; if (result) { diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.cpp b/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.cpp deleted file mode 100644 index cbb3c1998abae5..00000000000000 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -namespace facebook { -namespace react { - -extern const char RCTARTSurfaceViewComponentName[] = "ARTSurfaceView"; - -} // namespace react -} // namespace facebook diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.h b/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.h deleted file mode 100644 index 3a26257acc5f7a..00000000000000 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceShadowNode.h +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include -#include "RCTARTSurfaceViewProps.h" - -namespace facebook { -namespace react { - -extern const char RCTARTSurfaceViewComponentName[]; - -/* - * `ShadowNode` for component. - */ -using RCTARTSurfaceShadowNode = ConcreteViewShadowNode< - RCTARTSurfaceViewComponentName, - RCTARTSurfaceViewProps, - ViewEventEmitter>; - -} // namespace react -} // namespace facebook diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.h b/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.h deleted file mode 100644 index 30a6ab992fa7b8..00000000000000 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import - -/** - * UIView class for root component. - */ -@interface RCTARTSurfaceViewComponentView : RCTViewComponentView - -@end diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.mm deleted file mode 100644 index f8a26d871f6bf8..00000000000000 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentView.mm +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#import "RCTARTSurfaceViewComponentView.h" -#import -#import "RCTARTSurfaceViewComponentDescriptor.h" - -#import "FBRCTFabricComponentsPlugins.h" - -using namespace facebook::react; - -@implementation RCTARTSurfaceViewComponentView { -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - if (self = [super initWithFrame:frame]) { - static const auto defaultProps = std::make_shared(); - _props = defaultProps; - } - - return self; -} - -#pragma mark - RCTComponentViewProtocol - -+ (ComponentDescriptorProvider)componentDescriptorProvider -{ - return concreteComponentDescriptorProvider(); -} - -@end - -Class RCTARTSurfaceViewCls(void) -{ - return RCTARTSurfaceViewComponentView.class; -} diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.cpp b/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.cpp deleted file mode 100644 index fd94a7c0d8f73d..00000000000000 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.cpp +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#include "RCTARTSurfaceViewProps.h" - -#include - -namespace facebook { -namespace react { - -RCTARTSurfaceViewProps::RCTARTSurfaceViewProps( - const RCTARTSurfaceViewProps &sourceProps, - const RawProps &rawProps) - : ViewProps(sourceProps, rawProps) {} - -} // namespace react -} // namespace facebook diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.h b/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.h deleted file mode 100644 index cbebf7c4de82d5..00000000000000 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewProps.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -#pragma once - -#include - -namespace facebook { -namespace react { - -class RCTARTSurfaceViewProps final : public ViewProps { - public: - RCTARTSurfaceViewProps() = default; - RCTARTSurfaceViewProps( - const RCTARTSurfaceViewProps &sourceProps, - const RawProps &rawProps); - -#pragma mark - Props -}; - -} // namespace react -} // namespace facebook diff --git a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm index e393dae3dabd51..4e87e202fab898 100644 --- a/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/Image/RCTImageComponentView.mm @@ -7,6 +7,7 @@ #import "RCTImageComponentView.h" +#import #import #import #import @@ -41,6 +42,8 @@ - (instancetype)initWithFrame:(CGRect)frame _imageView = [[UIImageView alloc] initWithFrame:self.bounds]; _imageView.clipsToBounds = YES; _imageView.contentMode = (UIViewContentMode)RCTResizeModeFromImageResizeMode(defaultProps->resizeMode); + _imageView.layer.minificationFilter = kCAFilterTrilinear; + _imageView.layer.magnificationFilter = kCAFilterTrilinear; _imageResponseObserverProxy = RCTImageResponseObserverProxy(self); @@ -161,17 +164,30 @@ - (void)didReceiveImage:(UIImage *)image fromObserver:(void const *)observer resizingMode:UIImageResizingModeStretch]; } - self->_imageView.image = image; - - // Apply trilinear filtering to smooth out mis-sized images. - self->_imageView.layer.minificationFilter = kCAFilterTrilinear; - self->_imageView.layer.magnificationFilter = kCAFilterTrilinear; - - auto data = _state->getData(); - auto instrumentation = std::static_pointer_cast( - data.getImageRequest().getSharedImageInstrumentation()); - if (instrumentation) { - instrumentation->didSetImage(); + void (^didSetImage)() = ^() { + if (!self->_state) { + return; + } + auto data = self->_state->getData(); + auto instrumentation = std::static_pointer_cast( + data.getImageRequest().getSharedImageInstrumentation()); + if (instrumentation) { + instrumentation->didSetImage(); + } + }; + + if (imageProps.blurRadius > __FLT_EPSILON__) { + // Blur on a background thread to avoid blocking interaction. + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + UIImage *blurredImage = RCTBlurredImageWithRadius(image, imageProps.blurRadius); + RCTExecuteOnMainQueue(^{ + self->_imageView.image = blurredImage; + didSetImage(); + }); + }); + } else { + self->_imageView.image = image; + didSetImage(); } } diff --git a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm index fc689ca35c324e..9da0483fad089a 100644 --- a/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/LegacyViewManagerInterop/RCTLegacyViewManagerInteropComponentView.mm @@ -36,8 +36,16 @@ - (instancetype)initWithFrame:(CGRect)frame + (NSMutableSet *)supportedViewManagers { - static NSMutableSet *supported = - [NSMutableSet setWithObjects:@"Picker", @"DatePicker", @"ProgressView", @"SegmentedControl", @"MaskedView", nil]; + static NSMutableSet *supported = [NSMutableSet setWithObjects:@"Picker", + @"DatePicker", + @"ProgressView", + @"SegmentedControl", + @"MaskedView", + @"ARTSurfaceView", + @"ARTText", + @"ARTShape", + @"ARTGroup", + nil]; return supported; } diff --git a/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h b/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h index 3bf14b7394b3c7..60f9dca7efafd3 100644 --- a/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h +++ b/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.h @@ -37,7 +37,6 @@ Class RCTSliderCls(void) __attribute__((used)); Class RCTSwitchCls(void) __attribute__((used)); Class RCTUnimplementedNativeViewCls(void) __attribute__((used)); Class RCTModalHostViewCls(void) __attribute__((used)); -Class RCTARTSurfaceViewCls(void) __attribute__((used)); Class RCTImageCls(void) __attribute__((used)); #ifdef __cplusplus diff --git a/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.mm b/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.mm index ccb07bcbb8e28a..f56ec907d8467a 100644 --- a/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.mm +++ b/React/Fabric/Mounting/ComponentViews/RCTFabricComponentsPlugins.mm @@ -26,7 +26,6 @@ {"Switch", RCTSwitchCls}, {"UnimplementedNativeView", RCTUnimplementedNativeViewCls}, {"ModalHostView", RCTModalHostViewCls}, - {"ARTSurfaceView", RCTARTSurfaceViewCls}, {"Image", RCTImageCls}, }; diff --git a/React/Fabric/Mounting/ComponentViews/SafeAreaView/RCTSafeAreaViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/SafeAreaView/RCTSafeAreaViewComponentView.mm index 00a1cb35a02ef8..982f63d5037a1a 100644 --- a/React/Fabric/Mounting/ComponentViews/SafeAreaView/RCTSafeAreaViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/SafeAreaView/RCTSafeAreaViewComponentView.mm @@ -86,6 +86,12 @@ - (void)updateState:(facebook::react::State::Shared const &)state [self _updateStateIfNecessary]; } +- (void)prepareForRecycle +{ + [super prepareForRecycle]; + _state.reset(); +} + + (ComponentDescriptorProvider)componentDescriptorProvider { return concreteComponentDescriptorProvider(); diff --git a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm index 05b8f7ac3f7238..1e7b92a2d104bb 100644 --- a/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/TextInput/RCTTextInputComponentView.mm @@ -42,6 +42,16 @@ @implementation RCTTextInputComponentView { * textInputDidChange]` call. */ BOOL _ignoreNextTextInputCall; + + /* + * A flag that when set to true, `_mostRecentEventCount` won't be incremented when `[self _updateState]` + * and delegate methods `textInputDidChange` and `textInputDidChangeSelection` will exit early. + * + * Setting `_backedTextInputView.attributedText` triggers delegate methods `textInputDidChange` and + * `textInputDidChangeSelection` for multiline text input only. + * In multiline text input this is undesirable as we don't want to be sending events for changes that JS triggered. + */ + BOOL _comingFromJS; } - (instancetype)initWithFrame:(CGRect)frame @@ -55,6 +65,7 @@ - (instancetype)initWithFrame:(CGRect)frame _backedTextInputView.frame = self.bounds; _backedTextInputView.textInputDelegate = self; _ignoreNextTextInputCall = NO; + _comingFromJS = NO; [self addSubview:_backedTextInputView]; } @@ -185,7 +196,9 @@ - (void)updateState:(State::Shared const &)state oldState:(State::Shared const & if (_mostRecentEventCount == _state->getData().mostRecentEventCount) { auto data = _state->getData(); + _comingFromJS = YES; [self _setAttributedString:RCTNSAttributedStringFromAttributedStringBox(data.attributedStringBox)]; + _comingFromJS = NO; } } @@ -204,11 +217,6 @@ - (void)_setAttributedString:(NSAttributedString *)attributedString { UITextRange *selectedRange = [_backedTextInputView selectedTextRange]; _backedTextInputView.attributedText = attributedString; - // Calling `[_backedTextInputView setAttributedText]` results - // in `textInputDidChangeSelection` being called but not `textInputDidChange`. - // For `_ignoreNextTextInputCall` to have correct value, these calls - // need to be balanced, that's why we manually set the flag here. - _ignoreNextTextInputCall = NO; if (_lastStringStateWasUpdatedWith.length == attributedString.length) { // Calling `[_backedTextInputView setAttributedText]` moves caret // to the end of text input field. This cancels any selection as well @@ -225,6 +233,7 @@ - (void)prepareForRecycle _backedTextInputView.attributedText = [[NSAttributedString alloc] init]; _mostRecentEventCount = 0; _state.reset(); + _comingFromJS = NO; _lastStringStateWasUpdatedWith = nil; _ignoreNextTextInputCall = NO; } @@ -334,10 +343,15 @@ - (BOOL)textInputShouldChangeTextInRange:(NSRange)range replacementText:(NSStrin - (void)textInputDidChange { + if (_comingFromJS) { + return; + } + if (_ignoreNextTextInputCall) { _ignoreNextTextInputCall = NO; return; } + [self _updateState]; if (_eventEmitter) { @@ -347,6 +361,9 @@ - (void)textInputDidChange - (void)textInputDidChangeSelection { + if (_comingFromJS) { + return; + } auto const &props = *std::static_pointer_cast(_props); if (props.traits.multiline && ![_lastStringStateWasUpdatedWith isEqual:_backedTextInputView.attributedText]) { [self textInputDidChange]; @@ -379,7 +396,7 @@ - (void)_updateState auto data = _state->getData(); _lastStringStateWasUpdatedWith = attributedString; data.attributedStringBox = RCTAttributedStringBoxFromNSAttributedString(attributedString); - _mostRecentEventCount += 1; + _mostRecentEventCount += _comingFromJS ? 0 : 1; data.mostRecentEventCount = _mostRecentEventCount; _state->updateState(std::move(data)); } @@ -419,8 +436,8 @@ - (void)setTextAndSelection:(NSInteger)eventCount if (_mostRecentEventCount != eventCount) { return; } - - if (value) { + _comingFromJS = YES; + if (![value isEqualToString:_backedTextInputView.attributedText.string]) { NSMutableAttributedString *mutableString = [[NSMutableAttributedString alloc] initWithAttributedString:_backedTextInputView.attributedText]; [mutableString replaceCharactersInRange:NSMakeRange(0, _backedTextInputView.attributedText.length) @@ -438,6 +455,7 @@ - (void)setTextAndSelection:(NSInteger)eventCount UITextRange *range = [_backedTextInputView textRangeFromPosition:startPosition toPosition:endPosition]; [_backedTextInputView setSelectedTextRange:range notifyDelegate:NO]; } + _comingFromJS = NO; } @end diff --git a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm index 2fba022371ee5a..a0f8d7af169061 100644 --- a/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm +++ b/React/Fabric/Mounting/ComponentViews/View/RCTViewComponentView.mm @@ -48,6 +48,7 @@ - (void)setContentView:(UIView *)contentView if (_contentView) { [self addSubview:_contentView]; + _contentView.frame = RCTCGRectFromRect(_layoutMetrics.getContentFrame()); } } diff --git a/React/Fabric/RCTSurfacePresenter.h b/React/Fabric/RCTSurfacePresenter.h index e23e9a39ac227c..38538abc99730b 100644 --- a/React/Fabric/RCTSurfacePresenter.h +++ b/React/Fabric/RCTSurfacePresenter.h @@ -10,8 +10,8 @@ #import #import #import +#import #import -#import NS_ASSUME_NONNULL_BEGIN diff --git a/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm b/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm index 3a97f969a20ef5..307e6aff299acd 100644 --- a/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm +++ b/React/Fabric/RCTSurfacePresenterBridgeAdapter.mm @@ -17,9 +17,9 @@ #import #import +#import #import #import -#import using namespace facebook::react; diff --git a/React/Fabric/Utils/MainRunLoopEventBeat.h b/React/Fabric/Utils/MainRunLoopEventBeat.h index 055728e322b37f..eeb2aeea4538e7 100644 --- a/React/Fabric/Utils/MainRunLoopEventBeat.h +++ b/React/Fabric/Utils/MainRunLoopEventBeat.h @@ -9,8 +9,8 @@ #include #include +#include #include -#include namespace facebook { namespace react { diff --git a/React/Fabric/Utils/RuntimeEventBeat.h b/React/Fabric/Utils/RuntimeEventBeat.h index bc95c141ea9b09..d55980f40c604f 100644 --- a/React/Fabric/Utils/RuntimeEventBeat.h +++ b/React/Fabric/Utils/RuntimeEventBeat.h @@ -7,8 +7,8 @@ #include #include +#include #include -#include namespace facebook { namespace react { diff --git a/React/Views/ScrollView/RCTScrollViewManager.m b/React/Views/ScrollView/RCTScrollViewManager.m index 26801ca0165306..cabd0ccd224886 100644 --- a/React/Views/ScrollView/RCTScrollViewManager.m +++ b/React/Views/ScrollView/RCTScrollViewManager.m @@ -151,7 +151,6 @@ - (RCTPlatformView *)view // TODO(macOS GH#774) addUIBlock:^(__unused RCTUIManager *uiManager, NSDictionary *viewRegistry) { RCTScrollView *view = viewRegistry[reactTag]; if (!view || ![view isKindOfClass:[RCTScrollView class]]) { - RCTLogError(@"Cannot find RCTScrollView with tag #%@", reactTag); return; } diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/network/BUCK b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/network/BUCK index f5842dcae00118..ebfebaf7fe9f4e 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/network/BUCK +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/network/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "network", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/rule/ReactNativeTestRule.java b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/rule/ReactNativeTestRule.java index 1dd5b381a79bc7..8d6252f28b8c88 100644 --- a/ReactAndroid/src/androidTest/java/com/facebook/react/testing/rule/ReactNativeTestRule.java +++ b/ReactAndroid/src/androidTest/java/com/facebook/react/testing/rule/ReactNativeTestRule.java @@ -95,6 +95,11 @@ public void run() { public void onReactContextInitialized(ReactContext reactContext) { final UIManagerModule uiManagerModule = reactContext.getCatalystInstance().getNativeModule(UIManagerModule.class); + + if (uiManagerModule == null) { + return; + } + uiManagerModule .getUIImplementation() .setLayoutUpdateListener( diff --git a/ReactAndroid/src/main/java/com/facebook/debug/holder/BUCK b/ReactAndroid/src/main/java/com/facebook/debug/holder/BUCK index 9212d5990f14dd..c1ee4ded0329dd 100644 --- a/ReactAndroid/src/main/java/com/facebook/debug/holder/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/debug/holder/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_libra rn_android_library( name = "holder", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/debug/tags/BUCK b/ReactAndroid/src/main/java/com/facebook/debug/tags/BUCK index 1442e63d2acfdf..876be9f2ba6753 100644 --- a/ReactAndroid/src/main/java/com/facebook/debug/tags/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/debug/tags/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_libra rn_android_library( name = "tags", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/BUCK b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/BUCK index 9c844d1b75b321..cec027de58b101 100644 --- a/ReactAndroid/src/main/java/com/facebook/fbreact/specs/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/fbreact/specs/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "IS_OSS_BU rn_android_library( name = "FBReactNativeSpec", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = ["PUBLIC"], deps = [ react_native_dep("third-party/java/jsr-305:jsr-305"), diff --git a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK index aacd3e0fe2899b..3b4ea04dbfdff0 100644 --- a/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/hermes/instrumentation/BUCK @@ -11,6 +11,7 @@ rn_android_library( rn_android_library( name = "hermes_samplingprofiler", srcs = ["HermesSamplingProfiler.java"], + labels = ["supermodule:android/default/public.react_native.infra"], visibility = ["PUBLIC"], deps = [ react_native_dep("java/com/facebook/proguard/annotations:annotations"), @@ -29,6 +30,7 @@ rn_xplat_cxx_library( headers = ["HermesSamplingProfiler.h"], header_namespace = "", compiler_flags = ["-fexceptions"], + labels = ["supermodule:android/default/public.react_native.infra"], platforms = ANDROID, soname = "libjsijniprofiler.$(ext)", visibility = [ diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 17eae9a95057da..59ccbbedefb4b8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -470,7 +470,9 @@ public void onBackPressed() { } else { DeviceEventManagerModule deviceEventManagerModule = reactContext.getNativeModule(DeviceEventManagerModule.class); - deviceEventManagerModule.emitHardwareBackPressed(); + if (deviceEventManagerModule != null) { + deviceEventManagerModule.emitHardwareBackPressed(); + } } } @@ -497,7 +499,9 @@ public void onNewIntent(Intent intent) { || NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action))) { DeviceEventManagerModule deviceEventManagerModule = currentContext.getNativeModule(DeviceEventManagerModule.class); - deviceEventManagerModule.emitNewIntentReceived(uri); + if (deviceEventManagerModule != null) { + deviceEventManagerModule.emitNewIntentReceived(uri); + } } currentContext.onNewIntent(mCurrentActivity, intent); } @@ -775,9 +779,12 @@ public void onConfigurationChanged(Context updatedContext, @Nullable Configurati ReactContext currentReactContext = getCurrentReactContext(); if (currentReactContext != null) { - currentReactContext - .getNativeModule(AppearanceModule.class) - .onConfigurationChanged(updatedContext); + AppearanceModule appearanceModule = + currentReactContext.getNativeModule(AppearanceModule.class); + + if (appearanceModule != null) { + appearanceModule.onConfigurationChanged(updatedContext); + } } } @@ -1143,21 +1150,29 @@ private void attachRootViewToInstance(final ReactRoot reactRoot) { @Nullable Bundle initialProperties = reactRoot.getAppProperties(); - final int rootTag = - uiManager.addRootView( - reactRoot.getRootViewGroup(), - initialProperties == null - ? new WritableNativeMap() - : Arguments.fromBundle(initialProperties), - reactRoot.getInitialUITemplate()); - reactRoot.setRootViewTag(rootTag); + final int rootTag; + if (reactRoot.getUIManagerType() == FABRIC) { - // Fabric requires to call updateRootLayoutSpecs before starting JS Application, - // this ensures the root will hace the correct pointScaleFactor. - uiManager.updateRootLayoutSpecs( - rootTag, reactRoot.getWidthMeasureSpec(), reactRoot.getHeightMeasureSpec()); + rootTag = + uiManager.startSurface( + reactRoot.getRootViewGroup(), + reactRoot.getJSModuleName(), + initialProperties == null + ? new WritableNativeMap() + : Arguments.fromBundle(initialProperties), + reactRoot.getWidthMeasureSpec(), + reactRoot.getHeightMeasureSpec()); + reactRoot.setRootViewTag(rootTag); reactRoot.setShouldLogContentAppeared(true); } else { + rootTag = + uiManager.addRootView( + reactRoot.getRootViewGroup(), + initialProperties == null + ? new WritableNativeMap() + : Arguments.fromBundle(initialProperties), + reactRoot.getInitialUITemplate()); + reactRoot.setRootViewTag(rootTag); reactRoot.runApplication(); } Systrace.beginAsyncSection( @@ -1245,32 +1260,38 @@ private ReactApplicationContext createReactContext( reactContext.initializeWithInstance(catalystInstance); - // TODO(T46487253): Remove after task is closed - FLog.e( - ReactConstants.TAG, - "ReactInstanceManager.createReactContext: mJSIModulePackage " - + (mJSIModulePackage != null ? "not null" : "null")); + if (ReactFeatureFlags.enableTurboModuleDebugLogs) { + // TODO(T46487253): Remove after task is closed + FLog.e( + ReactConstants.TAG, + "ReactInstanceManager.createReactContext: mJSIModulePackage " + + (mJSIModulePackage != null ? "not null" : "null")); + } if (mJSIModulePackage != null) { catalystInstance.addJSIModules( mJSIModulePackage.getJSIModules( reactContext, catalystInstance.getJavaScriptContextHolder())); - // TODO(T46487253): Remove after task is closed - FLog.e( - ReactConstants.TAG, - "ReactInstanceManager.createReactContext: ReactFeatureFlags.useTurboModules == " - + (ReactFeatureFlags.useTurboModules == false ? "false" : "true")); + if (ReactFeatureFlags.enableTurboModuleDebugLogs) { + // TODO(T46487253): Remove after task is closed + FLog.e( + ReactConstants.TAG, + "ReactInstanceManager.createReactContext: ReactFeatureFlags.useTurboModules == " + + (ReactFeatureFlags.useTurboModules == false ? "false" : "true")); + } if (ReactFeatureFlags.useTurboModules) { JSIModule turboModuleManager = catalystInstance.getJSIModule(JSIModuleType.TurboModuleManager); - // TODO(T46487253): Remove after task is closed - FLog.e( - ReactConstants.TAG, - "ReactInstanceManager.createReactContext: TurboModuleManager " - + (turboModuleManager == null ? "not created" : "created")); + if (ReactFeatureFlags.enableTurboModuleDebugLogs) { + // TODO(T46487253): Remove after task is closed + FLog.e( + ReactConstants.TAG, + "ReactInstanceManager.createReactContext: TurboModuleManager " + + (turboModuleManager == null ? "not created" : "created")); + } catalystInstance.setTurboModuleManager(turboModuleManager); diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 30b50691b9651a..7c82dd1539bc62 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -94,29 +94,19 @@ public interface ReactRootViewEventListener { private int mLastWidth = 0; private int mLastHeight = 0; private @UIManagerType int mUIManagerType = DEFAULT; - private final boolean mUseSurface; public ReactRootView(Context context) { super(context); - mUseSurface = false; - init(); - } - - public ReactRootView(Context context, boolean useSurface) { - super(context); - mUseSurface = useSurface; init(); } public ReactRootView(Context context, AttributeSet attrs) { super(context, attrs); - mUseSurface = false; init(); } public ReactRootView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); - mUseSurface = false; init(); } @@ -126,13 +116,6 @@ private void init() { @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { - // TODO: T60453649 - Add test automation to verify behavior of onMeasure - - if (mUseSurface) { - super.onMeasure(widthMeasureSpec, heightMeasureSpec); - return; - } - Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "ReactRootView.onMeasure"); try { boolean measureSpecsUpdated = @@ -200,9 +183,12 @@ public void onChildStartedNativeGesture(MotionEvent androidEvent) { return; } ReactContext reactContext = mReactInstanceManager.getCurrentReactContext(); - EventDispatcher eventDispatcher = - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); - mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, eventDispatcher); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + + if (uiManager != null) { + EventDispatcher eventDispatcher = uiManager.getEventDispatcher(); + mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, eventDispatcher); + } } @Override @@ -285,9 +271,12 @@ private void dispatchJSTouchEvent(MotionEvent event) { return; } ReactContext reactContext = mReactInstanceManager.getCurrentReactContext(); - EventDispatcher eventDispatcher = - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); - mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + + if (uiManager != null) { + EventDispatcher eventDispatcher = uiManager.getEventDispatcher(); + mJSTouchDispatcher.handleTouchEvent(event, eventDispatcher); + } } @Override @@ -301,9 +290,6 @@ public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { - if (mUseSurface) { - super.onLayout(changed, left, top, right, bottom); - } // No-op since UIManagerModule handles actually laying out children. } @@ -387,10 +373,6 @@ public void startReactApplication( mAppProperties = initialProperties; mInitialUITemplate = initialUITemplate; - if (mUseSurface) { - // TODO initialize surface here - } - mReactInstanceManager.createReactContextInBackground(); attachToReactInstanceManager(); @@ -528,26 +510,22 @@ public void runApplication() { CatalystInstance catalystInstance = reactContext.getCatalystInstance(); String jsAppModuleName = getJSModuleName(); - if (mUseSurface) { - // TODO call surface's runApplication - } else { - if (mWasMeasured) { - updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec); - } + if (mWasMeasured) { + updateRootLayoutSpecs(mWidthMeasureSpec, mHeightMeasureSpec); + } - WritableNativeMap appParams = new WritableNativeMap(); - appParams.putDouble("rootTag", getRootViewTag()); - @Nullable Bundle appProperties = getAppProperties(); - if (appProperties != null) { - appParams.putMap("initialProps", Arguments.fromBundle(appProperties)); - } + WritableNativeMap appParams = new WritableNativeMap(); + appParams.putDouble("rootTag", getRootViewTag()); + @Nullable Bundle appProperties = getAppProperties(); + if (appProperties != null) { + appParams.putMap("initialProps", Arguments.fromBundle(appProperties)); + } - mShouldLogContentAppeared = true; + mShouldLogContentAppeared = true; - // TODO T62192299: remove this - FLog.e(TAG, "runApplication: call AppRegistry.runApplication"); - catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams); - } + // TODO T62192299: remove this + FLog.e(TAG, "runApplication: call AppRegistry.runApplication"); + catalystInstance.getJSModule(AppRegistry.class).runApplication(jsAppModuleName, appParams); } finally { Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); } @@ -749,10 +727,12 @@ private void emitOrientationChanged(final int newRotation) { } private void emitUpdateDimensionsEvent() { - mReactInstanceManager - .getCurrentReactContext() - .getNativeModule(DeviceInfoModule.class) - .emitUpdateDimensionsEvent(); + DeviceInfoModule deviceInfo = + mReactInstanceManager.getCurrentReactContext().getNativeModule(DeviceInfoModule.class); + + if (deviceInfo != null) { + deviceInfo.emitUpdateDimensionsEvent(); + } } private WritableMap createKeyboardEventPayload( diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/BUCK b/ReactAndroid/src/main/java/com/facebook/react/animated/BUCK index edba01a1b1485d..57e9752b640e08 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/BUCK @@ -6,6 +6,7 @@ rn_android_library( "*.java", ]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java index 919b5a5f16e9f4..ead07f9512229b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedModule.java @@ -130,7 +130,8 @@ public void initialize() { // TODO T59412313 Implement this API on FabricUIManager to use in bridgeless mode if (reactApplicationContext != null && !reactApplicationContext.isBridgeless()) { reactApplicationContext.addLifecycleEventListener(this); - UIManagerModule uiManager = reactApplicationContext.getNativeModule(UIManagerModule.class); + UIManagerModule uiManager = + Assertions.assertNotNull(reactApplicationContext.getNativeModule(UIManagerModule.class)); uiManager.addUIManagerListener(this); } } @@ -191,7 +192,9 @@ private NativeAnimatedNodesManager getNodesManager() { ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn(); if (reactApplicationContext != null) { - UIManagerModule uiManager = reactApplicationContext.getNativeModule(UIManagerModule.class); + UIManagerModule uiManager = + Assertions.assertNotNull( + reactApplicationContext.getNativeModule(UIManagerModule.class)); mNodesManager = new NativeAnimatedNodesManager(uiManager); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java index 9ce9e66470ccfb..2c99f40d655a5f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/animated/NativeAnimatedNodesManager.java @@ -15,12 +15,14 @@ import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReadableArray; import com.facebook.react.bridge.ReadableMap; +import com.facebook.react.bridge.UIManager; import com.facebook.react.bridge.UiThreadUtil; import com.facebook.react.bridge.WritableMap; import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.IllegalViewOperationException; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.Event; +import com.facebook.react.uimanager.events.EventDispatcher; import com.facebook.react.uimanager.events.EventDispatcherListener; import java.util.ArrayDeque; import java.util.ArrayList; @@ -53,14 +55,16 @@ // there will be only one driver per mapping so all code code should be optimized around that. private final Map> mEventDrivers = new HashMap<>(); private final UIManagerModule.CustomEventNamesResolver mCustomEventNamesResolver; - private final UIManagerModule mUIManagerModule; + private final UIManager mUIManager; private int mAnimatedGraphBFSColor = 0; // Used to avoid allocating a new array on every frame in `runUpdates` and `onEventDispatch`. private final List mRunUpdateNodeList = new LinkedList<>(); public NativeAnimatedNodesManager(UIManagerModule uiManager) { - mUIManagerModule = uiManager; - uiManager.getEventDispatcher().addListener(this); + mUIManager = uiManager; + mUIManager.getEventDispatcher().addListener(this); + // TODO T64216139 Remove dependency of UIManagerModule when the Constants are not in Native + // anymore mCustomEventNamesResolver = uiManager.getDirectEventNamesResolver(); } @@ -85,7 +89,7 @@ public void createAnimatedNode(int tag, ReadableMap config) { } else if ("value".equals(type)) { node = new ValueAnimatedNode(config); } else if ("props".equals(type)) { - node = new PropsAnimatedNode(config, this, mUIManagerModule); + node = new PropsAnimatedNode(config, this, mUIManager); } else if ("interpolation".equals(type)) { node = new InterpolationAnimatedNode(config); } else if ("addition".equals(type)) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK index eaa8ab4df53479..53ac6202190a9c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/BUCK @@ -21,6 +21,7 @@ rn_android_library( exclude = INTERFACES, ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], proguard_config = "reactnative.pro", provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), @@ -65,6 +66,7 @@ rn_android_library( name = "interfaces", srcs = glob(INTERFACES), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], proguard_config = "reactnative.pro", provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java index 09f0f6db3f10e3..1a5067b7edb358 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstance.java @@ -62,8 +62,10 @@ public interface CatalystInstance boolean hasNativeModule(Class nativeModuleInterface); + @Nullable T getNativeModule(Class nativeModuleInterface); + @Nullable NativeModule getNativeModule(String moduleName); JSIModule getJSIModule(JSIModuleType moduleType); @@ -97,14 +99,18 @@ public interface CatalystInstance void setGlobalVariable(String propName, String jsonValue); /** - * Get the C pointer (as a long) to the JavaScriptCore context associated with this instance. + * Do not use this anymore. Use {@link #getRuntimeExecutor()} instead. Get the C pointer (as a + * long) to the JavaScriptCore context associated with this instance. * *

Use the following pattern to ensure that the JS context is not cleared while you are using * it: JavaScriptContextHolder jsContext = reactContext.getJavaScriptContextHolder() * synchronized(jsContext) { nativeThingNeedingJsContext(jsContext.get()); } */ + @Deprecated JavaScriptContextHolder getJavaScriptContextHolder(); + RuntimeExecutor getRuntimeExecutor(); + void addJSIModules(List jsiModules); /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java index a6ac1405b054a4..62cdb8a6cda784 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/CatalystInstanceImpl.java @@ -562,6 +562,7 @@ public boolean hasNativeModule(Class nativeModuleInt } @Override + @Nullable public T getNativeModule(Class nativeModuleInterface) { return (T) getNativeModule(getNameFromAnnotation(nativeModuleInterface)); } @@ -577,23 +578,28 @@ private TurboModuleRegistry getTurboModuleRegistry() { } @Override + @Nullable public NativeModule getNativeModule(String moduleName) { if (getTurboModuleRegistry() != null) { TurboModule turboModule = getTurboModuleRegistry().getModule(moduleName); - // TODO(T46487253): Remove after task is closed - FLog.e( - ReactConstants.TAG, - "CatalystInstanceImpl.getNativeModule: TurboModule " - + moduleName - + (turboModule == null ? " not" : "") - + " found"); + if (ReactFeatureFlags.enableTurboModuleDebugLogs) { + // TODO(T46487253): Remove after task is closed + FLog.e( + ReactConstants.TAG, + "CatalystInstanceImpl.getNativeModule: TurboModule " + + moduleName + + (turboModule == null ? " not" : "") + + " found"); + } if (turboModule != null) { return (NativeModule) turboModule; } } - return mNativeModuleRegistry.getModule(moduleName); + return mNativeModuleRegistry.hasModule(moduleName) + ? mNativeModuleRegistry.getModule(moduleName) + : null; } private String getNameFromAnnotation(Class nativeModuleInterface) { @@ -658,6 +664,9 @@ public JavaScriptContextHolder getJavaScriptContextHolder() { return mJavaScriptContextHolder; } + @Override + public native RuntimeExecutor getRuntimeExecutor(); + @Override public void addJSIModules(List jsiModules) { mJSIModuleRegistry.registerModules(jsiModules); diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index fe13dd689810e1..126237e74e8e31 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -158,6 +158,7 @@ public boolean hasNativeModule(Class nativeModuleInt } /** @return the instance of the specified module interface associated with this ReactContext. */ + @Nullable public T getNativeModule(Class nativeModuleInterface) { if (mCatalystInstance == null) { raiseCatalystInstanceMissingException(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/RuntimeExecutor.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/RuntimeExecutor.java new file mode 100644 index 00000000000000..2e001202e43185 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/RuntimeExecutor.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +package com.facebook.react.bridge; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; + +/** A Java holder for a C++ RuntimeExecutor. */ +public class RuntimeExecutor { + + @DoNotStrip private HybridData mHybridData; + + public RuntimeExecutor(HybridData hybridData) { + mHybridData = hybridData; + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java index 89ef6a717209d1..170fc7fcd3f25e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/UIManager.java @@ -10,6 +10,7 @@ import static com.facebook.infer.annotation.ThreadConfined.UI; import android.view.View; +import androidx.annotation.AnyThread; import androidx.annotation.Nullable; import androidx.annotation.UiThread; import com.facebook.infer.annotation.ThreadConfined; @@ -22,6 +23,15 @@ public interface UIManager extends JSIModule, PerformanceCounter { int addRootView( final T rootView, WritableMap initialProps, @Nullable String initialUITemplate); + /** Registers a new root view with width and height. */ + @AnyThread + int startSurface( + final T rootView, + final String moduleName, + final WritableMap initialProps, + int widthMeasureSpec, + int heightMeasureSpec); + /** * Updates the layout specs of the RootShadowNode based on the Measure specs received by * parameters. diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/BUCK b/ReactAndroid/src/main/java/com/facebook/react/common/BUCK index 5c67573a0254d1..0e5a4b52caeac1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/common/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/common/BUCK @@ -11,6 +11,7 @@ rn_android_library( exclude = SUB_PROJECTS, ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/common/network/BUCK b/ReactAndroid/src/main/java/com/facebook/react/common/network/BUCK index 934c22700dffe1..86005fbc76ae79 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/common/network/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/common/network/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_libra rn_android_library( name = "network", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/BUCK b/ReactAndroid/src/main/java/com/facebook/react/config/BUCK index 82c24dc8158a27..347452197e226b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/config/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "rn_android_library") rn_android_library( name = "config", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java index c5b9de82a4453f..c04a883d5fb5cc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java +++ b/ReactAndroid/src/main/java/com/facebook/react/config/ReactFeatureFlags.java @@ -23,6 +23,9 @@ public class ReactFeatureFlags { */ public static volatile boolean useTurboModules = false; + /** Should we output debug logs to debug the TurboModule infra? */ + public static volatile boolean enableTurboModuleDebugLogs = false; + /* * This feature flag enables logs for Fabric */ diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK index a5c503d2f750b0..1c2b6c72e761b4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "devsupport", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], manifest = "AndroidManifest.xml", provided_deps = [ react_native_dep("third-party/android/androidx:core"), @@ -46,6 +47,7 @@ rn_android_library( name = "interfaces", srcs = glob(["interfaces/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java index 8a99c522ba9fbf..e93b645cb83bd5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java +++ b/ReactAndroid/src/main/java/com/facebook/react/devsupport/DevSupportManagerBase.java @@ -962,19 +962,22 @@ private void handleCaptureHeap(final Responder responder) { return; } JSCHeapCapture heapCapture = mCurrentContext.getNativeModule(JSCHeapCapture.class); - heapCapture.captureHeap( - mApplicationContext.getCacheDir().getPath(), - new JSCHeapCapture.CaptureCallback() { - @Override - public void onSuccess(File capture) { - responder.respond(capture.toString()); - } - @Override - public void onFailure(JSCHeapCapture.CaptureException error) { - responder.error(error.toString()); - } - }); + if (heapCapture != null) { + heapCapture.captureHeap( + mApplicationContext.getCacheDir().getPath(), + new JSCHeapCapture.CaptureCallback() { + @Override + public void onSuccess(File capture) { + responder.respond(capture.toString()); + } + + @Override + public void onFailure(JSCHeapCapture.CaptureException error) { + responder.error(error.toString()); + } + }); + } } private void updateLastErrorInfo( diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK index 7c0d2e0c11a8fa..4aa1d97440a5f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK @@ -9,6 +9,7 @@ rn_android_library( "mounting/**/*.java", ]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java index 4d55cf236d6038..0caf99934dd9f2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricJSIModuleProvider.java @@ -8,6 +8,7 @@ package com.facebook.react.fabric; import androidx.annotation.NonNull; +import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.JSIModuleProvider; import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.ReactApplicationContext; @@ -19,18 +20,23 @@ import com.facebook.react.fabric.mounting.LayoutMetricsConversions; import com.facebook.react.fabric.mounting.MountingManager; import com.facebook.react.fabric.mounting.mountitems.BatchMountItem; +import com.facebook.react.fabric.mounting.mountitems.CreateMountItem; import com.facebook.react.fabric.mounting.mountitems.DeleteMountItem; +import com.facebook.react.fabric.mounting.mountitems.DispatchCommandMountItem; import com.facebook.react.fabric.mounting.mountitems.DispatchIntCommandMountItem; import com.facebook.react.fabric.mounting.mountitems.DispatchStringCommandMountItem; import com.facebook.react.fabric.mounting.mountitems.InsertMountItem; import com.facebook.react.fabric.mounting.mountitems.MountItem; import com.facebook.react.fabric.mounting.mountitems.PreAllocateViewMountItem; +import com.facebook.react.fabric.mounting.mountitems.RemoveDeleteMultiMountItem; import com.facebook.react.fabric.mounting.mountitems.RemoveMountItem; +import com.facebook.react.fabric.mounting.mountitems.SendAccessibilityEvent; import com.facebook.react.fabric.mounting.mountitems.UpdateEventEmitterMountItem; import com.facebook.react.fabric.mounting.mountitems.UpdateLayoutMountItem; import com.facebook.react.fabric.mounting.mountitems.UpdateLocalDataMountItem; import com.facebook.react.fabric.mounting.mountitems.UpdatePaddingMountItem; import com.facebook.react.fabric.mounting.mountitems.UpdatePropsMountItem; +import com.facebook.react.fabric.mounting.mountitems.UpdateStateMountItem; import com.facebook.react.uimanager.StateWrapper; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.BatchEventDispatchedListener; @@ -83,7 +89,8 @@ public UIManager get() { private FabricUIManager createUIManager(@NonNull EventBeatManager eventBeatManager) { Systrace.beginSection( Systrace.TRACE_TAG_REACT_JAVA_BRIDGE, "FabricJSIModuleProvider.createUIManager"); - UIManagerModule nativeModule = mReactApplicationContext.getNativeModule(UIManagerModule.class); + UIManagerModule nativeModule = + Assertions.assertNotNull(mReactApplicationContext.getNativeModule(UIManagerModule.class)); EventDispatcher eventDispatcher = nativeModule.getEventDispatcher(); FabricUIManager fabricUIManager = new FabricUIManager( @@ -99,33 +106,38 @@ private FabricUIManager createUIManager(@NonNull EventBeatManager eventBeatManag // TODO T31905686: eager load Fabric classes, this is temporary and it will be removed // in the near future private static void loadClasses() { - BatchEventDispatchedListener.class.getClass(); - ReactNativeConfig.class.getClass(); - FabricComponents.class.getClass(); - StateWrapper.class.getClass(); + EventBeatManager.class.getClass(); + EventEmitterWrapper.class.getClass(); FabricEventEmitter.class.getClass(); - FabricUIManager.class.getClass(); - GuardedFrameCallback.class.getClass(); BatchMountItem.class.getClass(); + CreateMountItem.class.getClass(); DeleteMountItem.class.getClass(); + DispatchCommandMountItem.class.getClass(); DispatchIntCommandMountItem.class.getClass(); DispatchStringCommandMountItem.class.getClass(); InsertMountItem.class.getClass(); MountItem.class.getClass(); + PreAllocateViewMountItem.class.getClass(); + RemoveDeleteMultiMountItem.class.getClass(); RemoveMountItem.class.getClass(); + SendAccessibilityEvent.class.getClass(); UpdateEventEmitterMountItem.class.getClass(); UpdateLayoutMountItem.class.getClass(); UpdateLocalDataMountItem.class.getClass(); UpdatePaddingMountItem.class.getClass(); UpdatePropsMountItem.class.getClass(); + UpdateStateMountItem.class.getClass(); LayoutMetricsConversions.class.getClass(); MountingManager.class.getClass(); Binding.class.getClass(); ComponentFactoryDelegate.class.getClass(); - EventBeatManager.class.getClass(); - EventEmitterWrapper.class.getClass(); - StateWrapperImpl.class.getClass(); + FabricComponents.class.getClass(); FabricSoLoader.class.getClass(); - PreAllocateViewMountItem.class.getClass(); + FabricUIManager.class.getClass(); + GuardedFrameCallback.class.getClass(); + StateWrapper.class.getClass(); + StateWrapperImpl.class.getClass(); + BatchEventDispatchedListener.class.getClass(); + ReactNativeConfig.class.getClass(); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index d63206e3f2267c..e5239c8db9835d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -17,6 +17,7 @@ import static com.facebook.react.uimanager.common.UIManagerType.FABRIC; import android.annotation.SuppressLint; +import android.content.Context; import android.os.SystemClock; import android.view.View; import androidx.annotation.AnyThread; @@ -195,6 +196,7 @@ public int addRootView( return rootTag; } + @Override @AnyThread @ThreadConfined(ANY) public int startSurface( @@ -204,8 +206,9 @@ public int startSurface( int widthMeasureSpec, int heightMeasureSpec) { final int rootTag = ReactRootViewTagGenerator.getNextRootViewTag(); + Context context = rootView.getContext(); ThemedReactContext reactContext = - new ThemedReactContext(mReactApplicationContext, rootView.getContext(), moduleName); + new ThemedReactContext(mReactApplicationContext, context, moduleName); if (ENABLE_FABRIC_LOGS) { FLog.d(TAG, "Starting surface for module: %s and reactTag: %d", moduleName, rootTag); } @@ -219,8 +222,8 @@ public int startSurface( getMaxSize(widthMeasureSpec), getMinSize(heightMeasureSpec), getMaxSize(heightMeasureSpec), - I18nUtil.getInstance().isRTL(rootView.getContext()), - I18nUtil.getInstance().doLeftAndRightSwapInRTL(rootView.getContext())); + I18nUtil.getInstance().isRTL(context), + I18nUtil.getInstance().doLeftAndRightSwapInRTL(context)); return rootTag; } @@ -522,7 +525,6 @@ private void scheduleMountItem( long layoutEndTime, long finishTransactionStartTime, long finishTransactionEndTime) { - // TODO T31905686: support multithreading // When Binding.cpp calls scheduleMountItems during a commit phase, it always calls with // a BatchMountItem. No other sites call into this with a BatchMountItem, and Binding.cpp only // calls scheduleMountItems with a BatchMountItem. @@ -842,12 +844,6 @@ public void updateRootLayoutSpecs( if (reactContext != null) { isRTL = I18nUtil.getInstance().isRTL(reactContext); doLeftAndRightSwapInRTL = I18nUtil.getInstance().doLeftAndRightSwapInRTL(reactContext); - } else { - // TODO T65116569: analyze why this happens - ReactSoftException.logSoftException( - TAG, - new IllegalStateException( - "updateRootLayoutSpecs called before ReactContext set for tag: " + rootTag)); } mBinding.setConstraints( diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK index fc4d7c9c768531..83d5ba3a4fb4fc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/BUCK @@ -18,6 +18,7 @@ rn_xplat_cxx_library( "-frtti", ], fbandroid_allow_jni_merging = True, + labels = ["supermodule:android/default/public.react_native.infra"], platforms = (ANDROID), preprocessor_flags = [ "-DLOG_TAG=\"ReactNative\"", @@ -32,7 +33,7 @@ rn_xplat_cxx_library( react_native_xplat_target("fabric/scheduler:scheduler"), react_native_xplat_target("fabric/componentregistry:componentregistry"), react_native_xplat_target("fabric/components/scrollview:scrollview"), - react_native_xplat_target("utils:utils"), + react_native_xplat_target("runtimeexecutor:runtimeexecutor"), react_native_target("jni/react/jni:jni"), "//xplat/fbsystrace:fbsystrace", "//xplat/folly:molly", diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h index 5a36037c7d3334..5ed943f226cec2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/jni/EventBeatManager.h @@ -10,9 +10,9 @@ #include #include +#include #include #include -#include namespace facebook { namespace react { diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/UpdateStateMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/UpdateStateMountItem.java index 2eae18797061a9..4544e8f935e23e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/UpdateStateMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/UpdateStateMountItem.java @@ -35,7 +35,7 @@ public String toString() { new StringBuilder("UpdateStateMountItem [").append(mReactTag).append("]"); if (IS_DEVELOPMENT_ENVIRONMENT) { - result.append(" state: ").append(mStateWrapper != null ? mStateWrapper : ""); + result.append(" state: ").append(mStateWrapper != null ? mStateWrapper.getState() : ""); } return result.toString(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/BUCK b/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/BUCK index ef047b2e31f02e..1f1f74690a4719 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/jscexecutor/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "ANDROID", "FBJNI_TARGET", "react_nat rn_android_library( name = "jscexecutor", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/jstasks/BUCK b/ReactAndroid/src/main/java/com/facebook/react/jstasks/BUCK index fa2fc5ceadf033..b2cdc99110b575 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/jstasks/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/jstasks/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "jstasks", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/module/annotations/BUCK b/ReactAndroid/src/main/java/com/facebook/react/module/annotations/BUCK index 211b98157bf10e..f081fc83a17774 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/module/annotations/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/module/annotations/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "annotations", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/module/model/BUCK b/ReactAndroid/src/main/java/com/facebook/react/module/model/BUCK index b76f609c809272..59e700971e872b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/module/model/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/module/model/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "rn_android_libra rn_android_library( name = "model", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/module/processing/BUCK b/ReactAndroid/src/main/java/com/facebook/react/module/processing/BUCK index 663c170036449a..b2c8041bdc6981 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/module/processing/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/module/processing/BUCK @@ -15,6 +15,7 @@ rn_java_annotation_processor( rn_java_library( name = "processing-lib", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], source = "8", target = "8", deps = [ diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/BUCK index c7d1ffc46c759e..5d0fa7d9d1c958 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/accessibilityinfo/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "accessibilityinfo", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/BUCK index 60c8584e16c264..62802072e94797 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/appearance/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "appearance", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/appregistry/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/appregistry/BUCK index 5ea989b39c9429..dc2c4d824b2a52 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/appregistry/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/appregistry/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_target", "rn_android_li rn_android_library( name = "appregistry", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/BUCK index b3e191047dc295..3b873f61574438 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/appstate/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "appstate", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BUCK index aedfca7dd5888f..0a4d2b472e2210 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "blob", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BUCK index 4bd4ee666c3d62..2ab5488c94a15f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/blob/jni/BUCK @@ -11,6 +11,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + labels = ["supermodule:android/default/public.react_native.infra"], platforms = ANDROID, soname = "libreactnativeblob.$(ext)", visibility = ["PUBLIC"], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/camera/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/camera/BUCK index 775fd1db0f00c1..01e0240e5b7dee 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/camera/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/camera/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "camera", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/BUCK index 9e0390ea8527b8..c3fa4b7884140b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/clipboard/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "clipboard", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/common/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/common/BUCK index 938ef3c649f912..c8376f61beec51 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/common/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/common/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "common", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/core/BUCK index 9432c4513c5e4b..4e8a8ee3fafff2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "core", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK index 4a5b7eeb92f7ed..91683c6f233033 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/datepicker/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "datepicker", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/BUCK index 61950b38fbe2ba..2f0d2caef1a471 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "debug", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], @@ -29,6 +30,7 @@ rn_android_library( rn_android_library( name = "interfaces", srcs = glob(["interfaces/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.java b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.java index 6eae4d7a5c8200..df4b653cc9bfce 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/debug/FpsDebugFrameCallback.java @@ -75,7 +75,8 @@ public FpsInfo( public FpsDebugFrameCallback(ReactContext reactContext) { mReactContext = reactContext; - mUIManagerModule = reactContext.getNativeModule(UIManagerModule.class); + mUIManagerModule = + Assertions.assertNotNull(reactContext.getNativeModule(UIManagerModule.class)); mDidJSUpdateUiDuringFrameDetector = new DidJSUpdateUiDuringFrameDetector(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK index 0f33ea66f71e80..a33ecbf2677641 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "deviceinfo", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/BUCK index 93cae84131f6e4..1987e6e9223e16 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/dialog/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "dialog", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/fabric/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/fabric/BUCK index b19a3c20bbc8df..5bbb74d994b22f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/fabric/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/fabric/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_target", "rn_android_li rn_android_library( name = "fabric", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ ], visibility = [ diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/BUCK index 0e467a7738e3f9..fd6819910638ce 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "fresco", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java index df26770d309376..ac70eff2adcc19 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/fresco/FrescoModule.java @@ -12,6 +12,7 @@ import com.facebook.common.logging.FLog; import com.facebook.drawee.backends.pipeline.Fresco; import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory; +import com.facebook.imagepipeline.core.ImagePipeline; import com.facebook.imagepipeline.core.ImagePipelineConfig; import com.facebook.imagepipeline.listener.RequestListener; import com.facebook.react.bridge.LifecycleEventListener; @@ -41,6 +42,7 @@ public class FrescoModule extends ReactContextBaseJavaModule public static final String NAME = "FrescoModule"; private final boolean mClearOnDestroy; private @Nullable ImagePipelineConfig mConfig; + private @Nullable ImagePipeline mImagePipeline; private static boolean sHasBeenInitialized = false; @@ -66,6 +68,20 @@ public FrescoModule(ReactApplicationContext reactContext, boolean clearOnDestroy this(reactContext, clearOnDestroy, null); } + /** + * Create a new Fresco module with a default configuration (or the previously given configuration + * via {@link #FrescoModule(ReactApplicationContext, boolean, ImagePipelineConfig)}. + * + * @param clearOnDestroy whether to clear the memory cache in onHostDestroy: this should be {@code + * true} for pure RN apps and {@code false} for apps that use Fresco outside of RN as well + * @param reactContext the context to use + */ + public FrescoModule( + ReactApplicationContext reactContext, ImagePipeline imagePipeline, boolean clearOnDestroy) { + this(reactContext, clearOnDestroy); + mImagePipeline = imagePipeline; + } + /** * Create a new Fresco module with a given ImagePipelineConfig. This should only be called when * the module has not been initialized yet. You can use {@link #hasBeenInitialized()} to check @@ -114,7 +130,7 @@ public String getName() { @Override public void clearSensitiveData() { // Clear image cache. - Fresco.getImagePipeline().clearCaches(); + getImagePipeline().clearCaches(); } /** @@ -168,7 +184,14 @@ public void onHostDestroy() { // the 'last' ReactActivity is being destroyed, which effectively means the app is being // backgrounded. if (hasBeenInitialized() && mClearOnDestroy) { - Fresco.getImagePipeline().clearMemoryCaches(); + getImagePipeline().clearMemoryCaches(); + } + } + + private ImagePipeline getImagePipeline() { + if (mImagePipeline == null) { + mImagePipeline = Fresco.getImagePipeline(); } + return mImagePipeline; } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/BUCK index 36bb281dc280c0..a00c306f8da8a4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/i18nmanager/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "i18nmanager", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/image/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/image/BUCK index 519a07adcba933..d924754e990d0e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/image/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/image/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "image", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], @@ -20,6 +21,7 @@ rn_android_library( react_native_target("java/com/facebook/react/modules/fresco:fresco"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/views/imagehelper:imagehelper"), + react_native_target("java/com/facebook/react/views/image:image"), ], exported_deps = [ react_native_target("java/com/facebook/fbreact/specs:FBReactNativeSpec"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java index aca084ed9f307c..71fb0a809c816f 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/image/ImageLoaderModule.java @@ -9,6 +9,7 @@ import android.net.Uri; import android.util.SparseArray; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.facebook.common.executors.CallerThreadExecutor; import com.facebook.common.references.CloseableReference; @@ -32,6 +33,7 @@ import com.facebook.react.bridge.WritableMap; import com.facebook.react.module.annotations.ReactModule; import com.facebook.react.modules.fresco.ReactNetworkImageRequest; +import com.facebook.react.views.image.ReactCallerContextFactory; import com.facebook.react.views.imagehelper.ImageSource; @ReactModule(name = ImageLoaderModule.NAME) @@ -43,9 +45,11 @@ public class ImageLoaderModule extends NativeImageLoaderAndroidSpec private static final String ERROR_GET_SIZE_FAILURE = "E_GET_SIZE_FAILURE"; public static final String NAME = "ImageLoader"; - private final Object mCallerContext; + private @Nullable final Object mCallerContext; private final Object mEnqueuedRequestMonitor = new Object(); private final SparseArray> mEnqueuedRequests = new SparseArray<>(); + private @Nullable ImagePipeline mImagePipeline = null; + private @Nullable ReactCallerContextFactory mCallerContextFactory; public ImageLoaderModule(ReactApplicationContext reactContext) { super(reactContext); @@ -57,11 +61,32 @@ public ImageLoaderModule(ReactApplicationContext reactContext, Object callerCont mCallerContext = callerContext; } + public ImageLoaderModule( + ReactApplicationContext reactContext, + ImagePipeline imagePipeline, + ReactCallerContextFactory callerContextFactory) { + super(reactContext); + mCallerContextFactory = callerContextFactory; + mImagePipeline = imagePipeline; + mCallerContext = null; + } + + private @Nullable Object getCallerContext() { + return mCallerContextFactory != null + ? mCallerContextFactory.getOrCreateCallerContext("", "") + : mCallerContext; + } + @Override + @NonNull public String getName() { return NAME; } + private ImagePipeline getImagePipeline() { + return mImagePipeline != null ? mImagePipeline : Fresco.getImagePipeline(); + } + /** * Fetch the width and height of the given image. * @@ -80,7 +105,7 @@ public void getSize(final String uriString, final Promise promise) { ImageRequest request = ImageRequestBuilder.newBuilderWithSource(source.getUri()).build(); DataSource> dataSource = - Fresco.getImagePipeline().fetchDecodedImage(request, mCallerContext); + getImagePipeline().fetchDecodedImage(request, getCallerContext()); DataSubscriber> dataSubscriber = new BaseDataSubscriber>() { @@ -141,7 +166,7 @@ public void getSizeWithHeaders( ReactNetworkImageRequest.fromBuilderWithHeaders(imageRequestBuilder, headers); DataSource> dataSource = - Fresco.getImagePipeline().fetchDecodedImage(request, mCallerContext); + getImagePipeline().fetchDecodedImage(request, getCallerContext()); DataSubscriber> dataSubscriber = new BaseDataSubscriber>() { @@ -201,7 +226,7 @@ public void prefetchImage( ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).build(); DataSource prefetchSource = - Fresco.getImagePipeline().prefetchToDiskCache(request, mCallerContext); + getImagePipeline().prefetchToDiskCache(request, getCallerContext()); DataSubscriber prefetchSubscriber = new BaseDataSubscriber() { @Override @@ -212,6 +237,8 @@ protected void onNewResultImpl(DataSource dataSource) { try { removeRequest(requestId); promise.resolve(true); + } catch (Exception e) { + promise.reject(ERROR_PREFETCH_FAILURE, e); } finally { dataSource.close(); } @@ -246,7 +273,7 @@ public void queryCache(final ReadableArray uris, final Promise promise) { @Override protected void doInBackgroundGuarded(Void... params) { WritableMap result = Arguments.createMap(); - ImagePipeline imagePipeline = Fresco.getImagePipeline(); + ImagePipeline imagePipeline = getImagePipeline(); for (int i = 0; i < uris.size(); i++) { String uriString = uris.getString(i); final Uri uri = Uri.parse(uriString); diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/intent/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/intent/BUCK index 616d73ed7507a5..a7f538cc2ea321 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/intent/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/intent/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "intent", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/network/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/network/BUCK index fb4b470d71e615..ccb9013abe9045 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/network/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/network/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "network", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK index e947137a59ba69..484e374c72a94c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/permissions/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "permissions", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/share/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/share/BUCK index 0e45037b0cee9e..11288aa404c14c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/share/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/share/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "share", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/sound/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/sound/BUCK index ac4b1d2f0920c2..8e199ed82a85e2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/sound/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/sound/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "sound", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ ], visibility = [ diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/BUCK index 4082dcd67a9148..8643e041815f6a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/statusbar/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "statusbar", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/storage/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/storage/BUCK index 81a13ec37975bf..2231b08feec476 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/storage/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/storage/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "storage", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java index 24c6f4deb4cbfc..3c4be024f518c5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/AndroidInfoModule.java @@ -12,12 +12,10 @@ import android.annotation.SuppressLint; import android.app.UiModeManager; import android.content.res.Configuration; -import android.content.res.Resources; import android.os.Build; import android.provider.Settings.Secure; import androidx.annotation.Nullable; import com.facebook.fbreact.specs.NativePlatformConstantsAndroidSpec; -import com.facebook.react.R; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.common.build.ReactBuildConfig; import com.facebook.react.module.annotations.ReactModule; @@ -73,7 +71,9 @@ public String getName() { constants.put("Fingerprint", Build.FINGERPRINT); constants.put("Model", Build.MODEL); if (ReactBuildConfig.DEBUG) { - constants.put("ServerHost", getServerHost()); + constants.put( + "ServerHost", + AndroidInfoHelpers.getServerHost(getReactApplicationContext().getApplicationContext())); } constants.put( "isTesting", "true".equals(System.getProperty(IS_TESTING)) || isRunningScreenshotTest()); @@ -98,12 +98,4 @@ private Boolean isRunningScreenshotTest() { return false; } } - - private String getServerHost() { - Resources resources = getReactApplicationContext().getApplicationContext().getResources(); - - Integer devServerPort = resources.getInteger(R.integer.react_native_dev_server_port); - - return AndroidInfoHelpers.getServerHost(devServerPort); - } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK index 30e4988a0fad6c..afc48e3db35129 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/BUCK @@ -7,6 +7,7 @@ rn_android_library( "ReactNativeVersion.java", ], is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], @@ -31,6 +32,7 @@ rn_android_library( "AndroidInfoHelpers.java", ], is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/timepicker/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/timepicker/BUCK index 9740b735f71328..dac030819debc6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/timepicker/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/timepicker/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "timepicker", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/toast/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/toast/BUCK index a297071e700324..fb3b79960fe585 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/toast/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/toast/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "toast", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/BUCK index d817e4149e38e1..219a1d36feb288 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/vibration/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "vibration", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/BUCK b/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/BUCK index 26f6686d14a861..4299354a4a6d76 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/websocket/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "websocket", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK index 092745fd177118..1cfd88bfc35a01 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/packagerconnection/BUCK @@ -6,6 +6,7 @@ rn_android_library( ["**/*.java"], ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/processing/BUCK b/ReactAndroid/src/main/java/com/facebook/react/processing/BUCK index f88f4fe679b860..5ff37878c58a18 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/processing/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/processing/BUCK @@ -15,6 +15,7 @@ rn_java_annotation_processor( rn_java_library( name = "processing-lib", srcs = glob(["*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], source = "7", target = "7", deps = [ diff --git a/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK b/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK index 4df1ab9930362d..5f114f91e88e13 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/shell/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "shell", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), @@ -51,7 +52,6 @@ rn_android_library( react_native_target("java/com/facebook/react/modules/websocket:websocket"), react_native_target("java/com/facebook/react/turbomodule/core/interfaces:interfaces"), react_native_target("java/com/facebook/react/uimanager:uimanager"), - react_native_target("java/com/facebook/react/views/art:art"), react_native_target("java/com/facebook/react/views/drawer:drawer"), react_native_target("java/com/facebook/react/views/image:image"), react_native_target("java/com/facebook/react/views/modal:modal"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java b/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java index 7c60cda3300a9d..e5d6f99a3186b9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java +++ b/ReactAndroid/src/main/java/com/facebook/react/shell/MainReactPackage.java @@ -43,8 +43,6 @@ import com.facebook.react.modules.websocket.WebSocketModule; import com.facebook.react.turbomodule.core.interfaces.TurboModule; import com.facebook.react.uimanager.ViewManager; -import com.facebook.react.views.art.ARTRenderableViewManager; -import com.facebook.react.views.art.ARTSurfaceViewManager; import com.facebook.react.views.drawer.ReactDrawerLayoutManager; import com.facebook.react.views.image.ReactImageManager; import com.facebook.react.views.modal.ReactModalHostManager; @@ -174,9 +172,6 @@ public MainReactPackage(MainPackageConfig config) { public List createViewManagers(ReactApplicationContext reactContext) { List viewManagers = new ArrayList<>(); - viewManagers.add(ARTRenderableViewManager.createARTGroupViewManager()); - viewManagers.add(ARTRenderableViewManager.createARTShapeViewManager()); - viewManagers.add(ARTRenderableViewManager.createARTTextViewManager()); viewManagers.add(new ReactDialogPickerManager()); viewManagers.add(new ReactDrawerLayoutManager()); viewManagers.add(new ReactDropdownPickerManager()); @@ -189,7 +184,6 @@ public List createViewManagers(ReactApplicationContext reactContext viewManagers.add(new SwipeRefreshLayoutManager()); // Native equivalents - viewManagers.add(new ARTSurfaceViewManager()); viewManagers.add(new FrescoBasedReactTextInlineImageViewManager()); viewManagers.add(new ReactImageManager()); viewManagers.add(new ReactModalHostManager()); diff --git a/ReactAndroid/src/main/java/com/facebook/react/surface/BUCK b/ReactAndroid/src/main/java/com/facebook/react/surface/BUCK index ad6bcd33c4a20d..7ea360411204d6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/surface/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/surface/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "surface", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK b/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK index bcd493aaf746b8..c57d2e682f350d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/touch/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "touch", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK index f3e34f4e46effc..7547027a771a8d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/BUCK @@ -8,6 +8,7 @@ rn_android_library( ], exclude = ["CallInvokerHolderImpl.java"], ), + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", @@ -38,6 +39,7 @@ rn_android_library( rn_android_library( name = "callinvokerholder", srcs = ["CallInvokerHolderImpl.java"], + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java index 004c8e8a7407a0..6b01a2008308ad 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/TurboModuleManager.java @@ -19,6 +19,7 @@ import com.facebook.react.bridge.JavaScriptContextHolder; import com.facebook.react.bridge.NativeModule; import com.facebook.react.common.ReactConstants; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.react.turbomodule.core.interfaces.CallInvokerHolder; import com.facebook.react.turbomodule.core.interfaces.TurboModule; import com.facebook.react.turbomodule.core.interfaces.TurboModuleRegistry; @@ -32,7 +33,7 @@ */ public class TurboModuleManager implements JSIModule, TurboModuleRegistry { private static volatile boolean sIsSoLibraryLoaded; - private final List mEagerInitModuleNames = new ArrayList<>(); + private final List mEagerInitModuleNames; private final TurboModuleProvider mJavaModuleProvider; private final TurboModuleProvider mCxxModuleProvider; @@ -64,11 +65,8 @@ public TurboModuleManager( delegate); installJSIBindings(); - if (delegate != null) { - synchronized (delegate) { - mEagerInitModuleNames.addAll(delegate.getEagerInitModuleNames()); - } - } + mEagerInitModuleNames = + delegate == null ? new ArrayList() : delegate.getEagerInitModuleNames(); mJavaModuleProvider = new TurboModuleProvider() { @@ -78,10 +76,7 @@ public TurboModule getModule(String moduleName) { return null; } - /** TODO(T65532092): Should TurboModuleManagerDelegate be thread-safe? */ - synchronized (delegate) { - return delegate.getModule(moduleName); - } + return delegate.getModule(moduleName); } }; @@ -93,13 +88,7 @@ public TurboModule getModule(String moduleName) { return null; } - CxxModuleWrapper nativeModule; - - /** TODO(T65532092): Should TurboModuleManagerDelegate be thread-safe? */ - synchronized (delegate) { - nativeModule = delegate.getLegacyCxxModule(moduleName); - } - + CxxModuleWrapper nativeModule = delegate.getLegacyCxxModule(moduleName); if (nativeModule != null) { // TurboModuleManagerDelegate must always return TurboModules Assertions.assertCondition( @@ -116,24 +105,52 @@ public List getEagerInitModuleNames() { return mEagerInitModuleNames; } + @DoNotStrip + @Nullable + private CxxModuleWrapper getLegacyCxxModule(String moduleName) { + final TurboModule turboModule = getModule(moduleName); + if (!(turboModule instanceof CxxModuleWrapper)) { + return null; + } + + return (CxxModuleWrapper) turboModule; + } + + @DoNotStrip + @Nullable + private TurboModule getJavaModule(String moduleName) { + final TurboModule turboModule = getModule(moduleName); + if (turboModule instanceof CxxModuleWrapper) { + return null; + } + + return turboModule; + } + /** - * TurboModuleHolders are used as locks to ensure that when n threads race to create a - * TurboModule, only the first thread creates that TurboModule. All other n - 1 threads wait until - * the TurboModule is created and initialized. + * Return the TurboModule instance that corresponds to the provided moduleName. + * + *

This method: - Creates and initializes the module if it doesn't already exist. - Returns + * null after TurboModuleManager has been torn down. */ @Nullable - private TurboModuleHolder getOrMaybeCreateTurboModuleHolder(String moduleName) { + public TurboModule getModule(String moduleName) { + TurboModuleHolder moduleHolder; + synchronized (mTurboModuleCleanupLock) { if (mTurboModuleCleanupStarted) { /* * Always return null after cleanup has started, so that getModule(moduleName) returns null. */ - FLog.e( - ReactConstants.TAG, - "TurboModuleManager.getOrMaybeCreateTurboModuleHolder: Tried to require TurboModule " - + moduleName - + " after cleanup initiated"); + if (ReactFeatureFlags.enableTurboModuleDebugLogs) { + // TODO(T46487253): Remove after task is closed + FLog.e( + ReactConstants.TAG, + "TurboModuleManager.getOrMaybeCreateTurboModuleHolder: Tried to require TurboModule " + + moduleName + + " after cleanup initiated"); + } return null; } @@ -144,24 +161,22 @@ private TurboModuleHolder getOrMaybeCreateTurboModuleHolder(String moduleName) { if (!mTurboModuleHolders.containsKey(moduleName)) { mTurboModuleHolders.put(moduleName, new TurboModuleHolder()); } - return mTurboModuleHolders.get(moduleName); + + moduleHolder = mTurboModuleHolders.get(moduleName); } + + return getModule(moduleName, moduleHolder); } /** - * If n threads race to create TurboModule x, then only the first thread should create x. All n - - * 1 other threads should wait until x is created and initialized. + * Given a TurboModuleHolder, and the TurboModule's moduleName, return the TurboModule instance. * - *

Note: After we've started cleanup, getModule will always return null. + *

Use the TurboModuleHolder to ensure that if n threads race to create TurboModule x, then + * only the first thread creates x. All n - 1 other threads wait until the x is created and + * initialized. */ @Nullable - public TurboModule getModule(String moduleName) { - final TurboModuleHolder moduleHolder = getOrMaybeCreateTurboModuleHolder(moduleName); - - if (moduleHolder == null) { - return null; - } - + private TurboModule getModule(String moduleName, @NonNull TurboModuleHolder moduleHolder) { boolean shouldCreateModule = false; synchronized (moduleHolder) { @@ -232,28 +247,6 @@ public TurboModule getModule(String moduleName) { } } - @DoNotStrip - @Nullable - private CxxModuleWrapper getLegacyCxxModule(String moduleName) { - final TurboModule turboModule = getModule(moduleName); - if (!(turboModule instanceof CxxModuleWrapper)) { - return null; - } - - return (CxxModuleWrapper) turboModule; - } - - @DoNotStrip - @Nullable - private TurboModule getJavaModule(String moduleName) { - final TurboModule turboModule = getModule(moduleName); - if (turboModule instanceof CxxModuleWrapper) { - return null; - } - - return turboModule; - } - /** Which TurboModules have been created? */ public Collection getModules() { final List turboModuleHolders = new ArrayList<>(); @@ -317,11 +310,17 @@ public void onCatalystInstanceDestroy() { mTurboModuleCleanupStarted = true; } - final Set turboModuleNames = new HashSet<>(mTurboModuleHolders.keySet()); + for (final Map.Entry moduleHolderEntry : + mTurboModuleHolders.entrySet()) { + final String moduleName = moduleHolderEntry.getKey(); + final TurboModuleHolder moduleHolder = moduleHolderEntry.getValue(); - for (final String moduleName : turboModuleNames) { - // Retrieve the TurboModule, possibly waiting for it to finish instantiating. - final TurboModule turboModule = getModule(moduleName); + /** + * ReactNative could start tearing down before this particular TurboModule has been fully + * initialized. In this case, we should wait for initialization to complete, before destroying + * the TurboModule. + */ + final TurboModule turboModule = getModule(moduleName, moduleHolder); if (turboModule != null) { // TODO(T48014458): Rename this to invalidate() diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK index e48328e07291ae..3e07e5c5355a80 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/interfaces/BUCK @@ -6,6 +6,7 @@ rn_android_library( ["*.java"], ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK index 4de25abe7deacc..183194f3d47dd9 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/turbomodule/core/jni/BUCK @@ -17,6 +17,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + labels = ["supermodule:android/default/public.react_native.infra"], platforms = ANDROID, preprocessor_flags = [ "-DLOG_TAG=\"ReactNative\"", @@ -55,6 +56,7 @@ rn_xplat_cxx_library( fbandroid_deps = [ FBJNI_TARGET, ], + labels = ["supermodule:android/default/public.react_native.infra"], platforms = ANDROID, preferred_linkage = "static", preprocessor_flags = [ diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK index 33eeffd0434703..a88d679b87f4f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/BUCK @@ -14,6 +14,7 @@ rn_android_library( ], ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), @@ -59,6 +60,7 @@ rn_android_library( "DisplayMetricsHolder.java", ], is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java index 26d958570bc86c..35c9ff92013033 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/NativeViewHierarchyManager.java @@ -7,8 +7,8 @@ package com.facebook.react.uimanager; -import android.content.res.Resources; import android.graphics.Matrix; +import android.graphics.Rect; import android.graphics.RectF; import android.util.SparseArray; import android.util.SparseBooleanArray; @@ -701,14 +701,12 @@ public synchronized void measureInWindow(int tag, int[] outputBuffer) { v.getLocationOnScreen(outputBuffer); - // We need to remove the status bar from the height. getLocationOnScreen will include the - // status bar. - Resources resources = v.getContext().getResources(); - int statusBarId = resources.getIdentifier("status_bar_height", "dimen", "android"); - if (statusBarId > 0) { - int height = (int) resources.getDimension(statusBarId); - outputBuffer[1] -= height; - } + // we need to subtract visibleWindowCoords - to subtract possible window insets, split screen or + // multi window + Rect visibleWindowFrame = new Rect(); + v.getWindowVisibleDisplayFrame(visibleWindowFrame); + outputBuffer[0] = outputBuffer[0] - visibleWindowFrame.left; + outputBuffer[1] = outputBuffer[1] - visibleWindowFrame.top; // outputBuffer[0,1] already contain what we want outputBuffer[2] = v.getWidth(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java index a97220763e4621..2fba8c52164c75 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ReactRoot.java @@ -41,9 +41,10 @@ public interface ReactRoot { /** Return native view for root */ ViewGroup getRootViewGroup(); - /** @return Cached values for widthMeasureSpec and heightMeasureSpec */ + /** @return Cached values for widthMeasureSpec. */ int getWidthMeasureSpec(); + /** @return Cached values for and heightMeasureSpec. */ int getHeightMeasureSpec(); /** Sets a flag that determines whether to log that content appeared on next view added. */ diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java index 8fdf52866ca7c1..0a5d5bb83a1345 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIImplementation.java @@ -805,7 +805,7 @@ private void measureLayoutRelativeToVerifiedAncestor( ReactShadowNode node, ReactShadowNode ancestor, int[] outputBuffer) { int offsetX = 0; int offsetY = 0; - if (node != ancestor) { + if (node != ancestor && !node.isVirtual()) { offsetX = Math.round(node.getLayoutX()); offsetY = Math.round(node.getLayoutY()); ReactShadowNode current = node.getParent(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 9d7879d425d2ae..d753e252a567c4 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -425,6 +425,16 @@ public int addRootView( return tag; } + @Override + public int startSurface( + final T rootView, + final String moduleName, + final WritableMap initialProps, + int widthMeasureSpec, + int heightMeasureSpec) { + throw new UnsupportedOperationException(); + } + /** Unregisters a new root view. */ @ReactMethod public void removeRootView(int rootViewTag) { @@ -807,6 +817,7 @@ public void setViewHierarchyUpdateDebugListener( mUIImplementation.setViewHierarchyUpdateDebugListener(listener); } + @Override public EventDispatcher getEventDispatcher() { return mEventDispatcher; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java index 9c2eed060a7110..4f8844cba117ad 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIViewOperationQueue.java @@ -113,11 +113,14 @@ public EmitOnLayoutEventOperation( @Override public void execute() { - mReactApplicationContext - .getNativeModule(UIManagerModule.class) - .getEventDispatcher() - .dispatchEvent( - OnLayoutEvent.obtain(mTag, mScreenX, mScreenY, mScreenWidth, mScreenHeight)); + UIManagerModule uiManager = mReactApplicationContext.getNativeModule(UIManagerModule.class); + + if (uiManager != null) { + uiManager + .getEventDispatcher() + .dispatchEvent( + OnLayoutEvent.obtain(mTag, mScreenX, mScreenY, mScreenWidth, mScreenHeight)); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/annotations/BUCK b/ReactAndroid/src/main/java/com/facebook/react/uimanager/annotations/BUCK index 3ecec7beea0e36..39953cea578b08 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/annotations/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/annotations/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "annotations", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/BUCK b/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/BUCK index f3b3d20aaaa3f6..9f54d4ad220281 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/common/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "common", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/BUCK b/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/BUCK index 446c2dce76055b..1f67fb5365cf5e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/util/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "util", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/util/BUCK b/ReactAndroid/src/main/java/com/facebook/react/util/BUCK index b78a3fd8e3d8c8..84188101bbfc06 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/util/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/util/BUCK @@ -3,6 +3,7 @@ load("//tools/build_defs/oss:rn_defs.bzl", "react_native_dep", "react_native_tar rn_android_library( name = "util", srcs = glob(["**/*.java"]), + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/BUCK b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/BUCK index 16bd74bbb87148..d950d48939265a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "viewmanagers", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerDelegate.java new file mode 100644 index 00000000000000..29288a63c8911a --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerDelegate.java @@ -0,0 +1,62 @@ +/** +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; +import com.facebook.react.uimanager.LayoutShadowNode; + +public class DatePickerManagerDelegate & DatePickerManagerInterface> extends BaseViewManagerDelegate { + public DatePickerManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "date": + mViewManager.setDate(view, value == null ? 0f : ((Double) value).floatValue()); + break; + case "initialDate": + mViewManager.setInitialDate(view, value == null ? 0f : ((Double) value).floatValue()); + break; + case "locale": + mViewManager.setLocale(view, value == null ? null : (String) value); + break; + case "maximumDate": + mViewManager.setMaximumDate(view, value == null ? 0f : ((Double) value).floatValue()); + break; + case "minimumDate": + mViewManager.setMinimumDate(view, value == null ? 0f : ((Double) value).floatValue()); + break; + case "minuteInterval": + mViewManager.setMinuteInterval(view, value == null ? 1 : ((Double) value).intValue()); + break; + case "mode": + mViewManager.setMode(view, (String) value); + break; + case "timeZoneOffsetInMinutes": + mViewManager.setTimeZoneOffsetInMinutes(view, value == null ? 0f : ((Double) value).floatValue()); + break; + default: + super.setProperty(view, propName, value); + } + } + + public void receiveCommand(DatePickerManagerInterface viewManager, T view, String commandName, ReadableArray args) { + switch (commandName) { + case "setNativeDate": + viewManager.setNativeDate(view, (float) args.getDouble(0)); + break; + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerInterface.java b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerInterface.java new file mode 100644 index 00000000000000..9df911c7284d3a --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/DatePickerManagerInterface.java @@ -0,0 +1,25 @@ +/** +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; + +public interface DatePickerManagerInterface { + void setDate(T view, float value); + void setInitialDate(T view, float value); + void setLocale(T view, @Nullable String value); + void setMaximumDate(T view, float value); + void setMinimumDate(T view, float value); + void setMinuteInterval(T view, @Nullable Integer value); + void setMode(T view, @Nullable String value); + void setTimeZoneOffsetInMinutes(T view, float value); + void setNativeDate(T view, float date); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerDelegate.java new file mode 100644 index 00000000000000..2d6732ee8d38a2 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerDelegate.java @@ -0,0 +1,51 @@ +/** +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +* @generated by codegen project: GeneratePropsJavaDelegate.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; +import com.facebook.react.bridge.ColorPropConverter; +import com.facebook.react.bridge.ReadableArray; +import com.facebook.react.uimanager.BaseViewManagerDelegate; +import com.facebook.react.uimanager.BaseViewManagerInterface; +import com.facebook.react.uimanager.LayoutShadowNode; + +public class PullToRefreshViewManagerDelegate & PullToRefreshViewManagerInterface> extends BaseViewManagerDelegate { + public PullToRefreshViewManagerDelegate(U viewManager) { + super(viewManager); + } + @Override + public void setProperty(T view, String propName, @Nullable Object value) { + switch (propName) { + case "tintColor": + mViewManager.setTintColor(view, ColorPropConverter.getColor(value, view.getContext())); + break; + case "titleColor": + mViewManager.setTitleColor(view, ColorPropConverter.getColor(value, view.getContext())); + break; + case "title": + mViewManager.setTitle(view, value == null ? null : (String) value); + break; + case "refreshing": + mViewManager.setRefreshing(view, value == null ? false : (boolean) value); + break; + default: + super.setProperty(view, propName, value); + } + } + + public void receiveCommand(PullToRefreshViewManagerInterface viewManager, T view, String commandName, ReadableArray args) { + switch (commandName) { + case "setNativeRefreshing": + viewManager.setNativeRefreshing(view, args.getBoolean(0)); + break; + } + } +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerInterface.java b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerInterface.java new file mode 100644 index 00000000000000..4f40ee89cbba01 --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/PullToRefreshViewManagerInterface.java @@ -0,0 +1,21 @@ +/** +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +* +* @generated by codegen project: GeneratePropsJavaInterface.js +*/ + +package com.facebook.react.viewmanagers; + +import android.view.View; +import androidx.annotation.Nullable; + +public interface PullToRefreshViewManagerInterface { + void setTintColor(T view, @Nullable Integer value); + void setTitleColor(T view, @Nullable Integer value); + void setTitle(T view, @Nullable String value); + void setRefreshing(T view, boolean value); + void setNativeRefreshing(T view, boolean refreshing); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/SwitchManagerDelegate.java b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/SwitchManagerDelegate.java index bee0b8c54f2065..5e419f8bd3fe91 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/SwitchManagerDelegate.java +++ b/ReactAndroid/src/main/java/com/facebook/react/viewmanagers/SwitchManagerDelegate.java @@ -11,6 +11,8 @@ import android.view.View; import androidx.annotation.Nullable; +import com.facebook.react.bridge.ColorPropConverter; +import com.facebook.react.bridge.ReadableArray; import com.facebook.react.uimanager.BaseViewManagerDelegate; import com.facebook.react.uimanager.BaseViewManagerInterface; import com.facebook.react.uimanager.LayoutShadowNode; @@ -29,25 +31,33 @@ public void setProperty(T view, String propName, @Nullable Object value) { mViewManager.setValue(view, value == null ? false : (boolean) value); break; case "tintColor": - mViewManager.setTintColor(view, value == null ? null : ((Double) value).intValue()); + mViewManager.setTintColor(view, ColorPropConverter.getColor(value, view.getContext())); break; case "onTintColor": - mViewManager.setOnTintColor(view, value == null ? null : ((Double) value).intValue()); + mViewManager.setOnTintColor(view, ColorPropConverter.getColor(value, view.getContext())); break; case "thumbTintColor": - mViewManager.setThumbTintColor(view, value == null ? null : ((Double) value).intValue()); + mViewManager.setThumbTintColor(view, ColorPropConverter.getColor(value, view.getContext())); break; case "thumbColor": - mViewManager.setThumbColor(view, value == null ? null : ((Double) value).intValue()); + mViewManager.setThumbColor(view, ColorPropConverter.getColor(value, view.getContext())); break; case "trackColorForFalse": - mViewManager.setTrackColorForFalse(view, value == null ? null : ((Double) value).intValue()); + mViewManager.setTrackColorForFalse(view, ColorPropConverter.getColor(value, view.getContext())); break; case "trackColorForTrue": - mViewManager.setTrackColorForTrue(view, value == null ? null : ((Double) value).intValue()); + mViewManager.setTrackColorForTrue(view, ColorPropConverter.getColor(value, view.getContext())); break; default: super.setProperty(view, propName, value); } } + + public void receiveCommand(SwitchManagerInterface viewManager, T view, String commandName, ReadableArray args) { + switch (commandName) { + case "setValue": + viewManager.setValue(view, args.getBoolean(0)); + break; + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java deleted file mode 100644 index bc941ac54c090c..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupShadowNode.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.RectF; -import androidx.annotation.Nullable; -import com.facebook.react.bridge.JSApplicationIllegalArgumentException; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.uimanager.annotations.ReactProp; - -/** Shadow node for virtual ARTGroup view */ -public class ARTGroupShadowNode extends ARTVirtualNode { - - protected @Nullable RectF mClipping; - - public ARTGroupShadowNode() {} - - @ReactProp(name = "clipping") - public void setClipping(@Nullable ReadableArray clippingDims) { - float[] clippingData = PropHelper.toFloatArray(clippingDims); - if (clippingData != null) { - mClipping = createClipping(clippingData); - markUpdated(); - } - } - - @Override - public boolean isVirtual() { - return true; - } - - public void draw(Canvas canvas, Paint paint, float opacity) { - opacity *= mOpacity; - if (opacity > MIN_OPACITY_FOR_DRAW) { - saveAndSetupCanvas(canvas); - - if (mClipping != null) { - canvas.clipRect( - mClipping.left * mScale, - mClipping.top * mScale, - mClipping.right * mScale, - mClipping.bottom * mScale); - } - - for (int i = 0; i < getChildCount(); i++) { - ARTVirtualNode child = (ARTVirtualNode) getChildAt(i); - child.draw(canvas, paint, opacity); - child.markUpdateSeen(); - } - - restoreCanvas(canvas); - } - } - - /** - * Creates a {@link RectF} from an array of dimensions (e.g. [x, y, width, height]) - * - * @param data the array of dimensions - * @return the {@link RectF} that can used to clip the canvas - */ - private static RectF createClipping(float[] data) { - if (data.length != 4) { - throw new JSApplicationIllegalArgumentException( - "Clipping should be array of length 4 (e.g. [x, y, width, height])"); - } - RectF clippingRect = new RectF(data[0], data[1], data[0] + data[2], data[1] + data[3]); - return clippingRect; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupViewManager.java deleted file mode 100644 index cde81adf02c1c6..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTGroupViewManager.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import com.facebook.react.module.annotations.ReactModule; - -/** ViewManager for shadowed ART group views. */ -@ReactModule(name = ARTRenderableViewManager.CLASS_GROUP) -public class ARTGroupViewManager extends ARTRenderableViewManager { - - /* package */ ARTGroupViewManager() { - super(CLASS_GROUP); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTRenderableViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTRenderableViewManager.java deleted file mode 100644 index c1515647fa324e..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTRenderableViewManager.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.view.View; -import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.ViewManager; - -/** - * ViewManager for all shadowed ART views: Group, Shape and Text. Since these never get rendered - * into native views and don't need any logic (all the logic is in {@link ARTSurfaceView}), this - * "stubbed" ViewManager is used for all of them. - */ -public class ARTRenderableViewManager extends ViewManager { - - public static final String CLASS_GROUP = "ARTGroup"; - public static final String CLASS_SHAPE = "ARTShape"; - public static final String CLASS_TEXT = "ARTText"; - - private final String mClassName; - - public static ARTRenderableViewManager createARTGroupViewManager() { - return new ARTGroupViewManager(); - } - - public static ARTRenderableViewManager createARTShapeViewManager() { - return new ARTShapeViewManager(); - } - - public static ARTRenderableViewManager createARTTextViewManager() { - return new ARTTextViewManager(); - } - - /* package */ ARTRenderableViewManager(String className) { - mClassName = className; - } - - @Override - public String getName() { - return mClassName; - } - - @Override - public ReactShadowNode createShadowNodeInstance() { - if (CLASS_GROUP.equals(mClassName)) { - return new ARTGroupShadowNode(); - } else if (CLASS_SHAPE.equals(mClassName)) { - return new ARTShapeShadowNode(); - } else if (CLASS_TEXT.equals(mClassName)) { - return new ARTTextShadowNode(); - } else { - throw new IllegalStateException("Unexpected type " + mClassName); - } - } - - @Override - public Class getShadowNodeClass() { - if (CLASS_GROUP.equals(mClassName)) { - return ARTGroupShadowNode.class; - } else if (CLASS_SHAPE.equals(mClassName)) { - return ARTShapeShadowNode.class; - } else if (CLASS_TEXT.equals(mClassName)) { - return ARTTextShadowNode.class; - } else { - throw new IllegalStateException("Unexpected type " + mClassName); - } - } - - @Override - protected View createViewInstance(ThemedReactContext reactContext) { - throw new IllegalStateException("ARTShape does not map into a native view"); - } - - @Override - public void updateExtraData(View root, Object extraData) { - throw new IllegalStateException("ARTShape does not map into a native view"); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java deleted file mode 100644 index 380e239347c01a..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeShadowNode.java +++ /dev/null @@ -1,320 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.DashPathEffect; -import android.graphics.LinearGradient; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.RectF; -import android.graphics.Shader; -import androidx.annotation.Nullable; -import com.facebook.common.logging.FLog; -import com.facebook.react.bridge.JSApplicationIllegalArgumentException; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.common.ReactConstants; -import com.facebook.react.uimanager.annotations.ReactProp; - -/** Shadow node for virtual ARTShape view */ -public class ARTShapeShadowNode extends ARTVirtualNode { - - private static final int CAP_BUTT = 0; - private static final int CAP_ROUND = 1; - private static final int CAP_SQUARE = 2; - - private static final int JOIN_BEVEL = 2; - private static final int JOIN_MITER = 0; - private static final int JOIN_ROUND = 1; - - private static final int PATH_TYPE_ARC = 4; - private static final int PATH_TYPE_CLOSE = 1; - private static final int PATH_TYPE_CURVETO = 3; - private static final int PATH_TYPE_LINETO = 2; - private static final int PATH_TYPE_MOVETO = 0; - - // For color type JS and ObjectiveC definitions counterparts - // refer to ReactNativeART.js and RCTConvert+ART.m - private static final int COLOR_TYPE_SOLID_COLOR = 0; - private static final int COLOR_TYPE_LINEAR_GRADIENT = 1; - private static final int COLOR_TYPE_RADIAL_GRADIENT = 2; - private static final int COLOR_TYPE_PATTERN = 3; - - protected @Nullable Path mPath; - private @Nullable float[] mStrokeColor; - private @Nullable float[] mBrushData; - private @Nullable float[] mStrokeDash; - private float mStrokeWidth = 1; - private int mStrokeCap = CAP_ROUND; - private int mStrokeJoin = JOIN_ROUND; - - public ARTShapeShadowNode() {} - - @ReactProp(name = "d") - public void setShapePath(@Nullable ReadableArray shapePath) { - float[] pathData = PropHelper.toFloatArray(shapePath); - mPath = createPath(pathData); - markUpdated(); - } - - @ReactProp(name = "stroke") - public void setStroke(@Nullable ReadableArray strokeColors) { - mStrokeColor = PropHelper.toFloatArray(strokeColors); - markUpdated(); - } - - @ReactProp(name = "strokeDash") - public void setStrokeDash(@Nullable ReadableArray strokeDash) { - mStrokeDash = PropHelper.toFloatArray(strokeDash); - markUpdated(); - } - - @ReactProp(name = "fill") - public void setFill(@Nullable ReadableArray fillColors) { - mBrushData = PropHelper.toFloatArray(fillColors); - markUpdated(); - } - - @ReactProp(name = "strokeWidth", defaultFloat = 1f) - public void setStrokeWidth(float strokeWidth) { - mStrokeWidth = strokeWidth; - markUpdated(); - } - - @ReactProp(name = "strokeCap", defaultInt = CAP_ROUND) - public void setStrokeCap(int strokeCap) { - mStrokeCap = strokeCap; - markUpdated(); - } - - @ReactProp(name = "strokeJoin", defaultInt = JOIN_ROUND) - public void setStrokeJoin(int strokeJoin) { - mStrokeJoin = strokeJoin; - markUpdated(); - } - - @Override - public void draw(Canvas canvas, Paint paint, float opacity) { - opacity *= mOpacity; - if (opacity > MIN_OPACITY_FOR_DRAW) { - saveAndSetupCanvas(canvas); - if (mPath == null) { - throw new JSApplicationIllegalArgumentException("Shapes should have a valid path (d) prop"); - } - if (setupFillPaint(paint, opacity)) { - canvas.drawPath(mPath, paint); - } - if (setupStrokePaint(paint, opacity)) { - canvas.drawPath(mPath, paint); - } - restoreCanvas(canvas); - } - markUpdateSeen(); - } - - /** - * Sets up {@link #mPaint} according to the props set on a shadow view. Returns {@code true} if - * the stroke should be drawn, {@code false} if not. - */ - protected boolean setupStrokePaint(Paint paint, float opacity) { - if (mStrokeWidth == 0 || mStrokeColor == null || mStrokeColor.length == 0) { - return false; - } - paint.reset(); - paint.setFlags(Paint.ANTI_ALIAS_FLAG); - paint.setStyle(Paint.Style.STROKE); - switch (mStrokeCap) { - case CAP_BUTT: - paint.setStrokeCap(Paint.Cap.BUTT); - break; - case CAP_SQUARE: - paint.setStrokeCap(Paint.Cap.SQUARE); - break; - case CAP_ROUND: - paint.setStrokeCap(Paint.Cap.ROUND); - break; - default: - throw new JSApplicationIllegalArgumentException( - "strokeCap " + mStrokeCap + " unrecognized"); - } - switch (mStrokeJoin) { - case JOIN_MITER: - paint.setStrokeJoin(Paint.Join.MITER); - break; - case JOIN_BEVEL: - paint.setStrokeJoin(Paint.Join.BEVEL); - break; - case JOIN_ROUND: - paint.setStrokeJoin(Paint.Join.ROUND); - break; - default: - throw new JSApplicationIllegalArgumentException( - "strokeJoin " + mStrokeJoin + " unrecognized"); - } - paint.setStrokeWidth(mStrokeWidth * mScale); - paint.setARGB( - (int) (mStrokeColor.length > 3 ? mStrokeColor[3] * opacity * 255 : opacity * 255), - (int) (mStrokeColor[0] * 255), - (int) (mStrokeColor[1] * 255), - (int) (mStrokeColor[2] * 255)); - if (mStrokeDash != null && mStrokeDash.length > 0) { - paint.setPathEffect(new DashPathEffect(mStrokeDash, 0)); - } - return true; - } - - /** - * Sets up {@link #mPaint} according to the props set on a shadow view. Returns {@code true} if - * the fill should be drawn, {@code false} if not. - */ - protected boolean setupFillPaint(Paint paint, float opacity) { - if (mBrushData != null && mBrushData.length > 0) { - paint.reset(); - paint.setFlags(Paint.ANTI_ALIAS_FLAG); - paint.setStyle(Paint.Style.FILL); - int colorType = (int) mBrushData[0]; - switch (colorType) { - case COLOR_TYPE_SOLID_COLOR: - paint.setARGB( - (int) (mBrushData.length > 4 ? mBrushData[4] * opacity * 255 : opacity * 255), - (int) (mBrushData[1] * 255), - (int) (mBrushData[2] * 255), - (int) (mBrushData[3] * 255)); - break; - case COLOR_TYPE_LINEAR_GRADIENT: - // For mBrushData format refer to LinearGradient and insertColorStopsIntoArray functions - // in ReactNativeART.js - if (mBrushData.length < 5) { - FLog.w( - ReactConstants.TAG, - "[ARTShapeShadowNode setupFillPaint] expects 5 elements, received " - + mBrushData.length); - return false; - } - float gradientStartX = mBrushData[1] * mScale; - float gradientStartY = mBrushData[2] * mScale; - float gradientEndX = mBrushData[3] * mScale; - float gradientEndY = mBrushData[4] * mScale; - int stops = (mBrushData.length - 5) / 5; - int[] colors = null; - float[] positions = null; - if (stops > 0) { - colors = new int[stops]; - positions = new float[stops]; - for (int i = 0; i < stops; i++) { - positions[i] = mBrushData[5 + 4 * stops + i]; - int r = (int) (255 * mBrushData[5 + 4 * i + 0]); - int g = (int) (255 * mBrushData[5 + 4 * i + 1]); - int b = (int) (255 * mBrushData[5 + 4 * i + 2]); - int a = (int) (255 * mBrushData[5 + 4 * i + 3]); - colors[i] = Color.argb(a, r, g, b); - } - } - paint.setShader( - new LinearGradient( - gradientStartX, - gradientStartY, - gradientEndX, - gradientEndY, - colors, - positions, - Shader.TileMode.CLAMP)); - break; - case COLOR_TYPE_RADIAL_GRADIENT: - // TODO(6352048): Support radial gradient etc. - case COLOR_TYPE_PATTERN: - // TODO(6352048): Support patterns etc. - default: - FLog.w(ReactConstants.TAG, "ART: Color type " + colorType + " not supported!"); - } - return true; - } - return false; - } - - /** - * Returns the floor modulus of the float arguments. Java modulus will return a negative remainder - * when the divisor is negative. Modulus should always be positive. This mimics the behavior of - * Math.floorMod, introduced in Java 8. - */ - private float modulus(float x, float y) { - float remainder = x % y; - float modulus = remainder; - if (remainder < 0) { - modulus += y; - } - return modulus; - } - - /** - * Creates a {@link Path} from an array of instructions constructed by JS (see - * ARTSerializablePath.js). Each instruction starts with a type (see PATH_TYPE_*) followed by - * arguments for that instruction. For example, to create a line the instruction will be 2 - * (PATH_LINE_TO), x, y. This will draw a line from the last draw point (or 0,0) to x,y. - * - * @param data the array of instructions - * @return the {@link Path} that can be drawn to a canvas - */ - private Path createPath(float[] data) { - Path path = new Path(); - path.moveTo(0, 0); - int i = 0; - while (i < data.length) { - int type = (int) data[i++]; - switch (type) { - case PATH_TYPE_MOVETO: - path.moveTo(data[i++] * mScale, data[i++] * mScale); - break; - case PATH_TYPE_CLOSE: - path.close(); - break; - case PATH_TYPE_LINETO: - path.lineTo(data[i++] * mScale, data[i++] * mScale); - break; - case PATH_TYPE_CURVETO: - path.cubicTo( - data[i++] * mScale, - data[i++] * mScale, - data[i++] * mScale, - data[i++] * mScale, - data[i++] * mScale, - data[i++] * mScale); - break; - case PATH_TYPE_ARC: - { - float x = data[i++] * mScale; - float y = data[i++] * mScale; - float r = data[i++] * mScale; - float start = (float) Math.toDegrees(data[i++]); - float end = (float) Math.toDegrees(data[i++]); - - boolean counterClockwise = !(data[i++] == 1f); - float sweep = end - start; - if (Math.abs(sweep) >= 360) { - path.addCircle(x, y, r, counterClockwise ? Path.Direction.CCW : Path.Direction.CW); - } else { - sweep = modulus(sweep, 360); - if (counterClockwise && sweep < 360) { - // Counter-clockwise sweeps are negative - sweep = -1 * (360 - sweep); - } - - RectF oval = new RectF(x - r, y - r, x + r, y + r); - path.arcTo(oval, start, sweep); - } - break; - } - default: - throw new JSApplicationIllegalArgumentException( - "Unrecognized drawing instruction " + type); - } - } - return path; - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeViewManager.java deleted file mode 100644 index f192481fabfbdc..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTShapeViewManager.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import com.facebook.react.module.annotations.ReactModule; - -/** ViewManager for shadowed ART shape views. */ -@ReactModule(name = ARTRenderableViewManager.CLASS_SHAPE) -public class ARTShapeViewManager extends ARTRenderableViewManager { - - /* package */ ARTShapeViewManager() { - super(CLASS_SHAPE); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceView.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceView.java deleted file mode 100644 index 95d0d6fbb8956b..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceView.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.content.Context; -import android.view.TextureView; - -/** Custom {@link View} implementation that draws an ARTSurface React view and its children. */ -public class ARTSurfaceView extends TextureView { - public ARTSurfaceView(Context context) { - super(context); - setOpaque(false); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java deleted file mode 100644 index 5a3e42c6b62da4..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewManager.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import com.facebook.react.module.annotations.ReactModule; -import com.facebook.react.uimanager.BaseViewManager; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.yoga.YogaMeasureFunction; -import com.facebook.yoga.YogaMeasureMode; -import com.facebook.yoga.YogaNode; - -/** - * ViewManager for ARTSurfaceView React views. Renders as a {@link ARTSurfaceView} and handles - * invalidating the native view on shadow view updates happening in the underlying tree. - */ -@ReactModule(name = ARTSurfaceViewManager.REACT_CLASS) -public class ARTSurfaceViewManager - extends BaseViewManager { - - public static final String REACT_CLASS = "ARTSurfaceView"; - - private static final YogaMeasureFunction MEASURE_FUNCTION = - new YogaMeasureFunction() { - @Override - public long measure( - YogaNode node, - float width, - YogaMeasureMode widthMode, - float height, - YogaMeasureMode heightMode) { - throw new IllegalStateException("SurfaceView should have explicit width and height set"); - } - }; - - @Override - public String getName() { - return REACT_CLASS; - } - - @Override - public ARTSurfaceViewShadowNode createShadowNodeInstance() { - ARTSurfaceViewShadowNode node = new ARTSurfaceViewShadowNode(); - node.setMeasureFunction(MEASURE_FUNCTION); - return node; - } - - @Override - public Class getShadowNodeClass() { - return ARTSurfaceViewShadowNode.class; - } - - @Override - protected ARTSurfaceView createViewInstance(ThemedReactContext reactContext) { - return new ARTSurfaceView(reactContext); - } - - @Override - public void updateExtraData(ARTSurfaceView root, Object extraData) { - ARTSurfaceViewShadowNode shadowNode = (ARTSurfaceViewShadowNode) extraData; - shadowNode.setupSurfaceTextureListener(root); - } - - @Override - public void setBackgroundColor(ARTSurfaceView view, int backgroundColor) { - // As of Android N TextureView does not support calling setBackground on it. - // It will also throw an exception when target SDK is set to N or higher. - - // Setting the background color for this view is handled in the shadow node. - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java deleted file mode 100644 index acc7fcaeec9287..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTSurfaceViewShadowNode.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.PorterDuff; -import android.graphics.SurfaceTexture; -import android.os.Build; -import android.view.Surface; -import android.view.TextureView; -import androidx.annotation.Nullable; -import com.facebook.common.logging.FLog; -import com.facebook.react.bridge.LifecycleEventListener; -import com.facebook.react.common.ReactConstants; -import com.facebook.react.uimanager.LayoutShadowNode; -import com.facebook.react.uimanager.ReactShadowNode; -import com.facebook.react.uimanager.ThemedReactContext; -import com.facebook.react.uimanager.UIViewOperationQueue; -import com.facebook.react.uimanager.ViewProps; -import com.facebook.react.uimanager.annotations.ReactProp; - -/** Shadow node for ART virtual tree root - ARTSurfaceView */ -public class ARTSurfaceViewShadowNode extends LayoutShadowNode - implements TextureView.SurfaceTextureListener, LifecycleEventListener { - - private @Nullable Surface mSurface; - - private @Nullable Integer mBackgroundColor; - - @ReactProp(name = ViewProps.BACKGROUND_COLOR, customType = "Color") - public void setBackgroundColor(Integer color) { - mBackgroundColor = color; - markUpdated(); - } - - @Override - public boolean isVirtual() { - return false; - } - - @Override - public boolean isVirtualAnchor() { - return true; - } - - @Override - public void onCollectExtraUpdates(UIViewOperationQueue uiUpdater) { - super.onCollectExtraUpdates(uiUpdater); - drawOutput(false); - uiUpdater.enqueueUpdateExtraData(getReactTag(), this); - } - - private void drawOutput(boolean markAsUpdated) { - if (mSurface == null || !mSurface.isValid()) { - markChildrenUpdatesSeen(this); - return; - } - - try { - Canvas canvas = mSurface.lockCanvas(null); - canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR); - if (mBackgroundColor != null) { - canvas.drawColor(mBackgroundColor); - } - - Paint paint = new Paint(); - for (int i = 0; i < getChildCount(); i++) { - ARTVirtualNode child = (ARTVirtualNode) getChildAt(i); - child.draw(canvas, paint, 1f); - if (markAsUpdated) { - child.markUpdated(); - } else { - child.markUpdateSeen(); - } - } - - if (mSurface == null) { - return; - } - mSurface.unlockCanvasAndPost(canvas); - } catch (IllegalArgumentException | IllegalStateException e) { - FLog.e(ReactConstants.TAG, e.getClass().getSimpleName() + " in Surface.unlockCanvasAndPost"); - } - } - - public void setupSurfaceTextureListener(ARTSurfaceView surfaceView) { - SurfaceTexture surface = surfaceView.getSurfaceTexture(); - surfaceView.setSurfaceTextureListener(this); - if (surface != null && mSurface == null) { - mSurface = new Surface(surface); - drawOutput(true); - } - } - - private void markChildrenUpdatesSeen(ReactShadowNode shadowNode) { - for (int i = 0; i < shadowNode.getChildCount(); i++) { - ReactShadowNode child = shadowNode.getChildAt(i); - child.markUpdateSeen(); - markChildrenUpdatesSeen(child); - } - } - - @Override - public void setThemedContext(ThemedReactContext themedContext) { - super.setThemedContext(themedContext); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { - themedContext.addLifecycleEventListener(this); - } - } - - @Override - public void dispose() { - super.dispose(); - if (Build.VERSION.SDK_INT > Build.VERSION_CODES.N) { - getThemedContext().removeLifecycleEventListener(this); - } - } - - @Override - public void onHostResume() { - drawOutput(false); - } - - @Override - public void onHostPause() {} - - @Override - public void onHostDestroy() {} - - @Override - public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) { - mSurface = new Surface(surface); - drawOutput(false); - } - - @Override - public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) { - mSurface.release(); - mSurface = null; - return true; - } - - @Override - public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {} - - @Override - public void onSurfaceTextureUpdated(SurfaceTexture surface) {} -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java deleted file mode 100644 index dca51da7f92e95..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextShadowNode.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Typeface; -import android.text.TextUtils; -import androidx.annotation.Nullable; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.bridge.ReadableMap; -import com.facebook.react.uimanager.annotations.ReactProp; - -/** Shadow node for virtual ARTText view */ -public class ARTTextShadowNode extends ARTShapeShadowNode { - - private static final String PROP_LINES = "lines"; - - private static final String PROP_FONT = "font"; - private static final String PROP_FONT_FAMILY = "fontFamily"; - private static final String PROP_FONT_SIZE = "fontSize"; - private static final String PROP_FONT_STYLE = "fontStyle"; - private static final String PROP_FONT_WEIGHT = "fontWeight"; - - private static final int DEFAULT_FONT_SIZE = 12; - - private static final int TEXT_ALIGNMENT_CENTER = 2; - private static final int TEXT_ALIGNMENT_LEFT = 0; - private static final int TEXT_ALIGNMENT_RIGHT = 1; - - private @Nullable ReadableMap mFrame; - private int mTextAlignment = TEXT_ALIGNMENT_LEFT; - - public ARTTextShadowNode() {} - - @ReactProp(name = "frame") - public void setFrame(@Nullable ReadableMap frame) { - mFrame = frame; - } - - @ReactProp(name = "alignment", defaultInt = TEXT_ALIGNMENT_LEFT) - public void setAlignment(int alignment) { - mTextAlignment = alignment; - } - - @Override - public void draw(Canvas canvas, Paint paint, float opacity) { - if (mFrame == null) { - return; - } - opacity *= mOpacity; - if (opacity <= MIN_OPACITY_FOR_DRAW) { - return; - } - if (!mFrame.hasKey(PROP_LINES)) { - return; - } - ReadableArray linesProp = mFrame.getArray(PROP_LINES); - if (linesProp == null || linesProp.size() == 0) { - return; - } - - // only set up the canvas if we have something to draw - saveAndSetupCanvas(canvas); - String[] lines = new String[linesProp.size()]; - for (int i = 0; i < lines.length; i++) { - lines[i] = linesProp.getString(i); - } - String text = TextUtils.join("\n", lines); - if (setupStrokePaint(paint, opacity)) { - applyTextPropertiesToPaint(paint); - if (mPath == null) { - canvas.drawText(text, 0, -paint.ascent(), paint); - } else { - canvas.drawTextOnPath(text, mPath, 0, 0, paint); - } - } - if (setupFillPaint(paint, opacity)) { - applyTextPropertiesToPaint(paint); - if (mPath == null) { - canvas.drawText(text, 0, -paint.ascent(), paint); - } else { - canvas.drawTextOnPath(text, mPath, 0, 0, paint); - } - } - restoreCanvas(canvas); - markUpdateSeen(); - } - - private void applyTextPropertiesToPaint(Paint paint) { - int alignment = mTextAlignment; - switch (alignment) { - case TEXT_ALIGNMENT_LEFT: - paint.setTextAlign(Paint.Align.LEFT); - break; - case TEXT_ALIGNMENT_RIGHT: - paint.setTextAlign(Paint.Align.RIGHT); - break; - case TEXT_ALIGNMENT_CENTER: - paint.setTextAlign(Paint.Align.CENTER); - break; - } - if (mFrame != null) { - if (mFrame.hasKey(PROP_FONT)) { - ReadableMap font = mFrame.getMap(PROP_FONT); - if (font != null) { - float fontSize = DEFAULT_FONT_SIZE; - if (font.hasKey(PROP_FONT_SIZE)) { - fontSize = (float) font.getDouble(PROP_FONT_SIZE); - } - paint.setTextSize(fontSize * mScale); - boolean isBold = - font.hasKey(PROP_FONT_WEIGHT) && "bold".equals(font.getString(PROP_FONT_WEIGHT)); - boolean isItalic = - font.hasKey(PROP_FONT_STYLE) && "italic".equals(font.getString(PROP_FONT_STYLE)); - int fontStyle; - if (isBold && isItalic) { - fontStyle = Typeface.BOLD_ITALIC; - } else if (isBold) { - fontStyle = Typeface.BOLD; - } else if (isItalic) { - fontStyle = Typeface.ITALIC; - } else { - fontStyle = Typeface.NORMAL; - } - // NB: if the font family is null / unsupported, the default one will be used - paint.setTypeface(Typeface.create(font.getString(PROP_FONT_FAMILY), fontStyle)); - } - } - } - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextViewManager.java deleted file mode 100644 index b49b95b76d8c5f..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTTextViewManager.java +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import com.facebook.react.module.annotations.ReactModule; - -/** ViewManager for shadowed ART text views. */ -@ReactModule(name = ARTRenderableViewManager.CLASS_TEXT) -public class ARTTextViewManager extends ARTRenderableViewManager { - - /* package */ ARTTextViewManager() { - super(CLASS_TEXT); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java deleted file mode 100644 index 8f6592924e4e54..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/ARTVirtualNode.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import android.graphics.Canvas; -import android.graphics.Matrix; -import android.graphics.Paint; -import androidx.annotation.Nullable; -import com.facebook.react.bridge.JSApplicationIllegalArgumentException; -import com.facebook.react.bridge.ReadableArray; -import com.facebook.react.uimanager.DisplayMetricsHolder; -import com.facebook.react.uimanager.ReactShadowNodeImpl; -import com.facebook.react.uimanager.annotations.ReactProp; - -/** - * Base class for ARTView virtual nodes: {@link ARTGroupShadowNode}, {@link ARTShapeShadowNode} and - * indirectly for {@link ARTTextShadowNode}. - */ -public abstract class ARTVirtualNode extends ReactShadowNodeImpl { - - protected static final float MIN_OPACITY_FOR_DRAW = 0.01f; - - private static final float[] sMatrixData = new float[9]; - private static final float[] sRawMatrix = new float[9]; - - protected float mOpacity = 1f; - private @Nullable Matrix mMatrix = new Matrix(); - - protected final float mScale; - - public ARTVirtualNode() { - mScale = DisplayMetricsHolder.getWindowDisplayMetrics().density; - } - - @Override - public boolean isVirtual() { - return true; - } - - public abstract void draw(Canvas canvas, Paint paint, float opacity); - - /** - * Sets up the transform matrix on the canvas before an element is drawn. - * - *

NB: for perf reasons this does not apply opacity, as that would mean creating a new canvas - * layer (which allocates an offscreen bitmap) and having it composited afterwards. Instead, the - * drawing code should apply opacity recursively. - * - * @param canvas the canvas to set up - */ - protected final void saveAndSetupCanvas(Canvas canvas) { - canvas.save(); - if (mMatrix != null) { - canvas.concat(mMatrix); - } - } - - /** - * Restore the canvas after an element was drawn. This is always called in mirror with {@link - * #saveAndSetupCanvas}. - * - * @param canvas the canvas to restore - */ - protected void restoreCanvas(Canvas canvas) { - canvas.restore(); - } - - @ReactProp(name = "opacity", defaultFloat = 1f) - public void setOpacity(float opacity) { - mOpacity = opacity; - markUpdated(); - } - - @ReactProp(name = "transform") - public void setTransform(@Nullable ReadableArray transformArray) { - if (transformArray != null) { - int matrixSize = PropHelper.toFloatArray(transformArray, sMatrixData); - if (matrixSize == 6) { - setupMatrix(); - } else if (matrixSize != -1) { - throw new JSApplicationIllegalArgumentException("Transform matrices must be of size 6"); - } - } else { - mMatrix = null; - } - markUpdated(); - } - - protected void setupMatrix() { - sRawMatrix[0] = sMatrixData[0]; - sRawMatrix[1] = sMatrixData[2]; - sRawMatrix[2] = sMatrixData[4] * mScale; - sRawMatrix[3] = sMatrixData[1]; - sRawMatrix[4] = sMatrixData[3]; - sRawMatrix[5] = sMatrixData[5] * mScale; - sRawMatrix[6] = 0; - sRawMatrix[7] = 0; - sRawMatrix[8] = 1; - if (mMatrix == null) { - mMatrix = new Matrix(); - } - mMatrix.setValues(sRawMatrix); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/art/BUCK deleted file mode 100644 index b5eae199917ce9..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/BUCK +++ /dev/null @@ -1,21 +0,0 @@ -load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_target", "rn_android_library") - -rn_android_library( - name = "art", - srcs = glob(["*.java"]), - is_androidx = True, - visibility = [ - "PUBLIC", - ], - deps = [ - YOGA_TARGET, - react_native_dep("third-party/android/androidx:annotation"), - react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"), - react_native_dep("third-party/java/jsr-305:jsr-305"), - react_native_target("java/com/facebook/react/bridge:bridge"), - react_native_target("java/com/facebook/react/common:common"), - react_native_target("java/com/facebook/react/module/annotations:annotations"), - react_native_target("java/com/facebook/react/uimanager:uimanager"), - react_native_target("java/com/facebook/react/uimanager/annotations:annotations"), - ], -) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/art/PropHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/art/PropHelper.java deleted file mode 100644 index 970f505661b99b..00000000000000 --- a/ReactAndroid/src/main/java/com/facebook/react/views/art/PropHelper.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - -package com.facebook.react.views.art; - -import androidx.annotation.Nullable; -import com.facebook.react.bridge.ReadableArray; - -/** Contains static helper methods for accessing props. */ -/* package */ class PropHelper { - - /** - * Converts {@link ReadableArray} to an array of {@code float}. Returns newly created array. - * - * @return a {@code float[]} if converted successfully, or {@code null} if {@param value} was - * {@code null}. - */ - /*package*/ static @Nullable float[] toFloatArray(@Nullable ReadableArray value) { - if (value != null) { - float[] result = new float[value.size()]; - toFloatArray(value, result); - return result; - } - return null; - } - - /** - * Converts given {@link ReadableArray} to an array of {@code float}. Writes result to the array - * passed in {@param into}. This method will write to the output array up to the number of items - * from the input array. If the input array is longer than output the remaining part of the input - * will not be converted. - * - * @param value input array - * @param into output array - * @return number of items copied from input to the output array - */ - /*package*/ static int toFloatArray(ReadableArray value, float[] into) { - int length = value.size() > into.length ? into.length : value.size(); - for (int i = 0; i < length; i++) { - into[i] = (float) value.getDouble(i); - } - return value.size(); - } -} diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/common/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/common/BUCK index b6a8fbdbde991d..c9f4f1bda7ce78 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/common/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/common/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "common", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/java/jsr-305:jsr-305"), react_native_dep("third-party/android/androidx:annotation"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/BUCK index 57d72472c1964a..9b24b8e6611515 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "drawer", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java index d2f22623a81508..712353eb0a42f2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/drawer/ReactDrawerLayoutManager.java @@ -56,9 +56,12 @@ public ReactDrawerLayoutManager() { @Override protected void addEventEmitters(ThemedReactContext reactContext, ReactDrawerLayout view) { - view.addDrawerListener( - new DrawerEventEmitter( - view, reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher())); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + if (uiManager == null) { + return; + } + + view.addDrawerListener(new DrawerEventEmitter(view, uiManager.getEventDispatcher())); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/image/BUCK index 3cddf8e7158472..e60547c2a4101b 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/BUCK @@ -8,6 +8,7 @@ rn_android_library( name = "imageevents", srcs = IMAGE_EVENT_FILES, is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), @@ -31,6 +32,7 @@ rn_android_library( exclude = IMAGE_EVENT_FILES, ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactCallerContextFactory.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactCallerContextFactory.java index 7ccc594b946a18..46e9573fdb0ca1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactCallerContextFactory.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactCallerContextFactory.java @@ -1,3 +1,5 @@ +// (c) Facebook, Inc. and its affiliates. Confidential and proprietary. + /* * Copyright (c) Facebook, Inc. and its affiliates. * @@ -8,7 +10,6 @@ package com.facebook.react.views.image; import androidx.annotation.Nullable; -import com.facebook.react.uimanager.ThemedReactContext; /** * This interface is used from {@link ReactImageManager} to customize the CallerContext object @@ -19,8 +20,9 @@ public interface ReactCallerContextFactory { /** * This method will be called at the time {@link ReactImageManager} creates {@link ReactImageView} * - * @param reactContext {@link ThemedReactContext} used to create the {@link ReactImageView} + * @param surfaceID {@link String} used to log the name of the surface * @return an {@link Object} that represents the CallerContext. */ - Object getOrCreateCallerContext(ThemedReactContext reactContext, @Nullable String analyticTag); + @Nullable + Object getOrCreateCallerContext(@Nullable String surfaceID, @Nullable String analyticTag); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java index e90301b6acea0b..7077ceb7ad9030 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/image/ReactImageManager.java @@ -107,7 +107,7 @@ public Object getCallerContext() { public ReactImageView createViewInstance(ThemedReactContext context) { Object callerContext = mCallerContextFactory != null - ? mCallerContextFactory.getOrCreateCallerContext(context, null) + ? mCallerContextFactory.getOrCreateCallerContext(context.getSurfaceID(), null) : getCallerContext(); return new ReactImageView( context, getDraweeControllerBuilder(), mGlobalImageLoadListener, callerContext); @@ -129,7 +129,7 @@ public void setInternal_AnalyticsTag(ReactImageView view, @Nullable String analy if (mCallerContextFactory != null) { view.updateCallerContext( mCallerContextFactory.getOrCreateCallerContext( - (ThemedReactContext) view.getContext(), analyticTag)); + ((ThemedReactContext) view.getContext()).getSurfaceID(), analyticTag)); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/imagehelper/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/imagehelper/BUCK index b870bef0195b24..990f459c89c89a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/imagehelper/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/imagehelper/BUCK @@ -7,6 +7,7 @@ rn_android_library( exclude = ["MultiSourceHelper.java"], ), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], @@ -21,6 +22,7 @@ rn_android_library( name = "withmultisource", srcs = ["MultiSourceHelper.java"], is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK index bb6d9818b89266..6c69eb6af88884 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "modal", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java index ac0cffd04979fa..00e0066b97a125 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostManager.java @@ -105,8 +105,12 @@ public void setIdentifier(ReactModalHostView view, int value) {} @Override protected void addEventEmitters(ThemedReactContext reactContext, final ReactModalHostView view) { - final EventDispatcher dispatcher = - reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + if (uiManager == null) { + return; + } + + final EventDispatcher dispatcher = uiManager.getEventDispatcher(); view.setOnRequestCloseListener( new ReactModalHostView.OnRequestCloseListener() { @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java index 110ebdf34be342..d5312acdb18672 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java @@ -414,9 +414,14 @@ private void updateFirstChildView() { new GuardedRunnable(reactContext) { @Override public void runGuarded() { - (getReactContext()) - .getNativeModule(UIManagerModule.class) - .updateNodeSize(viewTag, viewWidth, viewHeight); + UIManagerModule uiManager = + (getReactContext()).getNativeModule(UIManagerModule.class); + + if (uiManager == null) { + return; + } + + uiManager.updateNodeSize(viewTag, viewWidth, viewHeight); } }); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/picker/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/picker/BUCK index 32fdd11dc47ebe..ca04eca2315179 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/picker/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/picker/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "picker", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:appcompat"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java index b03783ca3fea8f..e5c42e059905e6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/picker/ReactPickerManager.java @@ -62,9 +62,13 @@ protected void onAfterUpdateTransaction(ReactPicker view) { @Override protected void addEventEmitters(final ThemedReactContext reactContext, final ReactPicker picker) { - picker.setOnSelectListener( - new PickerEventEmitter( - picker, reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher())); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + + if (uiManager == null) { + return; + } + + picker.setOnSelectListener(new PickerEventEmitter(picker, uiManager.getEventDispatcher())); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/BUCK index 4e480cd5c812ae..6ef5436e19a58a 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/progressbar/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "progressbar", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK index ef2b7b77d4eda6..ed41f3c10ebe43 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "scroll", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java index c905c5dc9a4f37..1b2c5312381c47 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollView.java @@ -7,12 +7,17 @@ package com.facebook.react.views.scroll; +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.view.FocusFinder; import android.view.KeyEvent; import android.view.MotionEvent; @@ -82,6 +87,10 @@ public class ReactHorizontalScrollView extends HorizontalScrollView private int pendingContentOffsetY = UNSET_CONTENT_OFFSET; private @Nullable StateWrapper mStateWrapper; + private @Nullable ValueAnimator mScrollAnimator; + private int mFinalAnimatedPositionScrollX = 0; + private int mFinalAnimatedPositionScrollY = 0; + private final Rect mTempRect = new Rect(); public ReactHorizontalScrollView(Context context) { @@ -648,6 +657,20 @@ public void run() { ReactHorizontalScrollView.this, mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY); } + /** Get current X position or position after current animation finishes, if any. */ + private int getPostAnimationScrollX() { + return mScrollAnimator != null && mScrollAnimator.isRunning() + ? mFinalAnimatedPositionScrollX + : getScrollX(); + } + + /** Get current X position or position after current animation finishes, if any. */ + private int getPostAnimationScrollY() { + return mScrollAnimator != null && mScrollAnimator.isRunning() + ? mFinalAnimatedPositionScrollY + : getScrollY(); + } + private int predictFinalScrollPosition(int velocityX) { // ScrollView can *only* scroll for 250ms when using smoothScrollTo and there's // no way to customize the scroll duration. So, we create a temporary OverScroller @@ -659,8 +682,8 @@ private int predictFinalScrollPosition(int velocityX) { int maximumOffset = Math.max(0, computeHorizontalScrollRange() - getWidth()); int width = getWidth() - ViewCompat.getPaddingStart(this) - ViewCompat.getPaddingEnd(this); scroller.fling( - getScrollX(), // startX - getScrollY(), // startY + getPostAnimationScrollX(), // startX + getPostAnimationScrollY(), // startY velocityX, // velocityX 0, // velocityY 0, // minX @@ -674,13 +697,13 @@ private int predictFinalScrollPosition(int velocityX) { } /** - * This will smooth scroll us to the nearest snap offset point It currently just looks at where + * This will smooth scroll us to the nearest snap offset point. It currently just looks at where * the content is and slides to the nearest point. It is intended to be run after we are done * scrolling, and handling any momentum scrolling. */ private void smoothScrollAndSnap(int velocity) { double interval = (double) getSnapInterval(); - double currentOffset = (double) getScrollX(); + double currentOffset = (double) (getPostAnimationScrollX()); double targetOffset = (double) predictFinalScrollPosition(velocity); int previousPage = (int) Math.floor(currentOffset / interval); @@ -914,7 +937,54 @@ public void setBorderStyle(@Nullable String style) { * scroll view and state. Calling raw `smoothScrollTo` doesn't update state. */ public void reactSmoothScrollTo(int x, int y) { - smoothScrollTo(x, y); + // `smoothScrollTo` contains some logic that, if called multiple times in a short amount of + // time, will treat all calls as part of the same animation and will not lengthen the duration + // of the animation. This means that, for example, if the user is scrolling rapidly, multiple + // pages could be considered part of one animation, causing some page animations to be animated + // very rapidly - looking like they're not animated at all. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + if (mScrollAnimator != null) { + mScrollAnimator.cancel(); + } + + mFinalAnimatedPositionScrollX = x; + mFinalAnimatedPositionScrollY = y; + PropertyValuesHolder scrollX = PropertyValuesHolder.ofInt("scrollX", getScrollX(), x); + PropertyValuesHolder scrollY = PropertyValuesHolder.ofInt("scrollY", getScrollY(), y); + mScrollAnimator = ObjectAnimator.ofPropertyValuesHolder(scrollX, scrollY); + mScrollAnimator.setDuration( + ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext())); + mScrollAnimator.addUpdateListener( + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + int scrollValueX = (Integer) valueAnimator.getAnimatedValue("scrollX"); + int scrollValueY = (Integer) valueAnimator.getAnimatedValue("scrollY"); + ReactHorizontalScrollView.this.scrollTo(scrollValueX, scrollValueY); + } + }); + mScrollAnimator.addListener( + new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animator) {} + + @Override + public void onAnimationEnd(Animator animator) { + mFinalAnimatedPositionScrollX = -1; + mFinalAnimatedPositionScrollY = -1; + mScrollAnimator = null; + } + + @Override + public void onAnimationCancel(Animator animator) {} + + @Override + public void onAnimationRepeat(Animator animator) {} + }); + mScrollAnimator.start(); + } else { + smoothScrollTo(x, y); + } updateStateOnScroll(x, y); setPendingContentOffsets(x, y); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java index ecb72fff78746f..7f11c77abf3a22 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactHorizontalScrollViewManager.java @@ -304,8 +304,8 @@ public void setFadingEdgeLength(ReactHorizontalScrollView view, int value) { @ReactProp(name = "contentOffset") public void setContentOffset(ReactHorizontalScrollView view, ReadableMap value) { if (value != null) { - double x = value.getDouble("x"); - double y = value.getDouble("y"); + double x = value.hasKey("x") ? value.getDouble("x") : 0; + double y = value.hasKey("y") ? value.getDouble("y") : 0; view.reactScrollTo((int) PixelUtil.toPixelFromDIP(x), (int) PixelUtil.toPixelFromDIP(y)); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java index f0d4e99658553a..7a77b954415cda 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollView.java @@ -7,11 +7,16 @@ package com.facebook.react.views.scroll; +import android.animation.Animator; +import android.animation.ObjectAnimator; +import android.animation.PropertyValuesHolder; +import android.animation.ValueAnimator; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Rect; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; +import android.os.Build; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.View; @@ -87,6 +92,10 @@ public class ReactScrollView extends ScrollView private int pendingContentOffsetY = UNSET_CONTENT_OFFSET; private @Nullable StateWrapper mStateWrapper; + private @Nullable ValueAnimator mScrollAnimator; + private int mFinalAnimatedPositionScrollX; + private int mFinalAnimatedPositionScrollY; + public ReactScrollView(ReactContext context) { this(context, null); } @@ -536,6 +545,20 @@ public void run() { ReactScrollView.this, mPostTouchRunnable, ReactScrollViewHelper.MOMENTUM_DELAY); } + /** Get current X position or position after current animation finishes, if any. */ + private int getPostAnimationScrollX() { + return mScrollAnimator != null && mScrollAnimator.isRunning() + ? mFinalAnimatedPositionScrollX + : getScrollX(); + } + + /** Get current X position or position after current animation finishes, if any. */ + private int getPostAnimationScrollY() { + return mScrollAnimator != null && mScrollAnimator.isRunning() + ? mFinalAnimatedPositionScrollY + : getScrollY(); + } + private int predictFinalScrollPosition(int velocityY) { // ScrollView can *only* scroll for 250ms when using smoothScrollTo and there's // no way to customize the scroll duration. So, we create a temporary OverScroller @@ -547,8 +570,8 @@ private int predictFinalScrollPosition(int velocityY) { int maximumOffset = getMaxScrollY(); int height = getHeight() - getPaddingBottom() - getPaddingTop(); scroller.fling( - getScrollX(), // startX - getScrollY(), // startY + getPostAnimationScrollX(), // startX + getPostAnimationScrollY(), // startY 0, // velocityX velocityY, // velocityY 0, // minX @@ -568,7 +591,7 @@ private int predictFinalScrollPosition(int velocityY) { */ private void smoothScrollAndSnap(int velocity) { double interval = (double) getSnapInterval(); - double currentOffset = (double) getScrollY(); + double currentOffset = (double) getPostAnimationScrollY(); double targetOffset = (double) predictFinalScrollPosition(velocity); int previousPage = (int) Math.floor(currentOffset / interval); @@ -785,7 +808,54 @@ public void onChildViewRemoved(View parent, View child) { * scroll view and state. Calling raw `smoothScrollTo` doesn't update state. */ public void reactSmoothScrollTo(int x, int y) { - smoothScrollTo(x, y); + // `smoothScrollTo` contains some logic that, if called multiple times in a short amount of + // time, will treat all calls as part of the same animation and will not lengthen the duration + // of the animation. This means that, for example, if the user is scrolling rapidly, multiple + // pages could be considered part of one animation, causing some page animations to be animated + // very rapidly - looking like they're not animated at all. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { + if (mScrollAnimator != null) { + mScrollAnimator.cancel(); + } + + mFinalAnimatedPositionScrollX = x; + mFinalAnimatedPositionScrollY = y; + PropertyValuesHolder scrollX = PropertyValuesHolder.ofInt("scrollX", getScrollX(), x); + PropertyValuesHolder scrollY = PropertyValuesHolder.ofInt("scrollY", getScrollY(), y); + mScrollAnimator = ObjectAnimator.ofPropertyValuesHolder(scrollX, scrollY); + mScrollAnimator.setDuration( + ReactScrollViewHelper.getDefaultScrollAnimationDuration(getContext())); + mScrollAnimator.addUpdateListener( + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator valueAnimator) { + int scrollValueX = (Integer) valueAnimator.getAnimatedValue("scrollX"); + int scrollValueY = (Integer) valueAnimator.getAnimatedValue("scrollY"); + ReactScrollView.this.scrollTo(scrollValueX, scrollValueY); + } + }); + mScrollAnimator.addListener( + new Animator.AnimatorListener() { + @Override + public void onAnimationStart(Animator animator) {} + + @Override + public void onAnimationEnd(Animator animator) { + mFinalAnimatedPositionScrollX = -1; + mFinalAnimatedPositionScrollY = -1; + mScrollAnimator = null; + } + + @Override + public void onAnimationCancel(Animator animator) {} + + @Override + public void onAnimationRepeat(Animator animator) {} + }); + mScrollAnimator.start(); + } else { + smoothScrollTo(x, y); + } updateStateOnScroll(x, y); setPendingContentOffsets(x, y); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java index 3f7b829d4eea08..5183f24c44bd80 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewHelper.java @@ -7,8 +7,10 @@ package com.facebook.react.views.scroll; +import android.content.Context; import android.view.View; import android.view.ViewGroup; +import android.widget.OverScroller; import com.facebook.react.bridge.JSApplicationIllegalArgumentException; import com.facebook.react.bridge.ReactContext; import com.facebook.react.uimanager.UIManagerHelper; @@ -21,6 +23,12 @@ public class ReactScrollViewHelper { public static final String AUTO = "auto"; public static final String OVER_SCROLL_NEVER = "never"; + // If all else fails, this is the hardcoded value in OverScroller.java, in AOSP. + // The default is defined here (as of this diff): + // https://android.googlesource.com/platform/frameworks/base/+/ae5bcf23b5f0875e455790d6af387184dbd009c1/core/java/android/widget/OverScroller.java#44 + private static int SMOOTH_SCROLL_DURATION = 250; + private static boolean mSmoothScrollDurationInitialized = false; + /** Shared by {@link ReactScrollView} and {@link ReactHorizontalScrollView}. */ public static void emitScrollEvent(ViewGroup scrollView, float xVelocity, float yVelocity) { emitScrollEvent(scrollView, ScrollEventType.SCROLL, xVelocity, yVelocity); @@ -83,4 +91,43 @@ public static int parseOverScrollMode(String jsOverScrollMode) { throw new JSApplicationIllegalArgumentException("wrong overScrollMode: " + jsOverScrollMode); } } + + public static int getDefaultScrollAnimationDuration(Context context) { + if (!mSmoothScrollDurationInitialized) { + mSmoothScrollDurationInitialized = true; + + try { + OverScrollerDurationGetter overScrollerDurationGetter = + new OverScrollerDurationGetter(context); + SMOOTH_SCROLL_DURATION = overScrollerDurationGetter.getScrollAnimationDuration(); + } catch (Throwable e) { + } + } + + return SMOOTH_SCROLL_DURATION; + } + + private static class OverScrollerDurationGetter extends OverScroller { + // This is the default in AOSP, hardcoded in OverScroller.java. + private int mScrollAnimationDuration = 250; + + OverScrollerDurationGetter(Context context) { + // We call with a null context because OverScroller does not use the context + // in the execution path we're interested in, unless heavily modified in an AOSP fork. + super(context); + } + + public int getScrollAnimationDuration() { + // If startScroll is called without a duration, OverScroller will call `startScroll(x, y, dx, + // dy, duration)` with the default duration. + super.startScroll(0, 0, 0, 0); + + return mScrollAnimationDuration; + } + + @Override + public void startScroll(int startX, int startY, int dx, int dy, int duration) { + mScrollAnimationDuration = duration; + } + } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java index ed7cd05778836e..adf04118c3f437 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/scroll/ReactScrollViewManager.java @@ -308,8 +308,8 @@ public void setFadingEdgeLength(ReactScrollView view, int value) { @ReactProp(name = "contentOffset") public void setContentOffset(ReactScrollView view, ReadableMap value) { if (value != null) { - double x = value.getDouble("x"); - double y = value.getDouble("y"); + double x = value.hasKey("x") ? value.getDouble("x") : 0; + double y = value.hasKey("y") ? value.getDouble("y") : 0; view.reactScrollTo((int) PixelUtil.toPixelFromDIP(x), (int) PixelUtil.toPixelFromDIP(y)); } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/slider/BUCK index f41e9bcc83b927..4aa48da0029ddf 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "slider", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java index 9215864a9c6391..2bab0c053204a3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/slider/ReactSliderManager.java @@ -91,12 +91,17 @@ public long measure( @Override public void onProgressChanged(SeekBar seekbar, int progress, boolean fromUser) { ReactContext reactContext = (ReactContext) seekbar.getContext(); - reactContext - .getNativeModule(UIManagerModule.class) - .getEventDispatcher() - .dispatchEvent( - new ReactSliderEvent( - seekbar.getId(), ((ReactSlider) seekbar).toRealProgress(progress), fromUser)); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + + if (uiManager != null) { + uiManager + .getEventDispatcher() + .dispatchEvent( + new ReactSliderEvent( + seekbar.getId(), + ((ReactSlider) seekbar).toRealProgress(progress), + fromUser)); + } } @Override @@ -105,13 +110,16 @@ public void onStartTrackingTouch(SeekBar seekbar) {} @Override public void onStopTrackingTouch(SeekBar seekbar) { ReactContext reactContext = (ReactContext) seekbar.getContext(); - reactContext - .getNativeModule(UIManagerModule.class) - .getEventDispatcher() - .dispatchEvent( - new ReactSlidingCompleteEvent( - seekbar.getId(), - ((ReactSlider) seekbar).toRealProgress(seekbar.getProgress()))); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + + if (uiManager != null) { + uiManager + .getEventDispatcher() + .dispatchEvent( + new ReactSlidingCompleteEvent( + seekbar.getId(), + ((ReactSlider) seekbar).toRealProgress(seekbar.getProgress()))); + } } }; diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/BUCK index e6ea16364a92f1..f4e77eb6322462 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/swiperefresh/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "swiperefresh", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/BUCK index f7140b7d6ea198..677c0ddb179f57 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "switchview", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:appcompat"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java index bd5336ad6b92d8..0a6b8c8762e740 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/switchview/ReactSwitchManager.java @@ -80,8 +80,14 @@ public long measure( @Override public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { ReactContext reactContext = (ReactContext) buttonView.getContext(); - reactContext - .getNativeModule(UIManagerModule.class) + + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + + if (uiManager == null) { + return; + } + + uiManager .getEventDispatcher() .dispatchEvent(new ReactSwitchEvent(buttonView.getId(), isChecked)); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK index 62458f6ae265ae..6b4ef8857c33a5 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "text", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index 68bfc3455e7fe6..3d7988087ffaeb 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -25,6 +25,7 @@ import androidx.appcompat.widget.AppCompatTextView; import androidx.appcompat.widget.TintContextWrapper; import com.facebook.common.logging.FLog; +import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.Arguments; import com.facebook.react.bridge.ReactContext; import com.facebook.react.bridge.WritableArray; @@ -118,7 +119,8 @@ protected void onLayout( } ReactContext reactContext = getReactContext(); - UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + UIManagerModule uiManager = + Assertions.assertNotNull(reactContext.getNativeModule(UIManagerModule.class)); Spanned text = (Spanned) getText(); Layout layout = getLayout(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java index 4b64720d80e51c..f98035c179bba1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/TextLayoutManager.java @@ -46,6 +46,10 @@ public class TextLayoutManager { private static final String INLINE_VIEW_PLACEHOLDER = "0"; private static final Object sSpannableCacheLock = new Object(); + private static final boolean DEFAULT_INCLUDE_FONT_PADDING = true; + private static final String INCLUDE_FONT_PADDING_KEY = "includeFontPadding"; + private static final String TEXT_BREAK_STRATEGY_KEY = "textBreakStrategy"; + private static final String MAXIMUM_NUMBER_OF_LINES_KEY = "maximumNumberOfLines"; private static LruCache sSpannableCache = new LruCache<>(spannableCacheSize); public static boolean isRTL(ReadableMap attributedString) { @@ -216,17 +220,20 @@ public static long measureText( // TODO(5578671): Handle text direction (see View#getTextDirectionHeuristic) TextPaint textPaint = sTextPaintInstance; - Spannable preparedSpannableText = + Spannable text = getOrCreateSpannableForText(context, attributedString, reactTextViewManagerCallback); int textBreakStrategy = - TextAttributeProps.getTextBreakStrategy(paragraphAttributes.getString("textBreakStrategy")); - boolean includeFontPadding = true; - - if (preparedSpannableText == null) { + TextAttributeProps.getTextBreakStrategy( + paragraphAttributes.getString(TEXT_BREAK_STRATEGY_KEY)); + boolean includeFontPadding = + paragraphAttributes.hasKey(INCLUDE_FONT_PADDING_KEY) + ? paragraphAttributes.getBoolean(INCLUDE_FONT_PADDING_KEY) + : DEFAULT_INCLUDE_FONT_PADDING; + + if (text == null) { throw new IllegalStateException("Spannable element has not been prepared in onBeforeLayout"); } - Spanned text = preparedSpannableText; BoringLayout.Metrics boring = BoringLayout.isBoring(text, textPaint); float desiredWidth = boring == null ? Layout.getDesiredWidth(text, textPaint) : Float.NaN; @@ -302,8 +309,8 @@ public static long measureText( } int maximumNumberOfLines = - paragraphAttributes.hasKey("maximumNumberOfLines") - ? paragraphAttributes.getInt("maximumNumberOfLines") + paragraphAttributes.hasKey(MAXIMUM_NUMBER_OF_LINES_KEY) + ? paragraphAttributes.getInt(MAXIMUM_NUMBER_OF_LINES_KEY) : UNSET; int calculatedLineCount = diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/BUCK index 8b755be5593036..d882979b4893af 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/frescosupport/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "frescosupport", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], visibility = [ "PUBLIC", ], diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK index 745cfe2b89e8f0..ba19532ffc7fa1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "textinput", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], required_for_source_only_abi = True, visibility = [ "PUBLIC", diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java index 78a05c5e48d860..5f2532a3006e41 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java @@ -623,7 +623,9 @@ private void setIntrinsicContentSize() { ReactContext reactContext = getReactContext(this); final ReactTextInputLocalData localData = new ReactTextInputLocalData(this); UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); - uiManager.setViewLocalData(getId(), localData); + if (uiManager != null) { + uiManager.setViewLocalData(getId(), localData); + } } } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditTextInputConnectionWrapper.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditTextInputConnectionWrapper.java index b56789ddf06e67..47b4391c327f11 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditTextInputConnectionWrapper.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditTextInputConnectionWrapper.java @@ -12,6 +12,7 @@ import android.view.inputmethod.InputConnection; import android.view.inputmethod.InputConnectionWrapper; import androidx.annotation.Nullable; +import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.ReactContext; import com.facebook.react.uimanager.UIManagerModule; import com.facebook.react.uimanager.events.EventDispatcher; @@ -62,7 +63,9 @@ class ReactEditTextInputConnectionWrapper extends InputConnectionWrapper { public ReactEditTextInputConnectionWrapper( InputConnection target, final ReactContext reactContext, final ReactEditText editText) { super(target, false); - mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + mEventDispatcher = + Assertions.assertNotNull(reactContext.getNativeModule(UIManagerModule.class)) + .getEventDispatcher(); mEditText = editText; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java index 6e462335820b6f..f5a83221375f67 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactTextInputManager.java @@ -1096,18 +1096,23 @@ public boolean onEditorAction(TextView v, int actionId, KeyEvent keyEvent) { private class ReactContentSizeWatcher implements ContentSizeWatcher { private ReactEditText mEditText; - private EventDispatcher mEventDispatcher; + private @Nullable EventDispatcher mEventDispatcher; private int mPreviousContentWidth = 0; private int mPreviousContentHeight = 0; public ReactContentSizeWatcher(ReactEditText editText) { mEditText = editText; ReactContext reactContext = getReactContext(editText); - mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + UIManagerModule uiManager = reactContext.getNativeModule(UIManagerModule.class); + mEventDispatcher = uiManager != null ? uiManager.getEventDispatcher() : null; } @Override public void onLayout() { + if (mEventDispatcher == null) { + return; + } + int contentWidth = mEditText.getWidth(); int contentHeight = mEditText.getHeight(); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/BUCK index 41bdc06a8225f0..a4d7b073035547 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/unimplementedview/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "unimplementedview", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/view/BUCK index 186cf548b42d7c..1b9b8e05181547 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "view", srcs = glob(["*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:core"), react_native_dep("third-party/android/androidx:fragment"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java index cad4db8b4f14b5..beb51d86fb4e39 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/view/ReactViewManager.java @@ -233,10 +233,14 @@ public void setFocusable(final ReactViewGroup view, boolean focusable) { new View.OnClickListener() { @Override public void onClick(View v) { - final EventDispatcher mEventDispatcher = - ((ReactContext) view.getContext()) - .getNativeModule(UIManagerModule.class) - .getEventDispatcher(); + UIManagerModule uiManager = + ((ReactContext) view.getContext()).getNativeModule(UIManagerModule.class); + + if (uiManager == null) { + return; + } + + final EventDispatcher mEventDispatcher = uiManager.getEventDispatcher(); mEventDispatcher.dispatchEvent(new ViewGroupClickEvent(view.getId())); } }); diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK index bcde344867c3f4..77179a7e98f8f1 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/BUCK @@ -4,6 +4,7 @@ rn_android_library( name = "viewpager", srcs = glob(["**/*.java"]), is_androidx = True, + labels = ["supermodule:android/default/public.react_native.infra"], provided_deps = [ react_native_dep("third-party/android/androidx:annotation"), react_native_dep("third-party/android/androidx:core"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java index 2c6fc370d0d15a..398751a8f6e79e 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/viewpager/ReactViewPager.java @@ -13,6 +13,7 @@ import androidx.viewpager.widget.PagerAdapter; import androidx.viewpager.widget.ViewPager; import com.facebook.common.logging.FLog; +import com.facebook.infer.annotation.Assertions; import com.facebook.react.bridge.ReactContext; import com.facebook.react.common.ReactConstants; import com.facebook.react.uimanager.UIManagerModule; @@ -154,7 +155,9 @@ public void onPageScrollStateChanged(int state) { public ReactViewPager(ReactContext reactContext) { super(reactContext); - mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher(); + mEventDispatcher = + Assertions.assertNotNull(reactContext.getNativeModule(UIManagerModule.class)) + .getEventDispatcher(); mIsCurrentItemFromJs = false; setOnPageChangeListener(new PageChangeListener()); setAdapter(new Adapter()); diff --git a/ReactAndroid/src/main/jni/react/jni/Android.mk b/ReactAndroid/src/main/jni/react/jni/Android.mk index ed19e7fbc33810..dabd4b7c5125c9 100644 --- a/ReactAndroid/src/main/jni/react/jni/Android.mk +++ b/ReactAndroid/src/main/jni/react/jni/Android.mk @@ -25,7 +25,7 @@ LOCAL_LDLIBS += -landroid LOCAL_SHARED_LIBRARIES := libfolly_json libfb libfbjni libglog_init libyoga # The static libraries (.a files) that this module depends on. -LOCAL_STATIC_LIBRARIES := libreactnative libcallinvokerholder +LOCAL_STATIC_LIBRARIES := libreactnative libcallinvokerholder libruntimeexecutor # Name of this module. # @@ -70,6 +70,7 @@ $(call import-module,jsi) $(call import-module,jsiexecutor) $(call import-module,callinvoker) $(call import-module,hermes) +$(call import-module,runtimeexecutor) include $(REACT_SRC_DIR)/turbomodule/core/jni/Android.mk diff --git a/ReactAndroid/src/main/jni/react/jni/BUCK b/ReactAndroid/src/main/jni/react/jni/BUCK index 53f2353ee8ab1b..931a8933d92986 100644 --- a/ReactAndroid/src/main/jni/react/jni/BUCK +++ b/ReactAndroid/src/main/jni/react/jni/BUCK @@ -19,6 +19,7 @@ EXPORTED_HEADERS = [ "NativeMap.h", "ReadableNativeArray.h", "ReadableNativeMap.h", + "JRuntimeExecutor.h", "WritableNativeArray.h", "WritableNativeMap.h", ] @@ -42,6 +43,7 @@ rn_xplat_cxx_library( "-Wno-inconsistent-missing-override", ], fbandroid_allow_jni_merging = True, + labels = ["supermodule:android/default/public.react_native.infra"], platforms = ANDROID, preprocessor_flags = [ "-DLOG_TAG=\"ReactNativeJNI\"", @@ -55,7 +57,7 @@ rn_xplat_cxx_library( deps = ([ "//xplat/third-party/linker_lib:android", "//xplat/third-party/linker_lib:atomic", - "//xplat/third-party/glog:glog", + "//third-party/glog:glog", "//xplat/folly:molly", "//fbandroid/xplat/fbgloginit:fbgloginit", "//xplat/fbsystrace:fbsystrace", @@ -64,6 +66,7 @@ rn_xplat_cxx_library( react_native_xplat_target("cxxreact:jsbigstring"), react_native_xplat_target("cxxreact:module"), react_native_xplat_target("jsinspector:jsinspector"), + react_native_xplat_target("runtimeexecutor:runtimeexecutor"), react_native_xplat_dep("jsi:jsi"), FBJNI_TARGET, ]) if not IS_OSS_BUILD else [], diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp index 4b279d208b41b1..7d5b1acf483f88 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.cpp @@ -131,6 +131,8 @@ void CatalystInstanceImpl::registerNatives() { makeNativeMethod( "jniHandleMemoryPressure", CatalystInstanceImpl::handleMemoryPressure), + makeNativeMethod( + "getRuntimeExecutor", CatalystInstanceImpl::getRuntimeExecutor), }); JNativeRunnable::registerNatives(); @@ -326,5 +328,14 @@ CatalystInstanceImpl::getNativeCallInvokerHolder() { return nativeCallInvokerHolder_; } +jni::alias_ref +CatalystInstanceImpl::getRuntimeExecutor() { + if (!runtimeExecutor_) { + runtimeExecutor_ = jni::make_global( + JRuntimeExecutor::newObjectCxxArgs(instance_->getRuntimeExecutor())); + } + return runtimeExecutor_; +} + } // namespace react } // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h index 32a2eef9178399..dd9990ef090a00 100644 --- a/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h +++ b/ReactAndroid/src/main/jni/react/jni/CatalystInstanceImpl.h @@ -9,10 +9,12 @@ #include #include +#include #include #include "CxxModuleWrapper.h" #include "JMessageQueueThread.h" +#include "JRuntimeExecutor.h" #include "JSLoader.h" #include "JavaModuleWrapper.h" #include "ModuleRegistryBuilder.h" @@ -92,6 +94,7 @@ class CatalystInstanceImpl : public jni::HybridClass { void jniCallJSCallback(jint callbackId, NativeArray *arguments); jni::alias_ref getJSCallInvokerHolder(); jni::alias_ref getNativeCallInvokerHolder(); + jni::alias_ref getRuntimeExecutor(); void setGlobalVariable(std::string propName, std::string &&jsonValue); jlong getJavaScriptContext(); void handleMemoryPressure(int pressureLevel); @@ -103,6 +106,7 @@ class CatalystInstanceImpl : public jni::HybridClass { std::shared_ptr moduleMessageQueue_; jni::global_ref jsCallInvokerHolder_; jni::global_ref nativeCallInvokerHolder_; + jni::global_ref runtimeExecutor_; }; } // namespace react diff --git a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentDescriptor.h b/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.cpp similarity index 56% rename from React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentDescriptor.h rename to ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.cpp index 4cd2480ad5050a..e8e6436c294ff2 100644 --- a/React/Fabric/Mounting/ComponentViews/ART/RCTARTSurfaceViewComponentDescriptor.h +++ b/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.cpp @@ -5,16 +5,17 @@ * LICENSE file in the root directory of this source tree. */ -#pragma once - -#include -#include "RCTARTSurfaceShadowNode.h" +#include "JRuntimeExecutor.h" namespace facebook { namespace react { -using RCTARTSurfaceComponentDescriptor = - ConcreteComponentDescriptor; +JRuntimeExecutor::JRuntimeExecutor(RuntimeExecutor runtimeExecutor) + : runtimeExecutor_(runtimeExecutor) {} + +RuntimeExecutor JRuntimeExecutor::get() { + return runtimeExecutor_; +} } // namespace react } // namespace facebook diff --git a/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h b/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h new file mode 100644 index 00000000000000..1a250d7a867b52 --- /dev/null +++ b/ReactAndroid/src/main/jni/react/jni/JRuntimeExecutor.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +class JRuntimeExecutor : public jni::HybridClass { + public: + static auto constexpr kJavaDescriptor = + "Lcom/facebook/react/bridge/RuntimeExecutor;"; + + RuntimeExecutor get(); + + private: + friend HybridBase; + JRuntimeExecutor(RuntimeExecutor runtimeExecutor); + RuntimeExecutor runtimeExecutor_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/better/BUCK b/ReactCommon/better/BUCK index bff98453e7633a..fb403d3a8dfad5 100644 --- a/ReactCommon/better/BUCK +++ b/ReactCommon/better/BUCK @@ -35,6 +35,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -48,10 +49,10 @@ rn_xplat_cxx_library( tests = [], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", ], ) diff --git a/ReactCommon/callinvoker/BUCK b/ReactCommon/callinvoker/BUCK index a9c3fca7e279b5..0f702cb7282867 100644 --- a/ReactCommon/callinvoker/BUCK +++ b/ReactCommon/callinvoker/BUCK @@ -16,6 +16,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], platforms = (ANDROID, APPLE), preferred_linkage = "static", diff --git a/ReactCommon/config/BUCK b/ReactCommon/config/BUCK index 361f317ba0e042..9c81d30e98dab6 100644 --- a/ReactCommon/config/BUCK +++ b/ReactCommon/config/BUCK @@ -24,6 +24,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -37,10 +38,10 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", ], ) diff --git a/ReactCommon/cxxreact/Android.mk b/ReactCommon/cxxreact/Android.mk index 10c321448a61c5..df9b9e640bc69c 100644 --- a/ReactCommon/cxxreact/Android.mk +++ b/ReactCommon/cxxreact/Android.mk @@ -19,7 +19,7 @@ LOCAL_CFLAGS := \ LOCAL_CFLAGS += -fexceptions -frtti -Wno-unused-lambda-capture -LOCAL_STATIC_LIBRARIES := boost jsi callinvoker +LOCAL_STATIC_LIBRARIES := boost jsi callinvoker runtimeexecutor LOCAL_SHARED_LIBRARIES := jsinspector libfolly_json glog include $(BUILD_STATIC_LIBRARY) diff --git a/ReactCommon/cxxreact/BUCK b/ReactCommon/cxxreact/BUCK index 8ef91ae51b020b..d5453556bd6e91 100644 --- a/ReactCommon/cxxreact/BUCK +++ b/ReactCommon/cxxreact/BUCK @@ -18,6 +18,7 @@ rn_xplat_cxx_library( prefix = "cxxreact", ), compiler_flags = CXX_LIBRARY_COMPILER_FLAGS, + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = get_apple_compiler_flags(), fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], force_static = True, @@ -43,6 +44,7 @@ rn_xplat_cxx_library( "-fexceptions", "-frtti", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = get_apple_compiler_flags(), fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], force_static = True, @@ -75,9 +77,9 @@ rn_xplat_cxx_library( ], deps = [ ":module", + "//third-party/glog:glog", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", ], ) @@ -126,6 +128,7 @@ rn_xplat_cxx_library( "-fexceptions", "-frtti", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_preprocessor_flags = get_android_inspector_flags(), fbobjc_compiler_flags = get_apple_compiler_flags(), fbobjc_force_static = True, @@ -151,7 +154,8 @@ rn_xplat_cxx_library( react_native_xplat_target("callinvoker:callinvoker"), react_native_xplat_target("jsinspector:jsinspector"), react_native_xplat_target("microprofiler:microprofiler"), + react_native_xplat_target("runtimeexecutor:runtimeexecutor"), + "//third-party/glog:glog", "//xplat/folly:optional", - "//xplat/third-party/glog:glog", ], ) diff --git a/ReactCommon/cxxreact/Instance.cpp b/ReactCommon/cxxreact/Instance.cpp index 6643b83a617865..d5b4af5e515ad8 100644 --- a/ReactCommon/cxxreact/Instance.cpp +++ b/ReactCommon/cxxreact/Instance.cpp @@ -229,6 +229,10 @@ std::shared_ptr Instance::getJSCallInvoker() { return std::static_pointer_cast(jsCallInvoker_); } +RuntimeExecutor Instance::getRuntimeExecutor() { + return nativeToJsBridge_->getRuntimeExecutor(); +} + std::shared_ptr Instance::getDecoratedNativeCallInvoker( std::shared_ptr nativeInvoker) { return nativeToJsBridge_->getDecoratedNativeCallInvoker(nativeInvoker); diff --git a/ReactCommon/cxxreact/Instance.h b/ReactCommon/cxxreact/Instance.h index 0d5bacb5360243..f475bf8a7fa72c 100644 --- a/ReactCommon/cxxreact/Instance.h +++ b/ReactCommon/cxxreact/Instance.h @@ -12,6 +12,7 @@ #include #include +#include #include #ifndef RN_EXPORT @@ -129,6 +130,11 @@ class RN_EXPORT Instance { std::shared_ptr getDecoratedNativeCallInvoker( std::shared_ptr nativeInvoker); + /** + * RuntimeExecutor is used by Fabric to access the jsi::Runtime. + */ + RuntimeExecutor getRuntimeExecutor(); + private: void callNativeModules(folly::dynamic &&calls, bool isEndOfBatch); void loadBundle( diff --git a/ReactCommon/cxxreact/NativeToJsBridge.cpp b/ReactCommon/cxxreact/NativeToJsBridge.cpp index 4d31ef058a17ad..64b0673423b8d9 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.cpp +++ b/ReactCommon/cxxreact/NativeToJsBridge.cpp @@ -331,5 +331,22 @@ std::shared_ptr NativeToJsBridge::getDecoratedNativeCallInvoker( return std::make_shared(m_delegate, nativeInvoker); } +RuntimeExecutor NativeToJsBridge::getRuntimeExecutor() { + auto runtimeExecutor = + [this, isDestroyed = m_destroyed]( + std::function &&callback) { + if (*isDestroyed) { + return; + } + runOnExecutorQueue( + [callback = std::move(callback)](JSExecutor *executor) { + jsi::Runtime *runtime = + (jsi::Runtime *)executor->getJavaScriptContext(); + callback(*runtime); + }); + }; + return runtimeExecutor; +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/cxxreact/NativeToJsBridge.h b/ReactCommon/cxxreact/NativeToJsBridge.h index 9cc9176b093bca..d298f9c27960c2 100644 --- a/ReactCommon/cxxreact/NativeToJsBridge.h +++ b/ReactCommon/cxxreact/NativeToJsBridge.h @@ -13,6 +13,7 @@ #include #include +#include #include namespace folly { @@ -106,6 +107,12 @@ class NativeToJsBridge { std::shared_ptr getDecoratedNativeCallInvoker( std::shared_ptr nativeInvoker); + /** + * RuntimeExecutor is used on Android to access the jsi::Runtime from Fabric + * and TurboModules + */ + RuntimeExecutor getRuntimeExecutor(); + private: // This is used to avoid a race condition where a proxyCallback gets queued // after ~NativeToJsBridge(), on the same thread. In that case, the callback diff --git a/ReactCommon/cxxreact/React-cxxreact.podspec b/ReactCommon/cxxreact/React-cxxreact.podspec index 12c0ac858aa5bb..cdb34aa745a8ef 100644 --- a/ReactCommon/cxxreact/React-cxxreact.podspec +++ b/ReactCommon/cxxreact/React-cxxreact.podspec @@ -41,4 +41,5 @@ Pod::Spec.new do |s| s.dependency "glog" s.dependency "React-jsinspector", version s.dependency "React-callinvoker", version + s.dependency "React-runtimeexecutor", version end diff --git a/ReactCommon/fabric/attributedstring/BUCK b/ReactCommon/fabric/attributedstring/BUCK index 0f7c23e1a08bec..cb6d8c234116b8 100644 --- a/ReactCommon/fabric/attributedstring/BUCK +++ b/ReactCommon/fabric/attributedstring/BUCK @@ -37,6 +37,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -50,11 +51,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", react_native_xplat_target("utils:utils"), react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp b/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp index 1cddadf5dc1f89..f33662b81d65a4 100644 --- a/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp +++ b/ReactCommon/fabric/attributedstring/ParagraphAttributes.cpp @@ -20,12 +20,14 @@ bool ParagraphAttributes::operator==(const ParagraphAttributes &rhs) const { maximumNumberOfLines, ellipsizeMode, textBreakStrategy, - adjustsFontSizeToFit) == + adjustsFontSizeToFit, + includeFontPadding) == std::tie( rhs.maximumNumberOfLines, rhs.ellipsizeMode, rhs.textBreakStrategy, - rhs.adjustsFontSizeToFit) && + rhs.adjustsFontSizeToFit, + rhs.includeFontPadding) && floatEquality(minimumFontSize, rhs.minimumFontSize) && floatEquality(maximumFontSize, rhs.maximumFontSize); } @@ -44,7 +46,8 @@ SharedDebugStringConvertibleList ParagraphAttributes::getDebugProps() const { debugStringConvertibleItem("textBreakStrategy", textBreakStrategy), debugStringConvertibleItem("adjustsFontSizeToFit", adjustsFontSizeToFit), debugStringConvertibleItem("minimumFontSize", minimumFontSize), - debugStringConvertibleItem("maximumFontSize", maximumFontSize)}; + debugStringConvertibleItem("maximumFontSize", maximumFontSize), + debugStringConvertibleItem("includeFontPadding", includeFontPadding)}; } #endif diff --git a/ReactCommon/fabric/attributedstring/ParagraphAttributes.h b/ReactCommon/fabric/attributedstring/ParagraphAttributes.h index acc7636a6552b1..585696033618ce 100644 --- a/ReactCommon/fabric/attributedstring/ParagraphAttributes.h +++ b/ReactCommon/fabric/attributedstring/ParagraphAttributes.h @@ -49,6 +49,12 @@ class ParagraphAttributes : public DebugStringConvertible { */ bool adjustsFontSizeToFit{}; + /* + * (Android only) Leaves enough room for ascenders and descenders instead of + * using the font ascent and descent strictly. + */ + bool includeFontPadding{true}; + /* * In case of font size adjustment enabled, defines minimum and maximum * font sizes. @@ -82,7 +88,8 @@ struct hash { attributes.textBreakStrategy, attributes.adjustsFontSizeToFit, attributes.minimumFontSize, - attributes.maximumFontSize); + attributes.maximumFontSize, + attributes.includeFontPadding); } }; } // namespace std diff --git a/ReactCommon/fabric/attributedstring/conversions.h b/ReactCommon/fabric/attributedstring/conversions.h index e92f06ace4b5ed..774913dcd326e9 100644 --- a/ReactCommon/fabric/attributedstring/conversions.h +++ b/ReactCommon/fabric/attributedstring/conversions.h @@ -448,6 +448,11 @@ inline ParagraphAttributes convertRawProp( "maximumFontSize", sourceParagraphAttributes.maximumFontSize, defaultParagraphAttributes.maximumFontSize); + paragraphAttributes.includeFontPadding = convertRawProp( + rawProps, + "includeFontPadding", + sourceParagraphAttributes.includeFontPadding, + defaultParagraphAttributes.includeFontPadding); return paragraphAttributes; } @@ -481,6 +486,8 @@ inline folly::dynamic toDynamic( values("ellipsizeMode", toString(paragraphAttributes.ellipsizeMode)); values("textBreakStrategy", toString(paragraphAttributes.textBreakStrategy)); values("adjustsFontSizeToFit", paragraphAttributes.adjustsFontSizeToFit); + values("includeFontPadding", paragraphAttributes.includeFontPadding); + return values; } diff --git a/ReactCommon/fabric/componentregistry/BUCK b/ReactCommon/fabric/componentregistry/BUCK index b5be24c533470c..1eec505f7e2cdf 100644 --- a/ReactCommon/fabric/componentregistry/BUCK +++ b/ReactCommon/fabric/componentregistry/BUCK @@ -36,6 +36,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -48,13 +49,13 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", "//xplat/jsi:JSIDynamic", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", react_native_xplat_target("fabric/core:core"), react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("utils:utils"), diff --git a/ReactCommon/fabric/components/activityindicator/BUCK b/ReactCommon/fabric/components/activityindicator/BUCK index 310b4fe07f8f8a..b0eaa75eae36a7 100644 --- a/ReactCommon/fabric/components/activityindicator/BUCK +++ b/ReactCommon/fabric/components/activityindicator/BUCK @@ -35,6 +35,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -47,11 +48,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/image/BUCK b/ReactCommon/fabric/components/image/BUCK index 73d56d2ac01d47..9f94284cf15630 100644 --- a/ReactCommon/fabric/components/image/BUCK +++ b/ReactCommon/fabric/components/image/BUCK @@ -35,6 +35,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -47,11 +48,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/image/ImageShadowNode.cpp b/ReactCommon/fabric/components/image/ImageShadowNode.cpp index 5c34ca0ad34374..68d0667aa4e846 100644 --- a/ReactCommon/fabric/components/image/ImageShadowNode.cpp +++ b/ReactCommon/fabric/components/image/ImageShadowNode.cpp @@ -27,13 +27,18 @@ void ImageShadowNode::updateStateIfNeeded() { auto const &imageSource = getImageSource(); auto const ¤tState = getStateData(); + bool hasSameRadius = + getConcreteProps().blurRadius == currentState.getBlurRadius(); + bool hasSameImageSource = currentState.getImageSource() == imageSource; - if (currentState.getImageSource() == imageSource) { + if (hasSameImageSource && hasSameRadius) { return; } - auto state = ImageState{ - imageSource, imageManager_->requestImage(imageSource, getSurfaceId())}; + auto state = + ImageState{imageSource, + imageManager_->requestImage(imageSource, getSurfaceId()), + getConcreteProps().blurRadius}; setStateData(std::move(state)); } diff --git a/ReactCommon/fabric/components/image/ImageShadowNode.h b/ReactCommon/fabric/components/image/ImageShadowNode.h index a723a000b195dc..9ebcbdc97ada63 100644 --- a/ReactCommon/fabric/components/image/ImageShadowNode.h +++ b/ReactCommon/fabric/components/image/ImageShadowNode.h @@ -46,7 +46,7 @@ class ImageShadowNode final : public ConcreteViewShadowNode< ShadowNodeFamilyFragment const &familyFragment, ComponentDescriptor const &componentDescriptor) { auto imageSource = ImageSource{ImageSource::Type::Invalid}; - return {imageSource, {imageSource, nullptr}}; + return {imageSource, {imageSource, nullptr}, 0}; } #pragma mark - LayoutableShadowNode diff --git a/ReactCommon/fabric/components/image/ImageState.cpp b/ReactCommon/fabric/components/image/ImageState.cpp index 3521716d0b750e..d30d21680fb990 100644 --- a/ReactCommon/fabric/components/image/ImageState.cpp +++ b/ReactCommon/fabric/components/image/ImageState.cpp @@ -18,5 +18,9 @@ ImageRequest const &ImageState::getImageRequest() const { return *imageRequest_; } +Float ImageState::getBlurRadius() const { + return blurRadius_; +} + } // namespace react } // namespace facebook diff --git a/ReactCommon/fabric/components/image/ImageState.h b/ReactCommon/fabric/components/image/ImageState.h index 5280e4b0c65350..e41a9f5be48c3d 100644 --- a/ReactCommon/fabric/components/image/ImageState.h +++ b/ReactCommon/fabric/components/image/ImageState.h @@ -19,10 +19,13 @@ namespace react { */ class ImageState final { public: - ImageState(ImageSource const &imageSource, ImageRequest imageRequest) + ImageState( + ImageSource const &imageSource, + ImageRequest imageRequest, + Float const blurRadius) : imageSource_(imageSource), - imageRequest_( - std::make_shared(std::move(imageRequest))){}; + imageRequest_(std::make_shared(std::move(imageRequest))), + blurRadius_(blurRadius){}; /* * Returns stored ImageSource object. @@ -35,8 +38,11 @@ class ImageState final { */ ImageRequest const &getImageRequest() const; + Float getBlurRadius() const; + #ifdef ANDROID - ImageState(ImageState const &previousState, folly::dynamic data){}; + ImageState(ImageState const &previousState, folly::dynamic data) + : blurRadius_{0} {}; /* * Empty implementation for Android because it doesn't use this class. @@ -49,6 +55,7 @@ class ImageState final { private: ImageSource imageSource_; std::shared_ptr imageRequest_; + Float const blurRadius_; }; } // namespace react diff --git a/ReactCommon/fabric/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.mm b/ReactCommon/fabric/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.mm index dec8a569783662..7e2c3813676cf0 100644 --- a/ReactCommon/fabric/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.mm +++ b/ReactCommon/fabric/components/legacyviewmanagerinterop/LegacyViewManagerInteropComponentDescriptor.mm @@ -29,6 +29,12 @@ // If `moduleName` has "FB" prefix. return componentName + "Manager"; } + + std::string artPrefix("ART"); + if (std::mismatch(artPrefix.begin(), artPrefix.end(), componentName.begin()).first == artPrefix.end()) { + return componentName + "Manager"; + } + return "RCT" + componentName + "Manager"; } diff --git a/ReactCommon/fabric/components/modal/BUCK b/ReactCommon/fabric/components/modal/BUCK index 070a02cb8494fa..a84b80df2a456e 100644 --- a/ReactCommon/fabric/components/modal/BUCK +++ b/ReactCommon/fabric/components/modal/BUCK @@ -48,6 +48,7 @@ rn_xplat_cxx_library( fbandroid_headers = glob( ["platform/android/*.h"], ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( ["platform/android/*.cpp"], ), @@ -71,11 +72,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/picker/BUCK b/ReactCommon/fabric/components/picker/BUCK index 829f5adec8fd0c..8508262ce704d0 100644 --- a/ReactCommon/fabric/components/picker/BUCK +++ b/ReactCommon/fabric/components/picker/BUCK @@ -44,7 +44,9 @@ rn_xplat_cxx_library( fbandroid_deps = [ react_native_target("jni/react/jni:jni"), ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, + fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), force_static = True, platforms = (ANDROID, APPLE, CXX), @@ -54,11 +56,11 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/root/BUCK b/ReactCommon/fabric/components/root/BUCK index f67ca8fc8a852d..5805cff81df76a 100644 --- a/ReactCommon/fabric/components/root/BUCK +++ b/ReactCommon/fabric/components/root/BUCK @@ -35,6 +35,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -47,11 +48,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/scrollview/BUCK b/ReactCommon/fabric/components/scrollview/BUCK index 492edfc0f93f11..5f59cfba1a4768 100644 --- a/ReactCommon/fabric/components/scrollview/BUCK +++ b/ReactCommon/fabric/components/scrollview/BUCK @@ -38,6 +38,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -51,11 +52,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/slider/BUCK b/ReactCommon/fabric/components/slider/BUCK index 52f567d985a99e..41ce2c68985eb3 100644 --- a/ReactCommon/fabric/components/slider/BUCK +++ b/ReactCommon/fabric/components/slider/BUCK @@ -53,6 +53,7 @@ rn_xplat_cxx_library( fbandroid_headers = glob( ["platform/android/*.h"], ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( ["platform/android/*.cpp"], ), @@ -80,11 +81,11 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/switch/BUCK b/ReactCommon/fabric/components/switch/BUCK index f5b4493c5de37b..8d12a6a070fa0d 100644 --- a/ReactCommon/fabric/components/switch/BUCK +++ b/ReactCommon/fabric/components/switch/BUCK @@ -44,6 +44,7 @@ rn_xplat_cxx_library( fbandroid_deps = [ react_native_target("jni/react/jni:jni"), ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -55,11 +56,11 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/text/BUCK b/ReactCommon/fabric/components/text/BUCK index c32ad04dfc4509..a1271eb16c66ec 100644 --- a/ReactCommon/fabric/components/text/BUCK +++ b/ReactCommon/fabric/components/text/BUCK @@ -43,6 +43,7 @@ rn_xplat_cxx_library( "-Wall", ], cxx_tests = [":tests"], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -54,12 +55,12 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:container_evicting_cache_map", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("utils:utils"), react_native_xplat_target("fabric/attributedstring:attributedstring"), diff --git a/ReactCommon/fabric/components/textinput/BUCK b/ReactCommon/fabric/components/textinput/BUCK index aa630a15ac7383..616d7c0468e780 100644 --- a/ReactCommon/fabric/components/textinput/BUCK +++ b/ReactCommon/fabric/components/textinput/BUCK @@ -40,6 +40,7 @@ rn_xplat_cxx_library( "-Wall", ], cxx_tests = [":tests"], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -51,12 +52,12 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:container_evicting_cache_map", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("utils:utils"), react_native_xplat_target("fabric/attributedstring:attributedstring"), diff --git a/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h b/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h index 288545367b8b7e..be480cc8a13aba 100644 --- a/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h +++ b/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h @@ -30,6 +30,13 @@ class AndroidTextInputShadowNode : public ConcreteViewShadowNode< AndroidTextInputEventEmitter, AndroidTextInputState> { public: + static ShadowNodeTraits BaseTraits() { + auto traits = ConcreteViewShadowNode::BaseTraits(); + traits.set(ShadowNodeTraits::Trait::TextKind); + traits.set(ShadowNodeTraits::Trait::LeafYogaNode); + return traits; + } + using ConcreteViewShadowNode::ConcreteViewShadowNode; void setContextContainer(ContextContainer *contextContainer); diff --git a/ReactCommon/fabric/components/textinput/iostextinput/BUCK b/ReactCommon/fabric/components/textinput/iostextinput/BUCK index d6baec266ab94e..dfe4ccdf3df86e 100644 --- a/ReactCommon/fabric/components/textinput/iostextinput/BUCK +++ b/ReactCommon/fabric/components/textinput/iostextinput/BUCK @@ -51,12 +51,12 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:container_evicting_cache_map", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("utils:utils"), react_native_xplat_target("fabric/attributedstring:attributedstring"), diff --git a/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h b/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h index 96d3192c22d3ea..cfa7849ac7bd0d 100644 --- a/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h +++ b/ReactCommon/fabric/components/textinput/iostextinput/TextInputShadowNode.h @@ -36,6 +36,7 @@ class TextInputShadowNode : public ConcreteViewShadowNode< static ShadowNodeTraits BaseTraits() { auto traits = ConcreteViewShadowNode::BaseTraits(); traits.set(ShadowNodeTraits::Trait::TextKind); + traits.set(ShadowNodeTraits::Trait::LeafYogaNode); return traits; } diff --git a/ReactCommon/fabric/components/unimplementedview/BUCK b/ReactCommon/fabric/components/unimplementedview/BUCK index 1c8377d7daca60..aae773953d7f69 100644 --- a/ReactCommon/fabric/components/unimplementedview/BUCK +++ b/ReactCommon/fabric/components/unimplementedview/BUCK @@ -47,11 +47,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/components/view/BUCK b/ReactCommon/fabric/components/view/BUCK index 62aada6cf495ea..eb8a63fe20375a 100644 --- a/ReactCommon/fabric/components/view/BUCK +++ b/ReactCommon/fabric/components/view/BUCK @@ -41,6 +41,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -54,11 +55,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/core:core"), react_native_xplat_target("fabric/debug:debug"), diff --git a/ReactCommon/fabric/core/BUCK b/ReactCommon/fabric/core/BUCK index ecd7afa9203aba..5930a38025e754 100644 --- a/ReactCommon/fabric/core/BUCK +++ b/ReactCommon/fabric/core/BUCK @@ -44,6 +44,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -57,13 +58,13 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", "//xplat/jsi:JSIDynamic", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", react_native_xplat_target("utils:utils"), react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/graphics:graphics"), diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp index 2dd49e53065e66..fe2aaa84a753b4 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.cpp @@ -119,6 +119,15 @@ void ShadowNodeFamily::setMostRecentState(State::Shared const &state) const { mostRecentState_ = state; } +std::shared_ptr ShadowNodeFamily::getMostRecentStateIfObsolete( + State const &state) const { + std::unique_lock lock(mutex_); + if (!state.isObsolete_) { + return {}; + } + return mostRecentState_; +} + void ShadowNodeFamily::dispatchRawState( StateUpdate &&stateUpdate, EventPriority priority) const { diff --git a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h index 15998067f44222..1bf431061cb6b8 100644 --- a/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h +++ b/ReactCommon/fabric/core/shadownode/ShadowNodeFamily.h @@ -88,6 +88,15 @@ class ShadowNodeFamily { private: friend ShadowNode; friend ShadowNodeFamilyFragment; + friend State; + + /* + * Returns the most recent state if the given `state` is obsolete, + * otherwise returns `nullptr`. + * To be used by `State` only. + */ + std::shared_ptr getMostRecentStateIfObsolete( + State const &state) const; EventDispatcher::Weak eventDispatcher_; mutable std::shared_ptr mostRecentState_; diff --git a/ReactCommon/fabric/core/state/State.cpp b/ReactCommon/fabric/core/state/State.cpp index d6fb8afe8e5737..d8407cb7e64afe 100644 --- a/ReactCommon/fabric/core/state/State.cpp +++ b/ReactCommon/fabric/core/state/State.cpp @@ -32,6 +32,15 @@ State::Shared State::getMostRecentState() const { return family->getMostRecentState(); } +State::Shared State::getMostRecentStateIfObsolete() const { + auto family = family_.lock(); + if (!family) { + return {}; + } + + return family->getMostRecentStateIfObsolete(*this); +} + size_t State::getRevision() const { return revision_; } diff --git a/ReactCommon/fabric/core/state/State.h b/ReactCommon/fabric/core/state/State.h index e48cf15c3d409e..7e700da7e879d6 100644 --- a/ReactCommon/fabric/core/state/State.h +++ b/ReactCommon/fabric/core/state/State.h @@ -47,6 +47,12 @@ class State { */ State::Shared getMostRecentState() const; + /* + * Returns the most recent state (same as `getMostRecentState()` method) + * if this state is obsolete, otherwise returns `nullptr`. + */ + State::Shared getMostRecentStateIfObsolete() const; + /* * Returns a revision number of the `State` object. * The number is being automatically assigned during the creation of `State` diff --git a/ReactCommon/fabric/debug/BUCK b/ReactCommon/fabric/debug/BUCK index 766570e9ddbab2..9971b09cb503e3 100644 --- a/ReactCommon/fabric/debug/BUCK +++ b/ReactCommon/fabric/debug/BUCK @@ -39,6 +39,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), diff --git a/ReactCommon/fabric/graphics/BUCK b/ReactCommon/fabric/graphics/BUCK index b7a097079de887..bcedde153577c2 100644 --- a/ReactCommon/fabric/graphics/BUCK +++ b/ReactCommon/fabric/graphics/BUCK @@ -56,6 +56,7 @@ rn_xplat_cxx_library( ], prefix = "react/graphics", ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( [ "platform/cxx/**/*.cpp", @@ -95,11 +96,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", ], ) diff --git a/ReactCommon/fabric/imagemanager/BUCK b/ReactCommon/fabric/imagemanager/BUCK index a5458f5071a0b6..ba638f1d1e8098 100644 --- a/ReactCommon/fabric/imagemanager/BUCK +++ b/ReactCommon/fabric/imagemanager/BUCK @@ -45,6 +45,7 @@ rn_xplat_cxx_library( ], prefix = "", ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( [ "platform/cxx/**/*.cpp", @@ -96,11 +97,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/core:core"), react_native_xplat_target("fabric/mounting:mounting"), diff --git a/ReactCommon/fabric/mapbuffer/BUCK b/ReactCommon/fabric/mapbuffer/BUCK index cd4eee387d7357..89acfd5f302c30 100644 --- a/ReactCommon/fabric/mapbuffer/BUCK +++ b/ReactCommon/fabric/mapbuffer/BUCK @@ -40,10 +40,10 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", - "//xplat/third-party/glog:glog", react_native_xplat_target("utils:utils"), ], ) diff --git a/ReactCommon/fabric/mounting/BUCK b/ReactCommon/fabric/mounting/BUCK index 9d6ad218c1d131..afa937d70bd0cc 100644 --- a/ReactCommon/fabric/mounting/BUCK +++ b/ReactCommon/fabric/mounting/BUCK @@ -38,6 +38,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -51,11 +52,11 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", react_native_xplat_target("better:better"), react_native_xplat_target("fabric/components/root:root"), react_native_xplat_target("fabric/components/view:view"), @@ -76,6 +77,7 @@ fb_xplat_cxx_test( "-Wall", ], contacts = ["oncall+react_native@xmail.facebook.com"], + fbandroid_use_instrumentation_test = True, platforms = (ANDROID, APPLE, CXX), deps = [ ":mounting", diff --git a/ReactCommon/fabric/mounting/Differentiator.cpp b/ReactCommon/fabric/mounting/Differentiator.cpp index 919a7364de18ae..6661d5424407b2 100644 --- a/ReactCommon/fabric/mounting/Differentiator.cpp +++ b/ReactCommon/fabric/mounting/Differentiator.cpp @@ -54,7 +54,13 @@ class TinyMap final { // then we don't need to clean. cleanVector(erasedAtFront_ != numErased_); - return begin_(); + Iterator it = begin_(); + + if (it != nullptr) { + return it + erasedAtFront_; + } + + return nullptr; } inline Iterator end() { @@ -71,6 +77,10 @@ class TinyMap final { assert(key != 0); + if (begin_() == nullptr) { + return end(); + } + for (auto it = begin_() + erasedAtFront_; it != end(); it++) { if (it->first == key) { return it; @@ -86,14 +96,14 @@ class TinyMap final { } inline void erase(Iterator iterator) { - numErased_++; - // Invalidate tag. iterator->first = 0; if (iterator == begin_() + erasedAtFront_) { erasedAtFront_++; } + + numErased_++; } private: @@ -643,7 +653,7 @@ static void calculateShadowViewMutationsOptimizedMoves( } // At this point, oldTag is -1 or is in the new list, and hasn't been - // inserted or matched yet We're not sure yet if the new node is in the + // inserted or matched yet. We're not sure yet if the new node is in the // old list - generate an insert instruction for the new node. auto const &newChildPair = newChildPairs[newIndex]; insertMutations.push_back(ShadowViewMutation::InsertMutation( @@ -655,6 +665,14 @@ static void calculateShadowViewMutationsOptimizedMoves( // Final step: generate Create instructions for new nodes for (auto it = newInsertedPairs.begin(); it != newInsertedPairs.end(); it++) { + // Erased elements of a TinyMap will have a Tag/key of 0 - skip those + // These *should* be removed by the map; there are currently no KNOWN + // cases where TinyMap will do the wrong thing, but there are not yet + // any unit tests explicitly for TinyMap, so this is safer for now. + if (it->first == 0) { + continue; + } + auto const &newChildPair = *it->second; createMutations.push_back( ShadowViewMutation::CreateMutation(newChildPair.shadowView)); diff --git a/ReactCommon/fabric/mounting/ShadowTree.cpp b/ReactCommon/fabric/mounting/ShadowTree.cpp index 4099d0f1195dce..654d26fed0558a 100644 --- a/ReactCommon/fabric/mounting/ShadowTree.cpp +++ b/ReactCommon/fabric/mounting/ShadowTree.cpp @@ -22,6 +22,141 @@ namespace facebook { namespace react { +/* + * Generates (possibly) a new tree where all nodes with non-obsolete `State` + * objects. If all `State` objects in the tree are not obsolete for the moment + * of calling, the function returns `nullptr` (as an indication that no + * additional work is required). + */ +static ShadowNode::Unshared progressState(ShadowNode const &shadowNode) { + auto isStateChanged = false; + auto areChildrenChanged = false; + + auto newState = shadowNode.getState(); + if (newState) { + newState = newState->getMostRecentStateIfObsolete(); + if (newState) { + isStateChanged = true; + } + } + + auto newChildren = ShadowNode::ListOfShared{}; + if (shadowNode.getChildren().size() > 0) { + auto index = size_t{0}; + for (auto const &childNode : shadowNode.getChildren()) { + auto newChildNode = progressState(*childNode); + if (newChildNode) { + if (!areChildrenChanged) { + // Making a copy before the first mutation. + newChildren = shadowNode.getChildren(); + } + newChildren[index] = newChildNode; + areChildrenChanged = true; + } + index++; + } + } + + if (!areChildrenChanged && !isStateChanged) { + return nullptr; + } + + return shadowNode.clone({ + ShadowNodeFragment::propsPlaceholder(), + areChildrenChanged ? std::make_shared( + std::move(newChildren)) + : ShadowNodeFragment::childrenPlaceholder(), + isStateChanged ? newState : ShadowNodeFragment::statePlaceholder(), + }); +} + +/* + * An optimized version of the previous function (and relies on it). + * The function uses a given base tree to exclude unchanged (equal) parts + * of the three from the traversing. + */ +static ShadowNode::Unshared progressState( + ShadowNode const &shadowNode, + ShadowNode const &baseShadowNode) { + // The intuition behind the complexity: + // - A very few nodes have associated state, therefore it's mostly reading and + // it only writes when state objects were found obsolete; + // - Most before-after trees are aligned, therefore most tree branches will be + // skipped; + // - If trees are significantly different, any other algorithm will have + // close to linear complexity. + + auto isStateChanged = false; + auto areChildrenChanged = false; + + auto newState = shadowNode.getState(); + if (newState) { + newState = newState->getMostRecentStateIfObsolete(); + if (newState) { + isStateChanged = true; + } + } + + auto &children = shadowNode.getChildren(); + auto &baseChildren = baseShadowNode.getChildren(); + auto newChildren = ShadowNode::ListOfShared{}; + + auto childrenSize = children.size(); + auto baseChildrenSize = baseChildren.size(); + auto index = size_t{0}; + + // Stage 1: Aligned part. + for (index = 0; index < childrenSize && index < baseChildrenSize; index++) { + const auto &childNode = *children.at(index); + const auto &baseChildNode = *baseChildren.at(index); + + if (&childNode == &baseChildNode) { + // Nodes are identical, skipping. + continue; + } + + if (!ShadowNode::sameFamily(childNode, baseChildNode)) { + // Totally different nodes, updating is impossible. + break; + } + + auto newChildNode = progressState(childNode, baseChildNode); + if (newChildNode) { + if (!areChildrenChanged) { + // Making a copy before the first mutation. + newChildren = children; + } + newChildren[index] = newChildNode; + areChildrenChanged = true; + } + } + + // Stage 2: Misaligned part. + for (; index < childrenSize; index++) { + auto newChildNode = progressState(*children.at(index)); + if (newChildNode) { + if (!areChildrenChanged) { + // Making a copy before the first mutation. + newChildren = children; + } + newChildren[index] = newChildNode; + areChildrenChanged = true; + } + } + + if (!areChildrenChanged && !isStateChanged) { + return nullptr; + } + + return shadowNode.clone({ + ShadowNodeFragment::propsPlaceholder(), + areChildrenChanged ? std::make_shared( + std::move(newChildren)) + : ShadowNodeFragment::childrenPlaceholder(), + isStateChanged ? newState : ShadowNodeFragment::statePlaceholder(), + }); +} + static void updateMountedFlag( const SharedShadowNodeList &oldChildren, const SharedShadowNodeList &newChildren) { @@ -161,14 +296,23 @@ bool ShadowTree::tryCommit( return false; } - // Compare state revisions of old and new root - // Children of the root node may be mutated in-place if (enableStateReconciliation) { - UnsharedShadowNode reconciledNode = - reconcileStateWithTree(newRootShadowNode.get(), oldRootShadowNode); - if (reconciledNode != nullptr) { - newRootShadowNode = std::make_shared( - *reconciledNode, ShadowNodeFragment{}); + if (enableNewStateReconciliation_) { + auto updatedNewRootShadowNode = + progressState(*newRootShadowNode, *oldRootShadowNode); + if (updatedNewRootShadowNode) { + newRootShadowNode = + std::static_pointer_cast(updatedNewRootShadowNode); + } + } else { + // Compare state revisions of old and new root + // Children of the root node may be mutated in-place + UnsharedShadowNode reconciledNode = + reconcileStateWithTree(newRootShadowNode.get(), oldRootShadowNode); + if (reconciledNode != nullptr) { + newRootShadowNode = std::make_shared( + *reconciledNode, ShadowNodeFragment{}); + } } } diff --git a/ReactCommon/fabric/mounting/ShadowTree.h b/ReactCommon/fabric/mounting/ShadowTree.h index a2e9aaa1742055..f0c904d5159a0c 100644 --- a/ReactCommon/fabric/mounting/ShadowTree.h +++ b/ReactCommon/fabric/mounting/ShadowTree.h @@ -71,6 +71,14 @@ class ShadowTree final { MountingCoordinator::Shared getMountingCoordinator() const; + /* + * Temporary. + * Do not use. + */ + void setEnableNewStateReconciliation(bool value) { + enableNewStateReconciliation_ = value; + } + private: RootShadowNode::Unshared cloneRootShadowNode( RootShadowNode::Shared const &oldRootShadowNode, @@ -88,6 +96,7 @@ class ShadowTree final { mutable ShadowTreeRevision::Number revisionNumber_{ 0}; // Protected by `commitMutex_`. MountingCoordinator::Shared mountingCoordinator_; + bool enableNewStateReconciliation_{false}; }; } // namespace react diff --git a/ReactCommon/fabric/mounting/tests/MountingTelemetryTest.cpp b/ReactCommon/fabric/mounting/tests/MountingTelemetryTest.cpp index 8d1426675b85bb..cf31109a38fa32 100644 --- a/ReactCommon/fabric/mounting/tests/MountingTelemetryTest.cpp +++ b/ReactCommon/fabric/mounting/tests/MountingTelemetryTest.cpp @@ -27,7 +27,7 @@ void sleep(double durationInSeconds) { } TEST(MountingTelemetryTest, timepoints) { - auto threshold = int64_t{10}; + auto threshold = int64_t{70}; auto timepointA = telemetryTimePointNow(); sleep(0.1); @@ -39,7 +39,7 @@ TEST(MountingTelemetryTest, timepoints) { } TEST(MountingTelemetryTest, normalUseCase) { - auto threshold = int64_t{10}; + auto threshold = int64_t{70}; auto telemetry = MountingTelemetry{}; telemetry.willCommit(); diff --git a/ReactCommon/fabric/mounting/tests/MountingTest.cpp b/ReactCommon/fabric/mounting/tests/MountingTest.cpp index 4783516bf1c4a5..52361e23dc5ab3 100644 --- a/ReactCommon/fabric/mounting/tests/MountingTest.cpp +++ b/ReactCommon/fabric/mounting/tests/MountingTest.cpp @@ -77,6 +77,11 @@ TEST(MountingTest, testMinimalInstructionGeneration) { auto childD = makeNode(viewComponentDescriptor, 103, {}); auto childE = makeNode(viewComponentDescriptor, 104, {}); auto childF = makeNode(viewComponentDescriptor, 105, {}); + auto childG = makeNode(viewComponentDescriptor, 106, {}); + auto childH = makeNode(viewComponentDescriptor, 107, {}); + auto childI = makeNode(viewComponentDescriptor, 108, {}); + auto childJ = makeNode(viewComponentDescriptor, 109, {}); + auto childK = makeNode(viewComponentDescriptor, 110, {}); auto family = viewComponentDescriptor.createFamily( {10, SurfaceId(1), nullptr}, nullptr); @@ -107,6 +112,17 @@ TEST(MountingTest, testMinimalInstructionGeneration) { generateDefaultProps(viewComponentDescriptor), std::make_shared(SharedShadowNodeList{ childB, childA, childD, childF, childE, childC})}); + auto shadowNodeV7 = shadowNodeV6->clone(ShadowNodeFragment{ + generateDefaultProps(viewComponentDescriptor), + std::make_shared(SharedShadowNodeList{childF, + childE, + childC, + childD, + childG, + childH, + childI, + childJ, + childK})}); // Injecting a tree into the root node. auto rootNodeV1 = std::static_pointer_cast( @@ -139,6 +155,11 @@ TEST(MountingTest, testMinimalInstructionGeneration) { ShadowNodeFragment{ShadowNodeFragment::propsPlaceholder(), std::make_shared( SharedShadowNodeList{shadowNodeV6})})); + auto rootNodeV7 = std::static_pointer_cast( + rootNodeV6->ShadowNode::clone( + ShadowNodeFragment{ShadowNodeFragment::propsPlaceholder(), + std::make_shared( + SharedShadowNodeList{shadowNodeV7})})); // Layout and diff std::vector affectedLayoutableNodesV1{}; @@ -307,6 +328,23 @@ TEST(MountingTest, testMinimalInstructionGeneration) { assert(mutations5[3].type == ShadowViewMutation::Insert); assert(mutations5[3].newChildShadowView.tag == 105); assert(mutations5[3].index == 3); + + auto mutations6 = calculateShadowViewMutations( + DifferentiatorMode::OptimizedMoves, *rootNodeV6, *rootNodeV7); + + // The order and exact mutation instructions here may change at any time. + // This test just ensures that any changes are intentional. + // This test, in particular, ensures that a bug has been fixed: that with + // a particular sequence of inserts/removes/moves, we don't unintentionally + // create more "CREATE" mutations than necessary. + // The actual nodes that should be created in this transaction have a tag > + // 105. + assert(mutations6.size() == 25); + for (int i = 0; i < mutations6.size(); i++) { + if (mutations6[i].type == ShadowViewMutation::Create) { + assert(mutations6[i].newChildShadowView.tag > 105); + } + } } } // namespace react diff --git a/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp b/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp index 5eb9c6aa0c8583..ab2ad89b990449 100644 --- a/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp +++ b/ReactCommon/fabric/mounting/tests/ShadowTreeLifeCycleTest.cpp @@ -114,6 +114,9 @@ static void testShadowNodeTreeLifeCycle( LOG(ERROR) << "Entropy seed: " << entropy.getSeed() << "\n"; + // There are some issues getting `getDebugDescription` to compile + // under test on Android for now. +#ifndef ANDROID LOG(ERROR) << "Shadow Tree before: \n" << currentRootNode->getDebugDescription(); LOG(ERROR) << "Shadow Tree after: \n" @@ -128,6 +131,7 @@ static void testShadowNodeTreeLifeCycle( LOG(ERROR) << "Mutations:" << "\n" << getDebugDescription(mutations, {}); +#endif FAIL(); } @@ -165,7 +169,7 @@ TEST(MountingTest, stableSmallerTreeMoreIterationsClassic) { TEST(MountingTest, stableBiggerTreeFewerIterationsOptimizedMoves) { testShadowNodeTreeLifeCycle( DifferentiatorMode::OptimizedMoves, - /* seed */ 1, + /* seed */ 0, /* size */ 512, /* repeats */ 32, /* stages */ 32); @@ -174,7 +178,7 @@ TEST(MountingTest, stableBiggerTreeFewerIterationsOptimizedMoves) { TEST(MountingTest, stableSmallerTreeMoreIterationsOptimizedMoves) { testShadowNodeTreeLifeCycle( DifferentiatorMode::OptimizedMoves, - /* seed */ 1, + /* seed */ 0, /* size */ 16, /* repeats */ 512, /* stages */ 32); diff --git a/ReactCommon/fabric/scheduler/AsynchronousEventBeat.cpp b/ReactCommon/fabric/scheduler/AsynchronousEventBeat.cpp new file mode 100644 index 00000000000000..2649227d327ffd --- /dev/null +++ b/ReactCommon/fabric/scheduler/AsynchronousEventBeat.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "AsynchronousEventBeat.h" + +namespace facebook { +namespace react { + +AsynchronousEventBeat::AsynchronousEventBeat( + RunLoopObserver::Unique uiRunLoopObserver, + RuntimeExecutor runtimeExecutor) + : EventBeat({}), + uiRunLoopObserver_(std::move(uiRunLoopObserver)), + runtimeExecutor_(std::move(runtimeExecutor)) { + uiRunLoopObserver_->setDelegate(this); + uiRunLoopObserver_->enable(); +} + +void AsynchronousEventBeat::activityDidChange( + RunLoopObserver::Delegate const *delegate, + RunLoopObserver::Activity activity) const noexcept { + assert(delegate == this); + induce(); +} + +void AsynchronousEventBeat::induce() const { + if (!isRequested_) { + return; + } + + // Here we know that `this` object exists because the caller has a strong + // pointer to `owner`. To ensure the object will exist inside + // `runtimeExecutor_` callback, we need to copy the pointer there. + auto weakOwner = uiRunLoopObserver_->getOwner(); + + runtimeExecutor_([this, weakOwner](jsi::Runtime &runtime) mutable { + auto owner = weakOwner.lock(); + if (!owner) { + return; + } + + if (!isRequested_) { + return; + } + + this->beat(runtime); + }); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/scheduler/AsynchronousEventBeat.h b/ReactCommon/fabric/scheduler/AsynchronousEventBeat.h new file mode 100644 index 00000000000000..6e95c9b8f7918d --- /dev/null +++ b/ReactCommon/fabric/scheduler/AsynchronousEventBeat.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * Event beat associated with JavaScript runtime. + * The beat is called on `RuntimeExecutor`'s thread induced by the UI thread + * event loop. + */ +class AsynchronousEventBeat : public EventBeat, + public RunLoopObserver::Delegate { + public: + AsynchronousEventBeat( + RunLoopObserver::Unique uiRunLoopObserver, + RuntimeExecutor runtimeExecutor); + + void induce() const override; + +#pragma mark - RunLoopObserver::Delegate + + void activityDidChange( + RunLoopObserver::Delegate const *delegate, + RunLoopObserver::Activity activity) const noexcept override; + + private: + RunLoopObserver::Unique uiRunLoopObserver_; + RuntimeExecutor runtimeExecutor_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/scheduler/BUCK b/ReactCommon/fabric/scheduler/BUCK index 527e6756d5f96d..e65958365b3007 100644 --- a/ReactCommon/fabric/scheduler/BUCK +++ b/ReactCommon/fabric/scheduler/BUCK @@ -36,6 +36,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -48,13 +49,13 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", "//xplat/jsi:JSIDynamic", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", react_native_xplat_target("fabric/core:core"), react_native_xplat_target("fabric/mounting:mounting"), react_native_xplat_target("fabric/uimanager:uimanager"), diff --git a/ReactCommon/fabric/scheduler/Scheduler.cpp b/ReactCommon/fabric/scheduler/Scheduler.cpp index 671713b4b69a8a..e9db21ae7e7812 100644 --- a/ReactCommon/fabric/scheduler/Scheduler.cpp +++ b/ReactCommon/fabric/scheduler/Scheduler.cpp @@ -80,6 +80,14 @@ Scheduler::Scheduler( delegate_ = delegate; uiManager_ = uiManager; + +#ifdef ANDROID + enableNewStateReconciliation_ = reactNativeConfig_->getBool( + "react_fabric:enable_new_state_reconciliation_android"); +#else + enableNewStateReconciliation_ = reactNativeConfig_->getBool( + "react_fabric:enable_new_state_reconciliation_ios"); +#endif } Scheduler::~Scheduler() { @@ -141,6 +149,8 @@ void Scheduler::startSurface( *rootComponentDescriptor_, *uiManager_); + shadowTree->setEnableNewStateReconciliation(enableNewStateReconciliation_); + auto uiManager = uiManager_; uiManager->getShadowTreeRegistry().add(std::move(shadowTree)); diff --git a/ReactCommon/fabric/scheduler/Scheduler.h b/ReactCommon/fabric/scheduler/Scheduler.h index 59e91c5dfa711a..07799c62f1fa46 100644 --- a/ReactCommon/fabric/scheduler/Scheduler.h +++ b/ReactCommon/fabric/scheduler/Scheduler.h @@ -10,6 +10,7 @@ #include #include +#include #include #include #include @@ -21,7 +22,6 @@ #include #include #include -#include namespace facebook { namespace react { @@ -112,6 +112,7 @@ class Scheduler final : public UIManagerDelegate { std::shared_ptr uiManager_; std::shared_ptr reactNativeConfig_; EventDispatcher::Shared eventDispatcher_; + bool enableNewStateReconciliation_{false}; }; } // namespace react diff --git a/ReactCommon/fabric/scheduler/SchedulerToolbox.h b/ReactCommon/fabric/scheduler/SchedulerToolbox.h index 1862f1889fd0de..87462d89377ff1 100644 --- a/ReactCommon/fabric/scheduler/SchedulerToolbox.h +++ b/ReactCommon/fabric/scheduler/SchedulerToolbox.h @@ -7,10 +7,10 @@ #pragma once +#include #include #include #include -#include namespace facebook { namespace react { diff --git a/ReactCommon/fabric/scheduler/SynchronousEventBeat.cpp b/ReactCommon/fabric/scheduler/SynchronousEventBeat.cpp new file mode 100644 index 00000000000000..a30552eb51c29e --- /dev/null +++ b/ReactCommon/fabric/scheduler/SynchronousEventBeat.cpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#import "SynchronousEventBeat.h" + +namespace facebook { +namespace react { + +SynchronousEventBeat::SynchronousEventBeat( + RunLoopObserver::Unique uiRunLoopObserver, + RuntimeExecutor runtimeExecutor) + : EventBeat({}), + uiRunLoopObserver_(std::move(uiRunLoopObserver)), + runtimeExecutor_(std::move(runtimeExecutor)) { + uiRunLoopObserver_->setDelegate(this); + uiRunLoopObserver_->enable(); +} + +void SynchronousEventBeat::activityDidChange( + RunLoopObserver::Delegate const *delegate, + RunLoopObserver::Activity activity) const noexcept { + assert(delegate == this); + lockExecutorAndBeat(); +} + +void SynchronousEventBeat::induce() const { + if (!this->isRequested_) { + return; + } + + if (uiRunLoopObserver_->isOnRunLoopThread()) { + this->lockExecutorAndBeat(); + } +} + +void SynchronousEventBeat::lockExecutorAndBeat() const { + if (!this->isRequested_) { + return; + } + + executeSynchronouslyOnSameThread_CAN_DEADLOCK( + runtimeExecutor_, [this](jsi::Runtime &runtime) { beat(runtime); }); +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/scheduler/SynchronousEventBeat.h b/ReactCommon/fabric/scheduler/SynchronousEventBeat.h new file mode 100644 index 00000000000000..bf192e9078aff5 --- /dev/null +++ b/ReactCommon/fabric/scheduler/SynchronousEventBeat.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * Event beat associated with main run loop. + * The callback is always called on the main thread. + */ +class SynchronousEventBeat final : public EventBeat, + public RunLoopObserver::Delegate { + public: + SynchronousEventBeat( + RunLoopObserver::Unique uiRunLoopObserver, + RuntimeExecutor runtimeExecutor); + + void induce() const override; + +#pragma mark - RunLoopObserver::Delegate + + void activityDidChange( + RunLoopObserver::Delegate const *delegate, + RunLoopObserver::Activity activity) const noexcept override; + + private: + void lockExecutorAndBeat() const; + + RunLoopObserver::Unique uiRunLoopObserver_; + RuntimeExecutor runtimeExecutor_; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/fabric/templateprocessor/BUCK b/ReactCommon/fabric/templateprocessor/BUCK index 4a35935675458a..168a55862964e0 100644 --- a/ReactCommon/fabric/templateprocessor/BUCK +++ b/ReactCommon/fabric/templateprocessor/BUCK @@ -37,6 +37,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -50,13 +51,13 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", "//xplat/jsi:JSIDynamic", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", react_native_xplat_target("fabric/core:core"), react_native_xplat_target("fabric/uimanager:uimanager"), react_native_xplat_target("fabric/componentregistry:componentregistry"), diff --git a/ReactCommon/fabric/textlayoutmanager/BUCK b/ReactCommon/fabric/textlayoutmanager/BUCK index ba629ee394966b..720f3d3e8e2344 100644 --- a/ReactCommon/fabric/textlayoutmanager/BUCK +++ b/ReactCommon/fabric/textlayoutmanager/BUCK @@ -75,6 +75,7 @@ rn_xplat_cxx_library( ], prefix = "", ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( [ "platform/android/**/*.cpp", @@ -117,11 +118,11 @@ rn_xplat_cxx_library( ], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/attributedstring:attributedstring"), react_native_xplat_target("fabric/core:core"), diff --git a/ReactCommon/fabric/uimanager/BUCK b/ReactCommon/fabric/uimanager/BUCK index e2bdd3b4c26864..0d46cf3f3fea90 100644 --- a/ReactCommon/fabric/uimanager/BUCK +++ b/ReactCommon/fabric/uimanager/BUCK @@ -37,6 +37,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), @@ -50,20 +51,20 @@ rn_xplat_cxx_library( tests = [":tests"], visibility = ["PUBLIC"], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", "//xplat/jsi:JSIDynamic", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", react_native_xplat_target("config:config"), react_native_xplat_target("fabric/components/view:view"), react_native_xplat_target("fabric/mounting:mounting"), react_native_xplat_target("fabric/core:core"), react_native_xplat_target("fabric/componentregistry:componentregistry"), react_native_xplat_target("fabric/debug:debug"), - react_native_xplat_target("utils:utils"), + react_native_xplat_target("runtimeexecutor:runtimeexecutor"), ], ) diff --git a/ReactCommon/fabric/uimanager/UIManager.cpp b/ReactCommon/fabric/uimanager/UIManager.cpp index c2fa6be9278cf7..e87280c58cd28a 100644 --- a/ReactCommon/fabric/uimanager/UIManager.cpp +++ b/ReactCommon/fabric/uimanager/UIManager.cpp @@ -125,11 +125,11 @@ void UIManager::clearJSResponder() const { } ShadowNode::Shared const *UIManager::getNewestCloneOfShadowNode( - ShadowNode::Shared const &shadowNode) const { + ShadowNode const &shadowNode) const { auto findNewestChildInParent = [&](auto const &parentNode) -> ShadowNode::Shared const * { for (auto const &child : parentNode.getChildren()) { - if (ShadowNode::sameFamily(*child, *shadowNode)) { + if (ShadowNode::sameFamily(*child, shadowNode)) { return &child; } } @@ -138,7 +138,7 @@ ShadowNode::Shared const *UIManager::getNewestCloneOfShadowNode( ShadowNode const *ancestorShadowNode; shadowTreeRegistry_.visit( - shadowNode->getSurfaceId(), [&](ShadowTree const &shadowTree) { + shadowNode.getSurfaceId(), [&](ShadowTree const &shadowTree) { shadowTree.tryCommit( [&](RootShadowNode::Shared const &oldRootShadowNode) { ancestorShadowNode = oldRootShadowNode.get(); @@ -147,7 +147,7 @@ ShadowNode::Shared const *UIManager::getNewestCloneOfShadowNode( true); }); - auto ancestors = shadowNode->getFamily().getAncestors(*ancestorShadowNode); + auto ancestors = shadowNode.getFamily().getAncestors(*ancestorShadowNode); return findNewestChildInParent(ancestors.rbegin()->first.get()); } @@ -156,7 +156,7 @@ ShadowNode::Shared UIManager::findNodeAtPoint( ShadowNode::Shared const &node, Point point) const { return LayoutableShadowNode::findNodeAtPoint( - *getNewestCloneOfShadowNode(node), point); + *getNewestCloneOfShadowNode(*node), point); } void UIManager::setNativeProps( @@ -200,10 +200,18 @@ LayoutMetrics UIManager::getRelativeLayoutMetrics( }, true); }); + } else { + ancestorShadowNode = getNewestCloneOfShadowNode(*ancestorShadowNode)->get(); } + // Get latest version of both the ShadowNode and its ancestor. + // It is possible for JS (or other callers) to have a reference + // to a previous version of ShadowNodes, but we enforce that + // metrics are only calculated on most recently committed versions. + auto newestShadowNode = getNewestCloneOfShadowNode(shadowNode); + auto layoutableShadowNode = - traitCast(&shadowNode); + traitCast(newestShadowNode->get()); auto layoutableAncestorShadowNode = traitCast(ancestorShadowNode); @@ -251,6 +259,10 @@ void UIManager::dispatchCommand( } } +void UIManager::configureNextLayoutAnimation( + const folly::dynamic config, + SharedEventTarget successCallback, + SharedEventTarget errorCallback) const {} void UIManager::setComponentDescriptorRegistry( const SharedComponentDescriptorRegistry &componentDescriptorRegistry) { componentDescriptorRegistry_ = componentDescriptorRegistry; diff --git a/ReactCommon/fabric/uimanager/UIManager.h b/ReactCommon/fabric/uimanager/UIManager.h index 7d282d43836205..956f459f935cee 100644 --- a/ReactCommon/fabric/uimanager/UIManager.h +++ b/ReactCommon/fabric/uimanager/UIManager.h @@ -93,7 +93,7 @@ class UIManager final : public ShadowTreeDelegate { Point point) const; ShadowNode::Shared const *getNewestCloneOfShadowNode( - ShadowNode::Shared const &shadowNode) const; + ShadowNode const &shadowNode) const; /* * Returns layout metrics of given `shadowNode` relative to @@ -116,6 +116,14 @@ class UIManager final : public ShadowTreeDelegate { std::string const &commandName, folly::dynamic const args) const; + /** + * Configure a LayoutAnimation to happen on the next commit. + * This API configures a global LayoutAnimation starting from the root node. + */ + void configureNextLayoutAnimation( + const folly::dynamic config, + SharedEventTarget successCallback, + SharedEventTarget errorCallback) const; ShadowTreeRegistry const &getShadowTreeRegistry() const; SharedComponentDescriptorRegistry componentDescriptorRegistry_; diff --git a/ReactCommon/fabric/uimanager/UIManagerBinding.cpp b/ReactCommon/fabric/uimanager/UIManagerBinding.cpp index 981a165bc669f9..4c50095e4416a8 100644 --- a/ReactCommon/fabric/uimanager/UIManagerBinding.cpp +++ b/ReactCommon/fabric/uimanager/UIManagerBinding.cpp @@ -535,10 +535,15 @@ jsi::Value UIManagerBinding::get( *shadowNodeFromValue(runtime, arguments[0]), nullptr, {/* .includeTransform = */ true}); - auto frame = layoutMetrics.frame; auto onSuccessFunction = arguments[1].getObject(runtime).getFunction(runtime); + if (layoutMetrics == EmptyLayoutMetrics) { + onSuccessFunction.call(runtime, {0, 0, 0, 0, 0, 0}); + return jsi::Value::undefined(); + } + + auto frame = layoutMetrics.frame; onSuccessFunction.call( runtime, {0, @@ -568,8 +573,13 @@ jsi::Value UIManagerBinding::get( auto onSuccessFunction = arguments[1].getObject(runtime).getFunction(runtime); - auto frame = layoutMetrics.frame; + if (layoutMetrics == EmptyLayoutMetrics) { + onSuccessFunction.call(runtime, {0, 0, 0, 0}); + return jsi::Value::undefined(); + } + + auto frame = layoutMetrics.frame; onSuccessFunction.call( runtime, {jsi::Value{runtime, (double)frame.origin.x}, @@ -598,6 +608,27 @@ jsi::Value UIManagerBinding::get( }); } + if (methodName == "configureNextLayoutAnimation") { + return jsi::Function::createFromHostFunction( + runtime, + name, + 3, + [uiManager]( + jsi::Runtime &runtime, + const jsi::Value &thisValue, + const jsi::Value *arguments, + size_t count) -> jsi::Value { + uiManager->configureNextLayoutAnimation( + commandArgsFromValue( + runtime, + arguments[0]), // TODO T66507273: do a better job of parsing + // these arguments into a real struct / use a + // C++ typed object instead of folly::dynamic + eventTargetFromValue(runtime, arguments[1], -1), + eventTargetFromValue(runtime, arguments[2], -1)); + return jsi::Value::undefined(); + }); + } return jsi::Value::undefined(); } diff --git a/ReactCommon/hermes/inspector/BUCK b/ReactCommon/hermes/inspector/BUCK index 5b5356b799794b..9757b023533637 100644 --- a/ReactCommon/hermes/inspector/BUCK +++ b/ReactCommon/hermes/inspector/BUCK @@ -50,7 +50,9 @@ fb_xplat_cxx_library( header_namespace = "hermes/inspector", exported_headers = CHROME_EXPORTED_HEADERS, compiler_flags = CFLAGS_BY_MODE[hermes_build_mode()], + fbandroid_labels = ["supermodule:android/default/public.hermes"], fbobjc_header_path_prefix = "hermes/inspector/chrome", + fbobjc_labels = ["supermodule:ios/default/public.hermes"], macosx_tests_override = [], tests = [":chrome-tests"], visibility = [ @@ -61,12 +63,12 @@ fb_xplat_cxx_library( react_native_xplat_target("jsinspector:jsinspector"), ":detail", ":inspectorlib", + "//third-party/glog:glog", "//xplat/folly:futures", "//xplat/folly:molly", "//xplat/hermes/API:HermesAPI", "//xplat/jsi:JSIDynamic", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", ], ) @@ -116,7 +118,9 @@ fb_xplat_cxx_library( fbandroid_deps = [ "//fbandroid/native/fb:fb", ], + fbandroid_labels = ["supermodule:android/default/public.hermes"], fbobjc_header_path_prefix = "hermes/inspector/detail", + fbobjc_labels = ["supermodule:ios/default/public.hermes"], macosx_tests_override = [], tests = [":detail-tests"], visibility = [ @@ -188,7 +192,9 @@ fb_xplat_cxx_library( exported_headers = INSPECTOR_EXPORTED_HEADERS, compiler_flags = CFLAGS_BY_MODE[hermes_build_mode()], cxx_tests = [":inspector-tests"], + fbandroid_labels = ["supermodule:android/default/public.hermes"], fbobjc_header_path_prefix = "hermes/inspector", + fbobjc_labels = ["supermodule:ios/default/public.hermes"], macosx_tests_override = [], visibility = [ "PUBLIC", @@ -196,11 +202,11 @@ fb_xplat_cxx_library( xcode_public_headers_symlinks = True, deps = [ ":detail", + "//third-party/glog:glog", "//xplat/folly:futures", "//xplat/folly:molly", "//xplat/hermes/API:HermesAPI", "//xplat/jsi:jsi", - "//xplat/third-party/glog:glog", ], ) diff --git a/ReactCommon/hermes/inspector/Inspector.cpp b/ReactCommon/hermes/inspector/Inspector.cpp index 7376b578aa1e1c..3cca8ce1553b22 100644 --- a/ReactCommon/hermes/inspector/Inspector.cpp +++ b/ReactCommon/hermes/inspector/Inspector.cpp @@ -384,7 +384,8 @@ folly::Future Inspector::setPauseOnExceptions( folly::Future Inspector::setPauseOnLoads( const PauseOnLoadMode mode) { - std::unique_lock lock(mutex_); + // This flag does not touch the runtime, so it doesn't need the executor. + // Return a future anyways for consistency. auto promise = std::make_shared>(); pauseOnLoadMode_ = mode; promise->setValue(); diff --git a/ReactCommon/hermes/inspector/chrome/Connection.cpp b/ReactCommon/hermes/inspector/chrome/Connection.cpp index 6c170f312d3827..b7656bcf22c64d 100644 --- a/ReactCommon/hermes/inspector/chrome/Connection.cpp +++ b/ReactCommon/hermes/inspector/chrome/Connection.cpp @@ -35,6 +35,10 @@ namespace debugger = ::facebook::hermes::debugger; namespace inspector = ::facebook::hermes::inspector; namespace m = ::facebook::hermes::inspector::chrome::message; +static const char *const kVirtualBreakpointPrefix = "virtualbreakpoint-"; +static const char *const kBeforeScriptWithSourceMapExecution = + "beforeScriptWithSourceMapExecution"; + /* * Connection::Impl */ @@ -77,6 +81,8 @@ class Connection::Impl : public inspector::InspectorObserver, void handle(const m::debugger::ResumeRequest &req) override; void handle(const m::debugger::SetBreakpointRequest &req) override; void handle(const m::debugger::SetBreakpointByUrlRequest &req) override; + void handle( + const m::debugger::SetInstrumentationBreakpointRequest &req) override; void handle(const m::debugger::SetPauseOnExceptionsRequest &req) override; void handle(const m::debugger::StepIntoRequest &req) override; void handle(const m::debugger::StepOutRequest &req) override; @@ -88,7 +94,6 @@ class Connection::Impl : public inspector::InspectorObserver, const m::heapProfiler::StopTrackingHeapObjectsRequest &req) override; void handle(const m::runtime::EvaluateRequest &req) override; void handle(const m::runtime::GetPropertiesRequest &req) override; - void handle(const m::hermes::SetPauseOnLoadRequest &req) override; private: std::vector makePropsFromScope( @@ -111,6 +116,7 @@ class Connection::Impl : public inspector::InspectorObserver, folly::Function sendErrorToClient(int id); void sendResponseToClientViaExecutor(int id); void sendResponseToClientViaExecutor(folly::Future future, int id); + void sendResponseToClientViaExecutor(const m::Response &resp); void sendNotificationToClientViaExecutor(const m::Notification ¬e); void sendErrorToClientViaExecutor(int id, const std::string &error); @@ -131,6 +137,19 @@ class Connection::Impl : public inspector::InspectorObserver, std::mutex parsedScriptsMutex_; std::vector parsedScripts_; + // Some events are represented as a mode in Hermes but a breakpoint in CDP, + // e.g. "beforeScriptExecution" and "beforeScriptWithSourceMapExecution". + // Keep track of these separately. The caller should lock the + // virtualBreakpointMutex_. + std::mutex virtualBreakpointMutex_; + uint32_t nextVirtualBreakpoint_ = 1; + const std::string &createVirtualBreakpoint(const std::string &category); + bool isVirtualBreakpointId(const std::string &id); + bool hasVirtualBreakpoint(const std::string &category); + bool removeVirtualBreakpoint(const std::string &id); + std::unordered_map> + virtualBreakpoints_; + // The rest of these member variables are only accessed via executor_. std::unique_ptr executor_; std::unique_ptr remoteConn_; @@ -272,6 +291,7 @@ void Connection::Impl::onContextCreated(Inspector &inspector) { void Connection::Impl::onPause( Inspector &inspector, const debugger::ProgramState &state) { + bool sendNotification = true; m::debugger::PausedNotification note; note.callFrames = m::debugger::makeCallFrames(state, objTable_, getRuntime()); @@ -291,15 +311,37 @@ void Connection::Impl::onPause( case debugger::PauseReason::Exception: note.reason = "exception"; break; - case debugger::PauseReason::ScriptLoaded: - note.reason = "load"; + case debugger::PauseReason::ScriptLoaded: { + note.reason = "other"; + note.hitBreakpoints = std::vector(); + + std::lock_guard lock(virtualBreakpointMutex_); + for (auto &bp : + virtualBreakpoints_[kBeforeScriptWithSourceMapExecution]) { + note.hitBreakpoints->emplace_back(bp); + } + + // Debuggers don't tend to ever remove these kinds of breakpoints, but + // in the extremely unlikely event that it did *and* did it exactly + // between us 1. checking that we should stop, and 2. adding the stop + // reason here, then just resume and skip sending a pause notification. + if (note.hitBreakpoints->empty()) { + sendNotification = false; + inspector_->resume(); + } + }; + // This will be toggled back on in the next onScriptParsed if applicable + // Locking is handled by didPause in the inspector + inspector_->setPauseOnLoads(PauseOnLoadMode::None); break; default: note.reason = "other"; break; } - sendNotificationToClientViaExecutor(note); + if (sendNotification) { + sendNotificationToClientViaExecutor(note); + } } void Connection::Impl::onResume(Inspector &inspector) { @@ -318,6 +360,15 @@ void Connection::Impl::onScriptParsed( if (!info.sourceMappingUrl.empty()) { note.sourceMapURL = info.sourceMappingUrl; + + std::lock_guard lock(virtualBreakpointMutex_); + if (hasVirtualBreakpoint(kBeforeScriptWithSourceMapExecution)) { + // We are precariously relying on the fact that onScriptParsed + // is invoked immediately before the pause load mode is checked. + // That means that we can check for breakpoints and toggle the + // mode here, and then immediately turn it off in onPause. + inspector_->setPauseOnLoads(PauseOnLoadMode::All); + } } { @@ -525,9 +576,18 @@ void Connection::Impl::handle(const m::debugger::PauseRequest &req) { } void Connection::Impl::handle(const m::debugger::RemoveBreakpointRequest &req) { - auto breakpointId = folly::to(req.breakpointId); - sendResponseToClientViaExecutor( - inspector_->removeBreakpoint(breakpointId), req.id); + if (isVirtualBreakpointId(req.breakpointId)) { + std::lock_guard lock(virtualBreakpointMutex_); + if (!removeVirtualBreakpoint(req.breakpointId)) { + sendErrorToClientViaExecutor( + req.id, "Unknown breakpoint ID: " + req.breakpointId); + } + sendResponseToClientViaExecutor(req.id); + } else { + auto breakpointId = folly::to(req.breakpointId); + sendResponseToClientViaExecutor( + inspector_->removeBreakpoint(breakpointId), req.id); + } } void Connection::Impl::handle(const m::debugger::ResumeRequest &req) { @@ -594,6 +654,51 @@ void Connection::Impl::handle( .thenError(sendErrorToClient(req.id)); } +bool Connection::Impl::isVirtualBreakpointId(const std::string &id) { + return id.rfind(kVirtualBreakpointPrefix, 0) == 0; +} + +const std::string &Connection::Impl::createVirtualBreakpoint( + const std::string &category) { + auto ret = virtualBreakpoints_[category].insert(folly::to( + kVirtualBreakpointPrefix, nextVirtualBreakpoint_++)); + return *ret.first; +} + +bool Connection::Impl::hasVirtualBreakpoint(const std::string &category) { + auto pos = virtualBreakpoints_.find(category); + if (pos == virtualBreakpoints_.end()) + return false; + return !pos->second.empty(); +} + +bool Connection::Impl::removeVirtualBreakpoint(const std::string &id) { + // We expect roughly 1 category, so just iterate over all the sets + for (auto &kv : virtualBreakpoints_) { + if (kv.second.erase(id) > 0) { + return true; + } + } + return false; +} + +void Connection::Impl::handle( + const m::debugger::SetInstrumentationBreakpointRequest &req) { + if (req.instrumentation != kBeforeScriptWithSourceMapExecution) { + sendErrorToClientViaExecutor( + req.id, "Unknown instrumentation breakpoint: " + req.instrumentation); + return; + } + + // The act of creating and registering the breakpoint ID is enough + // to "set" it. We merely check for the existence of them later. + std::lock_guard lock(virtualBreakpointMutex_); + m::debugger::SetInstrumentationBreakpointResponse resp; + resp.id = req.id; + resp.breakpointId = createVirtualBreakpoint(req.instrumentation); + sendResponseToClientViaExecutor(resp); +} + void Connection::Impl::handle( const m::debugger::SetPauseOnExceptionsRequest &req) { debugger::PauseOnThrowMode mode = debugger::PauseOnThrowMode::None; @@ -761,21 +866,6 @@ void Connection::Impl::handle(const m::runtime::GetPropertiesRequest &req) { .thenError(sendErrorToClient(req.id)); } -void Connection::Impl::handle(const m::hermes::SetPauseOnLoadRequest &req) { - PauseOnLoadMode mode; - if (req.state == "none") { - mode = PauseOnLoadMode::None; - } else if (req.state == "all") { - mode = PauseOnLoadMode::All; - } else if (req.state == "smart") { - mode = PauseOnLoadMode::Smart; - } else { - sendErrorToClientViaExecutor(req.id, "Unrecognized pause on load mode"); - return; - } - sendResponseToClientViaExecutor(inspector_->setPauseOnLoads(mode), req.id); -} - /* * Send-to-client methods */ @@ -806,6 +896,15 @@ void Connection::Impl::sendResponseToClientViaExecutor(int id) { sendResponseToClientViaExecutor(folly::makeFuture(), id); } +void Connection::Impl::sendResponseToClientViaExecutor( + const m::Response &resp) { + std::string json = resp.toJson(); + + folly::makeFuture() + .via(executor_.get()) + .thenValue([this, json](const Unit &unit) { sendToClient(json); }); +} + void Connection::Impl::sendResponseToClientViaExecutor( folly::Future future, int id) { diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp index 18ce5ac65a6a60..d40c05e14727d9 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.cpp @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<<0d7691362d081e7bc44d2b7a0ed24371>> +// @generated SignedSource<<575de63c36edd2a9a0f191501fd4f662>> #include "MessageTypes.h" @@ -35,6 +35,8 @@ std::unique_ptr Request::fromJsonThrowOnError(const std::string &str) { {"Debugger.setBreakpoint", makeUnique}, {"Debugger.setBreakpointByUrl", makeUnique}, + {"Debugger.setInstrumentationBreakpoint", + makeUnique}, {"Debugger.setPauseOnExceptions", makeUnique}, {"Debugger.stepInto", makeUnique}, @@ -46,7 +48,6 @@ std::unique_ptr Request::fromJsonThrowOnError(const std::string &str) { makeUnique}, {"HeapProfiler.takeHeapSnapshot", makeUnique}, - {"Hermes.setPauseOnLoad", makeUnique}, {"Runtime.evaluate", makeUnique}, {"Runtime.getProperties", makeUnique}, }; @@ -506,6 +507,36 @@ void debugger::SetBreakpointByUrlRequest::accept( handler.handle(*this); } +debugger::SetInstrumentationBreakpointRequest:: + SetInstrumentationBreakpointRequest() + : Request("Debugger.setInstrumentationBreakpoint") {} + +debugger::SetInstrumentationBreakpointRequest:: + SetInstrumentationBreakpointRequest(const dynamic &obj) + : Request("Debugger.setInstrumentationBreakpoint") { + assign(id, obj, "id"); + assign(method, obj, "method"); + + dynamic params = obj.at("params"); + assign(instrumentation, params, "instrumentation"); +} + +dynamic debugger::SetInstrumentationBreakpointRequest::toDynamic() const { + dynamic params = dynamic::object; + put(params, "instrumentation", instrumentation); + + dynamic obj = dynamic::object; + put(obj, "id", id); + put(obj, "method", method); + put(obj, "params", std::move(params)); + return obj; +} + +void debugger::SetInstrumentationBreakpointRequest::accept( + RequestHandler &handler) const { + handler.handle(*this); +} + debugger::SetPauseOnExceptionsRequest::SetPauseOnExceptionsRequest() : Request("Debugger.setPauseOnExceptions") {} @@ -683,33 +714,6 @@ void heapProfiler::TakeHeapSnapshotRequest::accept( handler.handle(*this); } -hermes::SetPauseOnLoadRequest::SetPauseOnLoadRequest() - : Request("Hermes.setPauseOnLoad") {} - -hermes::SetPauseOnLoadRequest::SetPauseOnLoadRequest(const dynamic &obj) - : Request("Hermes.setPauseOnLoad") { - assign(id, obj, "id"); - assign(method, obj, "method"); - - dynamic params = obj.at("params"); - assign(state, params, "state"); -} - -dynamic hermes::SetPauseOnLoadRequest::toDynamic() const { - dynamic params = dynamic::object; - put(params, "state", state); - - dynamic obj = dynamic::object; - put(obj, "id", id); - put(obj, "method", method); - put(obj, "params", std::move(params)); - return obj; -} - -void hermes::SetPauseOnLoadRequest::accept(RequestHandler &handler) const { - handler.handle(*this); -} - runtime::EvaluateRequest::EvaluateRequest() : Request("Runtime.evaluate") {} runtime::EvaluateRequest::EvaluateRequest(const dynamic &obj) @@ -873,6 +877,24 @@ dynamic debugger::SetBreakpointByUrlResponse::toDynamic() const { return obj; } +debugger::SetInstrumentationBreakpointResponse:: + SetInstrumentationBreakpointResponse(const dynamic &obj) { + assign(id, obj, "id"); + + dynamic res = obj.at("result"); + assign(breakpointId, res, "breakpointId"); +} + +dynamic debugger::SetInstrumentationBreakpointResponse::toDynamic() const { + dynamic res = dynamic::object; + put(res, "breakpointId", breakpointId); + + dynamic obj = dynamic::object; + put(obj, "id", id); + put(obj, "result", std::move(res)); + return obj; +} + runtime::EvaluateResponse::EvaluateResponse(const dynamic &obj) { assign(id, obj, "id"); diff --git a/ReactCommon/hermes/inspector/chrome/MessageTypes.h b/ReactCommon/hermes/inspector/chrome/MessageTypes.h index 3d7222fd6ac65a..931e19fb41ab29 100644 --- a/ReactCommon/hermes/inspector/chrome/MessageTypes.h +++ b/ReactCommon/hermes/inspector/chrome/MessageTypes.h @@ -1,5 +1,5 @@ // Copyright 2004-present Facebook. All Rights Reserved. -// @generated SignedSource<<08b66e22784e225b926d36131b9a7693>> +// @generated SignedSource<> #pragma once @@ -38,6 +38,8 @@ struct SetBreakpointByUrlRequest; struct SetBreakpointByUrlResponse; struct SetBreakpointRequest; struct SetBreakpointResponse; +struct SetInstrumentationBreakpointRequest; +struct SetInstrumentationBreakpointResponse; struct SetPauseOnExceptionsRequest; struct StepIntoRequest; struct StepOutRequest; @@ -73,10 +75,6 @@ struct StopTrackingHeapObjectsRequest; struct TakeHeapSnapshotRequest; } // namespace heapProfiler -namespace hermes { -struct SetPauseOnLoadRequest; -} // namespace hermes - /// RequestHandler handles requests via the visitor pattern. struct RequestHandler { virtual ~RequestHandler() = default; @@ -90,6 +88,8 @@ struct RequestHandler { virtual void handle(const debugger::ResumeRequest &req) = 0; virtual void handle(const debugger::SetBreakpointRequest &req) = 0; virtual void handle(const debugger::SetBreakpointByUrlRequest &req) = 0; + virtual void handle( + const debugger::SetInstrumentationBreakpointRequest &req) = 0; virtual void handle(const debugger::SetPauseOnExceptionsRequest &req) = 0; virtual void handle(const debugger::StepIntoRequest &req) = 0; virtual void handle(const debugger::StepOutRequest &req) = 0; @@ -99,7 +99,6 @@ struct RequestHandler { virtual void handle( const heapProfiler::StopTrackingHeapObjectsRequest &req) = 0; virtual void handle(const heapProfiler::TakeHeapSnapshotRequest &req) = 0; - virtual void handle(const hermes::SetPauseOnLoadRequest &req) = 0; virtual void handle(const runtime::EvaluateRequest &req) = 0; virtual void handle(const runtime::GetPropertiesRequest &req) = 0; }; @@ -115,6 +114,8 @@ struct NoopRequestHandler : public RequestHandler { void handle(const debugger::ResumeRequest &req) override {} void handle(const debugger::SetBreakpointRequest &req) override {} void handle(const debugger::SetBreakpointByUrlRequest &req) override {} + void handle( + const debugger::SetInstrumentationBreakpointRequest &req) override {} void handle(const debugger::SetPauseOnExceptionsRequest &req) override {} void handle(const debugger::StepIntoRequest &req) override {} void handle(const debugger::StepOutRequest &req) override {} @@ -124,7 +125,6 @@ struct NoopRequestHandler : public RequestHandler { void handle( const heapProfiler::StopTrackingHeapObjectsRequest &req) override {} void handle(const heapProfiler::TakeHeapSnapshotRequest &req) override {} - void handle(const hermes::SetPauseOnLoadRequest &req) override {} void handle(const runtime::EvaluateRequest &req) override {} void handle(const runtime::GetPropertiesRequest &req) override {} }; @@ -351,6 +351,16 @@ struct debugger::SetBreakpointByUrlRequest : public Request { folly::Optional condition; }; +struct debugger::SetInstrumentationBreakpointRequest : public Request { + SetInstrumentationBreakpointRequest(); + explicit SetInstrumentationBreakpointRequest(const folly::dynamic &obj); + + folly::dynamic toDynamic() const override; + void accept(RequestHandler &handler) const override; + + std::string instrumentation; +}; + struct debugger::SetPauseOnExceptionsRequest : public Request { SetPauseOnExceptionsRequest(); explicit SetPauseOnExceptionsRequest(const folly::dynamic &obj); @@ -417,16 +427,6 @@ struct heapProfiler::TakeHeapSnapshotRequest : public Request { folly::Optional treatGlobalObjectsAsRoots; }; -struct hermes::SetPauseOnLoadRequest : public Request { - SetPauseOnLoadRequest(); - explicit SetPauseOnLoadRequest(const folly::dynamic &obj); - - folly::dynamic toDynamic() const override; - void accept(RequestHandler &handler) const override; - - std::string state; -}; - struct runtime::EvaluateRequest : public Request { EvaluateRequest(); explicit EvaluateRequest(const folly::dynamic &obj); @@ -499,6 +499,14 @@ struct debugger::SetBreakpointByUrlResponse : public Response { std::vector locations; }; +struct debugger::SetInstrumentationBreakpointResponse : public Response { + SetInstrumentationBreakpointResponse() = default; + explicit SetInstrumentationBreakpointResponse(const folly::dynamic &obj); + folly::dynamic toDynamic() const override; + + debugger::BreakpointId breakpointId{}; +}; + struct runtime::EvaluateResponse : public Response { EvaluateResponse() = default; explicit EvaluateResponse(const folly::dynamic &obj); diff --git a/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.cpp b/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.cpp index 9b85251ab0d415..5f9f96b9bc48b7 100644 --- a/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.cpp +++ b/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.cpp @@ -87,6 +87,10 @@ folly::Future AsyncHermesRuntime::getStoredValue() { return storedValue_.getFuture(); } +bool AsyncHermesRuntime::hasStoredValue() { + return storedValue_.isFulfilled(); +} + jsi::Value AsyncHermesRuntime::awaitStoredValue( std::chrono::milliseconds timeout) { return getStoredValue().get(timeout); diff --git a/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.h b/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.h index e1b8b24d7d70ed..b249746c407622 100644 --- a/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.h +++ b/ReactCommon/hermes/inspector/chrome/tests/AsyncHermesRuntime.h @@ -52,6 +52,11 @@ class AsyncHermesRuntime { */ folly::Future getStoredValue(); + /** + * hasStoredValue returns whether or not a value has been stored yet + */ + bool hasStoredValue(); + /** * awaitStoredValue is a helper for getStoredValue that returns the value * synchronously rather than in a future. diff --git a/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp b/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp index 18208192f67009..b55194a1869e1e 100644 --- a/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp +++ b/ReactCommon/hermes/inspector/chrome/tests/ConnectionTests.cpp @@ -748,6 +748,46 @@ TEST(ConnectionTests, testSetBreakpointById) { expectNotification(conn); } +TEST(ConnectionTests, testSetBreakpointByIdWithColumnInIndenting) { + TestContext context; + AsyncHermesRuntime &asyncRuntime = context.runtime(); + SyncConnection &conn = context.conn(); + int msgId = 1; + + asyncRuntime.executeScriptAsync(R"( + debugger; // line 1 + Math.random(); // 2 + )"); + + send(conn, ++msgId); + expectExecutionContextCreated(conn); + auto script = expectNotification(conn); + + expectPaused(conn, "other", {{"global", 1, 1}}); + + m::debugger::SetBreakpointRequest req; + req.id = ++msgId; + req.location.scriptId = script.scriptId; + req.location.lineNumber = 2; + // Specify a column location *before* rather than *on* the actual location + req.location.columnNumber = 0; + + conn.send(req.toJson()); + auto resp = expectResponse(conn, req.id); + EXPECT_EQ(resp.actualLocation.scriptId, script.scriptId); + EXPECT_EQ(resp.actualLocation.lineNumber, 2); + // Check that we resolved the column to the first available location + EXPECT_EQ(resp.actualLocation.columnNumber.value(), 4); + + send(conn, ++msgId); + expectNotification(conn); + + expectPaused(conn, "other", {{"global", 2, 1}}); + + send(conn, ++msgId); + expectNotification(conn); +} + TEST(ConnectionTests, testSetLazyBreakpoint) { TestContext context; AsyncHermesRuntime &asyncRuntime = context.runtime(); @@ -2231,6 +2271,84 @@ function foo(){x=1}debugger;foo(); expectNotification(conn); } +TEST(ConnectionTests, canBreakOnScriptsWithSourceMap) { + TestContext context; + AsyncHermesRuntime &asyncRuntime = context.runtime(); + SyncConnection &conn = context.conn(); + int msgId = 1; + + send(conn, msgId++); + expectExecutionContextCreated(conn); + + m::debugger::SetInstrumentationBreakpointRequest req; + req.id = msgId++; + req.instrumentation = "beforeScriptWithSourceMapExecution"; + + conn.send(req.toJson()); + auto bpId = expectResponse( + conn, req.id) + .breakpointId; + + asyncRuntime.executeScriptAsync(R"( + storeValue(42); debugger; + //# sourceURL=http://example.com/source.js + //# sourceMappingURL=http://example.com/source.map + )"); + expectNotification(conn); + + // We should get a pause before the first statement + auto note = expectNotification(conn); + ASSERT_FALSE(asyncRuntime.hasStoredValue()); + EXPECT_EQ(note.reason, "other"); + ASSERT_TRUE(note.hitBreakpoints.hasValue()); + ASSERT_EQ(note.hitBreakpoints->size(), 1); + EXPECT_EQ(note.hitBreakpoints->at(0), bpId); + + // Continue and verify that the JS code has now executed + send(conn, msgId++); + expectNotification(conn); + expectNotification(conn); + EXPECT_EQ(asyncRuntime.awaitStoredValue().asNumber(), 42); + + // Resume and exit + send(conn, msgId++); + expectNotification(conn); +} + +TEST(ConnectionTests, wontStopOnFilesWithoutSourceMaps) { + TestContext context; + AsyncHermesRuntime &asyncRuntime = context.runtime(); + SyncConnection &conn = context.conn(); + int msgId = 1; + + send(conn, msgId++); + expectExecutionContextCreated(conn); + + m::debugger::SetInstrumentationBreakpointRequest req; + req.id = msgId++; + req.instrumentation = "beforeScriptWithSourceMapExecution"; + + conn.send(req.toJson()); + expectResponse( + conn, req.id); + + // This script has no source map, so it should not trigger a break + asyncRuntime.executeScriptAsync(R"( + storeValue(42); debugger; + //# sourceURL=http://example.com/source.js + )"); + expectNotification(conn); + + // Continue and verify that the JS code has now executed without first + // pausing on the script load. + expectNotification(conn); + EXPECT_EQ(asyncRuntime.awaitStoredValue().asNumber(), 42); + + // Resume and exit + send(conn, msgId++); + expectNotification(conn); +} + } // namespace chrome } // namespace inspector } // namespace hermes diff --git a/ReactCommon/hermes/inspector/tools/message_types.txt b/ReactCommon/hermes/inspector/tools/message_types.txt index 6d02ed4e754d6e..0db4a6b7709ce9 100644 --- a/ReactCommon/hermes/inspector/tools/message_types.txt +++ b/ReactCommon/hermes/inspector/tools/message_types.txt @@ -10,6 +10,7 @@ Debugger.resumed Debugger.scriptParsed Debugger.setBreakpoint Debugger.setBreakpointByUrl +Debugger.setInstrumentationBreakpoint Debugger.setPauseOnExceptions Debugger.stepInto Debugger.stepOut @@ -23,4 +24,3 @@ Runtime.consoleAPICalled Runtime.evaluate Runtime.executionContextCreated Runtime.getProperties -Hermes.setPauseOnLoad diff --git a/ReactCommon/jsi/jsi/jsi.cpp b/ReactCommon/jsi/jsi/jsi.cpp index 73a27892580cd4..388f122c178c9e 100644 --- a/ReactCommon/jsi/jsi/jsi.cpp +++ b/ReactCommon/jsi/jsi/jsi.cpp @@ -450,5 +450,11 @@ void JSError::setValue(Runtime& rt, Value&& value) { } } +JSIException::~JSIException() {} + +JSINativeException::~JSINativeException() {} + +JSError::~JSError() {} + } // namespace jsi } // namespace facebook diff --git a/ReactCommon/jsi/jsi/jsi.h b/ReactCommon/jsi/jsi/jsi.h index 677e9049498e18..e48f524a105b1d 100644 --- a/ReactCommon/jsi/jsi/jsi.h +++ b/ReactCommon/jsi/jsi/jsi.h @@ -1212,6 +1212,8 @@ class JSI_EXPORT JSIException : public std::exception { return what_.c_str(); } + virtual ~JSIException(); + protected: std::string what_; }; @@ -1221,6 +1223,8 @@ class JSI_EXPORT JSIException : public std::exception { class JSI_EXPORT JSINativeException : public JSIException { public: JSINativeException(std::string what) : JSIException(std::move(what)) {} + + virtual ~JSINativeException(); }; /// This exception will be thrown by API functions whenever a JS @@ -1249,6 +1253,8 @@ class JSI_EXPORT JSError : public JSIException { /// but necessary to avoid ambiguity with the above. JSError(std::string what, Runtime& rt, Value&& value); + virtual ~JSError(); + const std::string& getStack() const { return stack_; } diff --git a/ReactCommon/jsiexecutor/BUCK b/ReactCommon/jsiexecutor/BUCK index 5eeaf7638fa369..1edfe366a9ac7e 100644 --- a/ReactCommon/jsiexecutor/BUCK +++ b/ReactCommon/jsiexecutor/BUCK @@ -16,10 +16,11 @@ cxx_library( "-frtti", ], fbandroid_deps = [ + "//third-party/glog:glog", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", "//xplat/third-party/linker_lib:atomic", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_force_static = True, fbobjc_header_path_prefix = "", fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], diff --git a/ReactCommon/jsinspector/BUCK b/ReactCommon/jsinspector/BUCK index 18cb5aeaf394c9..22b569eabee601 100644 --- a/ReactCommon/jsinspector/BUCK +++ b/ReactCommon/jsinspector/BUCK @@ -30,6 +30,7 @@ rn_xplat_cxx_library( "-fexceptions", "-std=c++1y", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_preferred_linkage = "shared", fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], visibility = [ diff --git a/ReactCommon/microprofiler/BUCK b/ReactCommon/microprofiler/BUCK index 09cb9ae5053496..571b3cea525be1 100644 --- a/ReactCommon/microprofiler/BUCK +++ b/ReactCommon/microprofiler/BUCK @@ -16,6 +16,7 @@ cxx_library( "-fexceptions", "-fno-data-sections", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], force_static = True, visibility = [ diff --git a/ReactCommon/jscallinvoker/.clang-tidy b/ReactCommon/runtimeexecutor/.clang-tidy similarity index 100% rename from ReactCommon/jscallinvoker/.clang-tidy rename to ReactCommon/runtimeexecutor/.clang-tidy diff --git a/ReactCommon/runtimeexecutor/Android.mk b/ReactCommon/runtimeexecutor/Android.mk new file mode 100644 index 00000000000000..b22071ecdab708 --- /dev/null +++ b/ReactCommon/runtimeexecutor/Android.mk @@ -0,0 +1,19 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +LOCAL_PATH := $(call my-dir) + +include $(CLEAR_VARS) + +LOCAL_MODULE := runtimeexecutor + +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/ReactCommon/*.cpp) + +LOCAL_C_INCLUDES := $(LOCAL_PATH)/ReactCommon +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +LOCAL_CFLAGS += -fexceptions -frtti -std=c++14 -Wall + +include $(BUILD_STATIC_LIBRARY) diff --git a/ReactCommon/runtimeexecutor/BUCK b/ReactCommon/runtimeexecutor/BUCK new file mode 100644 index 00000000000000..561b4c8d208b49 --- /dev/null +++ b/ReactCommon/runtimeexecutor/BUCK @@ -0,0 +1,53 @@ +load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_preprocessor_flags_for_build_mode") +load( + "//tools/build_defs/oss:rn_defs.bzl", + "ANDROID", + "APPLE", + "CXX", + "get_apple_compiler_flags", + "get_apple_inspector_flags", + "rn_xplat_cxx_library", +) + +APPLE_COMPILER_FLAGS = get_apple_compiler_flags() + +rn_xplat_cxx_library( + name = "runtimeexecutor", + srcs = glob( + [ + "**/*.cpp", + "**/*.mm", + ], + exclude = glob(["tests/**/*.cpp"]), + ), + headers = glob( + ["**/*.h"], + exclude = glob(["tests/**/*.h"]), + ), + header_namespace = "", + exported_headers = { + "ReactCommon/RuntimeExecutor.h": "ReactCommon/RuntimeExecutor.h", + }, + compiler_flags = [ + "-fexceptions", + "-frtti", + "-std=c++14", + "-Wall", + ], + fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, + fbobjc_frameworks = ["Foundation"], + fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], + fbobjc_preprocessor_flags = get_preprocessor_flags_for_build_mode() + get_apple_inspector_flags(), + force_static = True, + macosx_tests_override = [], + platforms = (ANDROID, APPLE, CXX), + preprocessor_flags = [ + "-DLOG_TAG=\"ReactNative\"", + "-DWITH_FBSYSTRACE=1", + ], + tests = [], + visibility = ["PUBLIC"], + deps = [ + "//xplat/jsi:jsi", + ], +) diff --git a/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec b/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec new file mode 100644 index 00000000000000..83f57ab1f5ea09 --- /dev/null +++ b/ReactCommon/runtimeexecutor/React-runtimeexecutor.podspec @@ -0,0 +1,36 @@ +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +require "json" + +package = JSON.parse(File.read(File.join(__dir__, "..", "..", "package.json"))) +version = package['version'] + +source = { :git => 'https://github.com/facebook/react-native.git' } +if version == '1000.0.0' + # This is an unpublished version, use the latest commit hash of the react-native repo, which we’re presumably in. + source[:commit] = `git rev-parse HEAD`.strip +else + source[:tag] = "v#{version}" +end + +folly_compiler_flags = '-DFOLLY_NO_CONFIG -DFOLLY_MOBILE=1 -DFOLLY_USE_LIBCPP=1 -Wno-comma -Wno-shorten-64-to-32' +folly_version = '2020.01.13.00' +boost_compiler_flags = '-Wno-documentation' + +Pod::Spec.new do |s| + s.name = "React-runtimeexecutor" + s.version = version + s.summary = "-" # TODO + s.homepage = "https://reactnative.dev/" + s.license = package["license"] + s.author = "Facebook, Inc. and its affiliates" + s.platforms = { :ios => "10.0", :tvos => "10.0", :osx => "10.14" } # TODO(macOS GH#214) + s.source = source + s.source_files = "**/*.{cpp,h}" + s.header_dir = "ReactCommon" + + s.dependency "React-jsi", version +end diff --git a/ReactCommon/utils/RuntimeExecutor.h b/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h similarity index 93% rename from ReactCommon/utils/RuntimeExecutor.h rename to ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h index bdde3603e610f9..e01e2df41c1da8 100644 --- a/ReactCommon/utils/RuntimeExecutor.h +++ b/ReactCommon/runtimeexecutor/ReactCommon/RuntimeExecutor.h @@ -78,12 +78,10 @@ inline static void executeSynchronouslyOnSameThread_CAN_DEADLOCK( std::function &&callback) noexcept { // Note: We need the third mutex to get back to the main thread before // the lambda is finished (because all mutexes are allocated on the stack). - // We use `recursive_mutex` here to not deadlock in case if a - // `RuntimeExecutor` executes the callback synchronously. - std::recursive_mutex mutex1; - std::recursive_mutex mutex2; - std::recursive_mutex mutex3; + std::mutex mutex1; + std::mutex mutex2; + std::mutex mutex3; mutex1.lock(); mutex2.lock(); diff --git a/ReactCommon/turbomodule/core/BUCK b/ReactCommon/turbomodule/core/BUCK index f3389ae5ad9c14..af7350e7f2ccad 100644 --- a/ReactCommon/turbomodule/core/BUCK +++ b/ReactCommon/turbomodule/core/BUCK @@ -28,6 +28,7 @@ rn_xplat_cxx_library( ], prefix = "ReactCommon", ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( [ "platform/android/**/*.cpp", @@ -70,12 +71,12 @@ rn_xplat_cxx_library( "PUBLIC", ], deps = [ + "//third-party/glog:glog", "//xplat/fbsystrace:fbsystrace", "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", "//xplat/jsi:JSIDynamic", - "//xplat/third-party/glog:glog", react_native_xplat_target("cxxreact:bridge"), react_native_xplat_target("cxxreact:module"), react_native_xplat_target("callinvoker:callinvoker"), diff --git a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm index f5a12a6dce6b26..f6179e0d344995 100644 --- a/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm +++ b/ReactCommon/turbomodule/core/platform/ios/RCTTurboModuleManager.mm @@ -321,12 +321,22 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name */ - (id)provideRCTTurboModule:(const char *)moduleName { - TurboModuleHolder *moduleHolder = [self _getOrCreateTurboModuleHolder:moduleName]; + TurboModuleHolder *moduleHolder; - if (!moduleHolder) { - return nil; + { + std::lock_guard guard(_turboModuleHoldersMutex); + if (_invalidating) { + return nil; + } + + moduleHolder = &_turboModuleHolders[moduleName]; } + return [self _provideRCTTurboModule:moduleName moduleHolder:moduleHolder]; +} + +- (id)_provideRCTTurboModule:(const char *)moduleName moduleHolder:(TurboModuleHolder *)moduleHolder +{ bool shouldCreateModule = false; { @@ -565,20 +575,6 @@ - (void)notifyAboutTurboModuleSetup:(const char *)name return module; } -/** - * Return a pointer to this TurboModule's TurboModuleHolder entry, creating one if it doesn't exist. - * Return nullptr if we've started teardown of TurboModuleManager. - */ -- (TurboModuleHolder *)_getOrCreateTurboModuleHolder:(const char *)moduleName -{ - std::lock_guard guard(_turboModuleHoldersMutex); - if (_invalidating) { - return nullptr; - } - - return &_turboModuleHolders[moduleName]; -} - /** * Should this TurboModule be created and initialized on the main queue? * @@ -732,15 +728,16 @@ - (void)bridgeDidInvalidateModules:(NSNotification *)notification // Backward-compatibility: RCTInvalidating handling. dispatch_group_t moduleInvalidationGroup = dispatch_group_create(); - for (const auto &pair : _turboModuleHolders) { + for (auto &pair : _turboModuleHolders) { std::string moduleName = pair.first; + TurboModuleHolder *moduleHolder = &pair.second; /** * We could start tearing down ReactNative before a TurboModule is fully initialized. In this case, we should wait - * for init to finish before we call invalidate on the module. Therefore, we call provideRCTTurboModule (because - * it's guaranteed to return a fully initialized NativeModule). + * for TurboModule init to finish before calling invalidate on it. So, we call _provideRCTTurboModule:moduleHolder, + * because it's guaranteed to return a fully initialized NativeModule. */ - id module = [self provideRCTTurboModule:moduleName.c_str()]; + id module = [self _provideRCTTurboModule:moduleName.c_str() moduleHolder:moduleHolder]; if ([module respondsToSelector:@selector(invalidate)]) { if ([module respondsToSelector:@selector(methodQueue)]) { diff --git a/ReactCommon/turbomodule/samples/BUCK b/ReactCommon/turbomodule/samples/BUCK index 1948f743955733..44173730827899 100644 --- a/ReactCommon/turbomodule/samples/BUCK +++ b/ReactCommon/turbomodule/samples/BUCK @@ -26,6 +26,7 @@ rn_xplat_cxx_library( ], prefix = "ReactCommon", ), + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbandroid_srcs = glob( [ "platform/android/**/*.cpp", @@ -36,6 +37,7 @@ rn_xplat_cxx_library( "-fobjc-arc-exceptions", ], fbobjc_inherited_buck_flags = get_static_library_ios_flags(), + fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], fbobjc_preprocessor_flags = OBJC_ARC_PREPROCESSOR_FLAGS + get_preprocessor_flags_for_build_mode(), force_static = True, ios_deps = [ diff --git a/ReactCommon/turbomodule/samples/SampleTurboCxxModule.cpp b/ReactCommon/turbomodule/samples/SampleTurboCxxModule.cpp index b970b2b72623d6..5d56c59d7ece20 100644 --- a/ReactCommon/turbomodule/samples/SampleTurboCxxModule.cpp +++ b/ReactCommon/turbomodule/samples/SampleTurboCxxModule.cpp @@ -5,9 +5,9 @@ * LICENSE file in the root directory of this source tree. */ -#import "SampleTurboCxxModule.h" +#include "SampleTurboCxxModule.h" -#import +#include using namespace facebook; diff --git a/ReactCommon/turbomodule/samples/SampleTurboCxxModule.h b/ReactCommon/turbomodule/samples/SampleTurboCxxModule.h index 7f1bd07bb1a789..c1ebb682362c64 100644 --- a/ReactCommon/turbomodule/samples/SampleTurboCxxModule.h +++ b/ReactCommon/turbomodule/samples/SampleTurboCxxModule.h @@ -7,9 +7,9 @@ #pragma once -#import +#include -#import "NativeSampleTurboCxxModuleSpecJSI.h" +#include "NativeSampleTurboCxxModuleSpecJSI.h" namespace facebook { namespace react { diff --git a/ReactCommon/utils/BUCK b/ReactCommon/utils/BUCK index dfcc229b285c5d..c9660e082d7157 100644 --- a/ReactCommon/utils/BUCK +++ b/ReactCommon/utils/BUCK @@ -39,6 +39,7 @@ rn_xplat_cxx_library( "-std=c++14", "-Wall", ], + fbandroid_labels = ["supermodule:android/default/public.react_native.infra"], fbobjc_compiler_flags = APPLE_COMPILER_FLAGS, fbobjc_frameworks = ["Foundation"], fbobjc_labels = ["supermodule:ios/default/public.react_native.infra"], diff --git a/ReactCommon/utils/RunLoopObserver.cpp b/ReactCommon/utils/RunLoopObserver.cpp new file mode 100644 index 00000000000000..bca81b6664d7b5 --- /dev/null +++ b/ReactCommon/utils/RunLoopObserver.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include "RunLoopObserver.h" + +#include + +namespace facebook { +namespace react { + +RunLoopObserver::RunLoopObserver( + Activity activities, + WeakOwner const &owner) noexcept + : activities_(activities), owner_(owner) {} + +void RunLoopObserver::setDelegate(Delegate const *delegate) const noexcept { + // We need these constraints to ensure basic thread-safety. + assert(delegate && "A delegate must not be `nullptr`."); + assert(!delegate_ && "`RunLoopObserver::setDelegate` must be called once."); + delegate_ = delegate; +} + +void RunLoopObserver::enable() const noexcept { + if (enabled_) { + return; + } + enabled_ = true; + + startObserving(); +} + +void RunLoopObserver::disable() const noexcept { + if (!enabled_) { + return; + } + enabled_ = false; + + stopObserving(); +} + +void RunLoopObserver::activityDidChange(Activity activity) const noexcept { + if (!enabled_) { + return; + } + + assert( + !owner_.expired() && + "`owner_` is null. The caller must `lock` the owner and check it for being not null."); + + delegate_->activityDidChange(delegate_, activity); +} + +RunLoopObserver::WeakOwner RunLoopObserver::getOwner() const noexcept { + return owner_; +} + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/utils/RunLoopObserver.h b/ReactCommon/utils/RunLoopObserver.h new file mode 100644 index 00000000000000..5bd7bd7a4c84c8 --- /dev/null +++ b/ReactCommon/utils/RunLoopObserver.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include +#include + +namespace facebook { +namespace react { + +/* + * A cross-platform abstraction for observing a run loop life cycle. + */ +class RunLoopObserver { + public: + using Unique = std::unique_ptr; + + /* + * The concept of an owner. + * A run loop observer normally observes a run loop running on a different + * thread. That implies that this other thread (the run loop thread) will call + * methods of this class owned by some other thread. To make it safe, we need + * to ensure that at the moment of the calling the observer still exists. To + * do so, we use an owner object (a weak pointer) that must retain (possibly + * indirectly) the observer. The platform-specific code should convert the + * weak pointer (owner) to a strong one right before calling the observer, + * ensuring the safety of calling; right after the call, the strong pointer + * should be safely released. + * + * Note, in the case when the pointer to the actual owner will be available + * later, only after calling the constructor of the class, the caller can + * create a dummy pointer beforehand and then merge it (using + * `shared_ptr(shared_ptr const &, X *)`) with the actual one (sharing + * the control block). + */ + using Owner = std::shared_ptr; + using WeakOwner = std::weak_ptr; + + /* + * Run loop activity stages which run loop observers can be observe. + */ + enum Activity : int32_t { + None = 0, + BeforeWaiting = 1 << 0, + AfterWaiting = 1 << 1, + }; + + /* + * A delegate interface. + */ + class Delegate { + public: + /* + * Called on every run loop tick at moments corresponding to requested + * activities. + * + * A platform-specific implementation guarantees that the owner pointer + * is retained during this call. + * Will be called on the thread associated with the run loop. + */ + virtual void activityDidChange(Delegate const *delegate, Activity activity) + const noexcept = 0; + + virtual ~Delegate() noexcept = default; + }; + + using Factory = std::function( + Activity activities, + WeakOwner const &owner)>; + + /* + * Constructs a run loop observer. + */ + RunLoopObserver(Activity activities, WeakOwner const &owner) noexcept; + virtual ~RunLoopObserver() noexcept = default; + + /* + * Sets the delegate. + * Must be called just once. + */ + void setDelegate(Delegate const *delegate) const noexcept; + + /* + * Enables or disables run loop observing. + * It can be used to save CPU cycles during periods of time when observing + * is not required. + * A newly constructed run time observer is initially disabled. + */ + void enable() const noexcept; + void disable() const noexcept; + + /* + * Returns true if called on a thread associated with the run loop. + * Must be implemented in subclasses. + */ + virtual bool isOnRunLoopThread() const noexcept = 0; + + /* + * Returns an owner associated with the observer. + * It might be useful to ensure the safety of consequent asynchronous calls. + */ + WeakOwner getOwner() const noexcept; + + protected: + /* + * Must be implemented in subclasses. + */ + virtual void startObserving() const noexcept = 0; + virtual void stopObserving() const noexcept = 0; + + /* + * Called by subclasses to generate a call on a delegate. + */ + void activityDidChange(Activity activity) const noexcept; + + Activity const activities_{}; + WeakOwner const owner_; + mutable Delegate const *delegate_{nullptr}; + mutable std::atomic enabled_{false}; +}; + +} // namespace react +} // namespace facebook diff --git a/ReactCommon/yoga/yoga/Yoga.cpp b/ReactCommon/yoga/yoga/Yoga.cpp index bb7da7bfd91d88..c2a5c286f99580 100644 --- a/ReactCommon/yoga/yoga/Yoga.cpp +++ b/ReactCommon/yoga/yoga/Yoga.cpp @@ -3664,8 +3664,8 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid( } YOGA_EXPORT float YGRoundValueToPixelGrid( - const float value, - const float pointScaleFactor, + const double value, + const double pointScaleFactor, const bool forceCeil, const bool forceFloor) { double scaledValue = ((double) value) * pointScaleFactor; @@ -4081,24 +4081,24 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor( static void YGRoundToPixelGrid( const YGNodeRef node, - const float pointScaleFactor, - const float absoluteLeft, - const float absoluteTop) { + const double pointScaleFactor, + const double absoluteLeft, + const double absoluteTop) { if (pointScaleFactor == 0.0f) { return; } - const float nodeLeft = node->getLayout().position[YGEdgeLeft]; - const float nodeTop = node->getLayout().position[YGEdgeTop]; + const double nodeLeft = node->getLayout().position[YGEdgeLeft]; + const double nodeTop = node->getLayout().position[YGEdgeTop]; - const float nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; - const float nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; + const double nodeWidth = node->getLayout().dimensions[YGDimensionWidth]; + const double nodeHeight = node->getLayout().dimensions[YGDimensionHeight]; - const float absoluteNodeLeft = absoluteLeft + nodeLeft; - const float absoluteNodeTop = absoluteTop + nodeTop; + const double absoluteNodeLeft = absoluteLeft + nodeLeft; + const double absoluteNodeTop = absoluteTop + nodeTop; - const float absoluteNodeRight = absoluteNodeLeft + nodeWidth; - const float absoluteNodeBottom = absoluteNodeTop + nodeHeight; + const double absoluteNodeRight = absoluteNodeLeft + nodeWidth; + const double absoluteNodeBottom = absoluteNodeTop + nodeHeight; // If a node has a custom measure function we never want to round down its // size as this could lead to unwanted text truncation. diff --git a/ReactCommon/yoga/yoga/Yoga.h b/ReactCommon/yoga/yoga/Yoga.h index 2fe60a4170da3e..87901a280ee84a 100644 --- a/ReactCommon/yoga/yoga/Yoga.h +++ b/ReactCommon/yoga/yoga/Yoga.h @@ -352,8 +352,8 @@ WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context); WIN_EXPORT void* YGConfigGetContext(YGConfigRef config); WIN_EXPORT float YGRoundValueToPixelGrid( - float value, - float pointScaleFactor, + double value, + double pointScaleFactor, bool forceCeil, bool forceFloor); diff --git a/package.json b/package.json index dcaa7c5a44094b..96b394ccb04919 100644 --- a/package.json +++ b/package.json @@ -107,7 +107,7 @@ "metro-react-native-babel-transformer": "0.59.0", "metro-source-map": "0.59.0", "nullthrows": "^1.1.1", - "pretty-format": "^25.4.0", + "pretty-format": "^26.0.1", "promise": "^8.0.3", "prop-types": "^15.7.2", "react-devtools-core": "^4.6.0", @@ -142,13 +142,13 @@ "eslint-plugin-react": "7.12.4", "eslint-plugin-react-hooks": "^3.0.0", "eslint-plugin-react-native": "3.8.1", - "eslint-plugin-relay": "1.7.0", - "flow-bin": "^0.123.0", + "eslint-plugin-relay": "1.7.1", + "flow-bin": "^0.124.0", "flow-remove-types": "1.2.3", "hermes-engine-darwin": "~0.5.0", - "jest": "^25.4.0", + "jest": "^26.0.1", "jest-junit": "^10.0.0", - "jscodeshift": "^0.7.0", + "jscodeshift": "^0.9.0", "mkdirp": "^0.5.1", "prettier": "1.19.1", "react": "16.13.1", @@ -156,7 +156,7 @@ "shelljs": "^0.7.8", "signedsource": "^1.0.0", "ws": "^6.1.4", - "yargs": "^14.2.0" + "yargs": "^15.3.1" }, "detox": { "test-runner": "jest", diff --git a/packages/react-native-codegen/.babelrc b/packages/react-native-codegen/.babelrc new file mode 100644 index 00000000000000..b8ac81899b77e0 --- /dev/null +++ b/packages/react-native-codegen/.babelrc @@ -0,0 +1,11 @@ +{ + "plugins": [ + "@babel/plugin-proposal-object-rest-spread", + "@babel/plugin-transform-async-to-generator", + "@babel/plugin-transform-destructuring", + "@babel/plugin-transform-flow-strip-types", + "@babel/plugin-syntax-dynamic-import", + "@babel/plugin-proposal-nullish-coalescing-operator", + "@babel/plugin-proposal-optional-chaining" + ] +} diff --git a/packages/react-native-codegen/.prettierrc b/packages/react-native-codegen/.prettierrc new file mode 100644 index 00000000000000..20374fd919f060 --- /dev/null +++ b/packages/react-native-codegen/.prettierrc @@ -0,0 +1,7 @@ +{ + "requirePragma": true, + "singleQuote": true, + "trailingComma": "all", + "bracketSpacing": false, + "jsxBracketSameLine": true +} diff --git a/packages/react-native-codegen/DEFS.bzl b/packages/react-native-codegen/DEFS.bzl index 9099034da04ca9..f54615a0494941 100644 --- a/packages/react-native-codegen/DEFS.bzl +++ b/packages/react-native-codegen/DEFS.bzl @@ -231,7 +231,7 @@ def rn_codegen_components( "//xplat/folly:headers_only", "//xplat/folly:memory", "//xplat/folly:molly", - "//xplat/third-party/glog:glog", + "//third-party/glog:glog", YOGA_CXX_TARGET, react_native_xplat_target("fabric/debug:debug"), react_native_xplat_target("fabric/core:core"), diff --git a/packages/react-native-codegen/package.json b/packages/react-native-codegen/package.json index 88d16e5f278f64..59168f8f95a1a9 100644 --- a/packages/react-native-codegen/package.json +++ b/packages/react-native-codegen/package.json @@ -7,16 +7,36 @@ "type": "git", "url": "git@github.com:facebook/react-native.git" }, + "scripts": { + "build": "yarn clean && node scripts/build.js --verbose", + "clean": "rm -rf lib", + "prepublish": "yarn run build" + }, "license": "MIT", "files": [ - "src" + "lib" ], "dependencies": { "flow-parser": "^0.121.0", - "jscodeshift": "^0.7.0", + "jscodeshift": "^0.9.0", "nullthrows": "^1.1.1" }, "beachball": { "shouldPublish": false - } + }, + "devDependencies": { + "@babel/core": "^7.0.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0", + "@babel/plugin-proposal-object-rest-spread": "^7.0.0", + "@babel/plugin-proposal-optional-chaining": "^7.0.0", + "@babel/plugin-syntax-dynamic-import": "^7.0.0", + "@babel/plugin-transform-async-to-generator": "^7.0.0", + "@babel/plugin-transform-destructuring": "^7.0.0", + "@babel/plugin-transform-flow-strip-types": "^7.0.0", + "chalk": "^4.0.0", + "glob": "^7.1.1", + "micromatch": "^4.0.2", + "mkdirp": "^0.5.1", + "prettier": "1.19.1" + } } diff --git a/packages/react-native-codegen/scripts/build.js b/packages/react-native-codegen/scripts/build.js new file mode 100644 index 00000000000000..9eefd4fdbb8f98 --- /dev/null +++ b/packages/react-native-codegen/scripts/build.js @@ -0,0 +1,117 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @format + */ + +/** + * script to build (transpile) files. + * + * Based off of the build script from Metro, and tweaked to run in just one + * package instead of in a monorepo. Just run `build.js` and the JS files in + * `src/` will be built in `lib/`, and the original source files will be copied + * over as `Example.js.flow`, so consumers of this module can still make use of + * type checking. + * + * Call this script with the `--verbose` flag to show the full output of this + * script. + */ + +'use strict'; + +const babel = require('@babel/core'); +const chalk = require('chalk'); +const fs = require('fs'); +const glob = require('glob'); +const micromatch = require('micromatch'); +const mkdirp = require('mkdirp'); +const path = require('path'); +const prettier = require('prettier'); +const prettierConfig = JSON.parse( + fs.readFileSync(path.resolve(__dirname, '..', '.prettierrc'), 'utf8'), +); + +const SRC_DIR = 'src'; +const BUILD_DIR = 'lib'; +const JS_FILES_PATTERN = '**/*.js'; +const IGNORE_PATTERN = '**/__tests__/**'; +const PACKAGE_DIR = path.resolve(__dirname, '../'); + +const fixedWidth = str => { + const WIDTH = 80; + const strs = str.match(new RegExp(`(.{1,${WIDTH}})`, 'g')) || [str]; + let lastString = strs[strs.length - 1]; + if (lastString.length < WIDTH) { + lastString += Array(WIDTH - lastString.length).join(chalk.dim('.')); + } + return strs + .slice(0, -1) + .concat(lastString) + .join('\n'); +}; + +function getBuildPath(file, buildFolder) { + const pkgSrcPath = path.resolve(PACKAGE_DIR, SRC_DIR); + const pkgBuildPath = path.resolve(PACKAGE_DIR, BUILD_DIR); + const relativeToSrcPath = path.relative(pkgSrcPath, file); + return path.resolve(pkgBuildPath, relativeToSrcPath); +} + +function buildFile(file, silent) { + const destPath = getBuildPath(file, BUILD_DIR); + + mkdirp.sync(path.dirname(destPath)); + if (micromatch.isMatch(file, IGNORE_PATTERN)) { + silent || + process.stdout.write( + chalk.dim(' \u2022 ') + + path.relative(PACKAGE_DIR, file) + + ' (ignore)\n', + ); + } else if (!micromatch.isMatch(file, JS_FILES_PATTERN)) { + fs.createReadStream(file).pipe(fs.createWriteStream(destPath)); + silent || + process.stdout.write( + chalk.red(' \u2022 ') + + path.relative(PACKAGE_DIR, file) + + chalk.red(' \u21D2 ') + + path.relative(PACKAGE_DIR, destPath) + + ' (copy)' + + '\n', + ); + } else { + const transformed = prettier.format( + babel.transformFileSync(file, {}).code, + { + ...prettierConfig, + parser: 'babel', + }, + ); + fs.writeFileSync(destPath, transformed); + const source = fs.readFileSync(file).toString('utf-8'); + if (/\@flow/.test(source)) { + fs.createReadStream(file).pipe(fs.createWriteStream(destPath + '.flow')); + } + silent || + process.stdout.write( + chalk.green(' \u2022 ') + + path.relative(PACKAGE_DIR, file) + + chalk.green(' \u21D2 ') + + path.relative(PACKAGE_DIR, destPath) + + '\n', + ); + } +} + +const srcDir = path.resolve(__dirname, '..', SRC_DIR); +const pattern = path.resolve(srcDir, '**/*'); +const files = glob.sync(pattern, {nodir: true}); + +process.stdout.write(fixedWidth(`${path.basename(PACKAGE_DIR)}\n`)); + +files.forEach(file => buildFile(file, !process.argv.includes('--verbose'))); + +process.stdout.write(`[ ${chalk.green('OK')} ]\n`); diff --git a/packages/react-native-codegen/src/CodegenSchema.js b/packages/react-native-codegen/src/CodegenSchema.js index 51d96416ff772e..17fb0d7df9c09d 100644 --- a/packages/react-native-codegen/src/CodegenSchema.js +++ b/packages/react-native-codegen/src/CodegenSchema.js @@ -10,6 +10,8 @@ 'use strict'; +export type PlatformType = 'iOS' | 'android'; + export type CommandsFunctionTypeAnnotation = $ReadOnly<{| type: 'FunctionTypeAnnotation', params: $ReadOnlyArray, @@ -309,8 +311,8 @@ export type OptionsShape = $ReadOnly<{| // Does not check for new name paperComponentName?: string, - // Use for components that are not used on one or the other platform. - excludedPlatform?: 'iOS' | 'android', + // Use for components that are not used on other platforms. + excludedPlatforms?: $ReadOnlyArray, // Use for components currently being renamed in paper // Will use new name if it is available and fallback to this name diff --git a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js index 6ecc358b3815f4..af61b2675e78a6 100644 --- a/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js +++ b/packages/react-native-codegen/src/generators/components/GenerateComponentHObjCpp.js @@ -337,7 +337,10 @@ module.exports = { return Object.keys(components) .filter(componentName => { const component = components[componentName]; - return component.excludedPlatform !== 'iOS'; + return !( + component.excludedPlatforms && + component.excludedPlatforms.includes('iOS') + ); }) .map(componentName => { return [ diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js b/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js index 0cfe41fa8c66ef..b6b03eb7d36979 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsCpp.js @@ -101,7 +101,10 @@ module.exports = { return Object.keys(components) .filter(componentName => { const component = components[componentName]; - return component.excludedPlatform !== 'iOS'; + return !( + component.excludedPlatforms && + component.excludedPlatforms.includes('iOS') + ); }) .map(componentName => { const component = components[componentName]; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js index adb94d16f442f4..a7ff3f9d77cda8 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsH.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsH.js @@ -768,7 +768,10 @@ module.exports = { return Object.keys(components) .filter(componentName => { const component = components[componentName]; - return component.excludedPlatform !== 'iOS'; + return !( + component.excludedPlatforms && + component.excludedPlatforms.includes('iOS') + ); }) .map(componentName => { const component = components[componentName]; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js index 17f587b0145327..08c99a48791373 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaDelegate.js @@ -274,7 +274,10 @@ module.exports = { return Object.keys(components) .filter(componentName => { const component = components[componentName]; - return component.excludedPlatform !== 'android'; + return !( + component.excludedPlatforms && + component.excludedPlatforms.includes('android') + ); }) .forEach(componentName => { const component = components[componentName]; diff --git a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js index bf4f42bbfc891d..af41763c82c0e5 100644 --- a/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js +++ b/packages/react-native-codegen/src/generators/components/GeneratePropsJavaInterface.js @@ -221,7 +221,10 @@ module.exports = { return Object.keys(components) .filter(componentName => { const component = components[componentName]; - return component.excludedPlatform !== 'android'; + return !( + component.excludedPlatforms && + component.excludedPlatforms.includes('android') + ); }) .forEach(componentName => { const component = components[componentName]; diff --git a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js index 6f3bf1becb890d..31689b483dcaed 100644 --- a/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/components/__test_fixtures__/fixtures.js @@ -1524,7 +1524,28 @@ const EXCLUDE_ANDROID: SchemaType = { ExcludedAndroid: { components: { ExcludedAndroidComponent: { - excludedPlatform: 'android', + excludedPlatforms: ['android'], + extendsProps: [ + { + type: 'ReactNativeBuiltInType', + knownTypeName: 'ReactNativeCoreViewProps', + }, + ], + events: [], + props: [], + commands: [], + }, + }, + }, + }, +}; + +const EXCLUDE_ANDROID_IOS: SchemaType = { + modules: { + ExcludedAndroidIos: { + components: { + ExcludedAndroidIosComponent: { + excludedPlatforms: ['android', 'iOS'], extendsProps: [ { type: 'ReactNativeBuiltInType', @@ -1566,4 +1587,5 @@ module.exports = { COMMANDS, COMMANDS_AND_PROPS, EXCLUDE_ANDROID, + EXCLUDE_ANDROID_IOS, }; diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap index 4c64141b0fbb36..e23ae48953f9ea 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentDescriptorH-test.js.snap @@ -286,6 +286,32 @@ using ExcludedAndroidComponentComponentDescriptor = ConcreteComponentDescriptor< } `; +exports[`GenerateComponentDescriptorH can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "ComponentDescriptors.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +using ExcludedAndroidIosComponentComponentDescriptor = ConcreteComponentDescriptor; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateComponentDescriptorH can generate fixture FLOAT_PROPS 1`] = ` Map { "ComponentDescriptors.h" => " diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap index 93b0a8b7f0ffe8..a921411cbe03a4 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateComponentHObjCpp-test.js.snap @@ -385,6 +385,27 @@ NS_ASSUME_NONNULL_BEGIN @end +NS_ASSUME_NONNULL_END", +} +`; + +exports[`GenerateComponentHObjCpp can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "RCTComponentViewHelpers.h" => "/** +* Copyright (c) Facebook, Inc. and its affiliates. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +#import +#import +#import + +NS_ASSUME_NONNULL_BEGIN + + + NS_ASSUME_NONNULL_END", } `; diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap index a13aedb1303c47..c70dc86ce28188 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterCpp-test.js.snap @@ -304,6 +304,29 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateEventEmitterCpp can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "EventEmitters.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap index 6b0076238052ea..229c08c3f15b42 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateEventEmitterH-test.js.snap @@ -330,6 +330,30 @@ namespace react { +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GenerateEventEmitterH can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "EventEmitters.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#pragma once + +#include + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap index 2d17c7496dc886..27ce7d45df9925 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsCpp-test.js.snap @@ -329,6 +329,30 @@ ExcludedAndroidComponentProps::ExcludedAndroidComponentProps( {} +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GeneratePropsCpp can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "Props.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap index 687290a402e574..3071e0e70ed107 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsH-test.js.snap @@ -574,6 +574,30 @@ class ExcludedAndroidComponentProps final : public ViewProps { }; +} // namespace react +} // namespace facebook +", +} +`; + +exports[`GeneratePropsH can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "Props.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +#pragma once + + + +namespace facebook { +namespace react { + + + } // namespace react } // namespace facebook ", diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap index 6ae0cd6f4f22c8..914f8e56da71a9 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaDelegate-test.js.snap @@ -442,6 +442,8 @@ public class InterfaceOnlyComponentManagerDelegate "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap index 45873d75b224bc..b064446f35b63a 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GeneratePropsJavaInterface-test.js.snap @@ -247,6 +247,8 @@ public interface InterfaceOnlyComponentManagerInterface { exports[`GeneratePropsJavaInterface can generate fixture EXCLUDE_ANDROID 1`] = `Map {}`; +exports[`GeneratePropsJavaInterface can generate fixture EXCLUDE_ANDROID_IOS 1`] = `Map {}`; + exports[`GeneratePropsJavaInterface can generate fixture FLOAT_PROPS 1`] = ` Map { "FloatPropNativeComponentManagerInterface.java" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap index 053638bd5b0b0e..22043570482540 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeCpp-test.js.snap @@ -253,6 +253,29 @@ extern const char ExcludedAndroidComponentComponentName[] = \\"ExcludedAndroidCo } `; +exports[`GenerateShadowNodeCpp can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "ShadowNodes.cpp" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include + +namespace facebook { +namespace react { + +extern const char ExcludedAndroidIosComponentComponentName[] = \\"ExcludedAndroidIosComponent\\"; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateShadowNodeCpp can generate fixture FLOAT_PROPS 1`] = ` Map { "ShadowNodes.cpp" => " diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap index 679337e818c9bc..5327702796da7c 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateShadowNodeH-test.js.snap @@ -360,6 +360,39 @@ using ExcludedAndroidComponentShadowNode = ConcreteViewShadowNode< } `; +exports[`GenerateShadowNodeH can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "ShadowNodes.h" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#pragma once + +#include +#include + +namespace facebook { +namespace react { + +extern const char ExcludedAndroidIosComponentComponentName[]; + +/* + * \`ShadowNode\` for component. + */ +using ExcludedAndroidIosComponentShadowNode = ConcreteViewShadowNode< + ExcludedAndroidIosComponentComponentName, + ExcludedAndroidIosComponentProps>; + +} // namespace react +} // namespace facebook +", +} +`; + exports[`GenerateShadowNodeH can generate fixture FLOAT_PROPS 1`] = ` Map { "ShadowNodes.h" => " diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap index 63141765868042..8f73a0c825023a 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateTests-test.js.snap @@ -354,6 +354,34 @@ TEST(ExcludedAndroidComponentProps_DoesNotDie, etc) { } `; +exports[`GenerateTests can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "Tests.cpp" => "/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +#include +#include +#include +#include +#include + +using namespace facebook::react; + +TEST(ExcludedAndroidIosComponentProps_DoesNotDie, etc) { + auto propParser = RawPropsParser(); + propParser.prepare(); + auto const &sourceProps = ExcludedAndroidIosComponentProps(); + auto const &rawProps = RawProps(folly::dynamic::object(\\"xx_invalid_xx\\", \\"xx_invalid_xx\\")); + rawProps.parse(propParser); + ExcludedAndroidIosComponentProps(sourceProps, rawProps); +}", +} +`; + exports[`GenerateTests can generate fixture FLOAT_PROPS 1`] = ` Map { "Tests.cpp" => "/** diff --git a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap index f7e1722e545a8e..d92c6470d7cfe8 100644 --- a/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap +++ b/packages/react-native-codegen/src/generators/components/__tests__/__snapshots__/GenerateViewConfigJs-test.js.snap @@ -483,6 +483,38 @@ export default nativeComponentName; } `; +exports[`GenerateViewConfigJs can generate fixture EXCLUDE_ANDROID_IOS 1`] = ` +Map { + "EXCLUDE_ANDROID_IOSNativeViewConfig.js" => " +/** + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + * @flow + */ + +'use strict'; + +const registerGeneratedViewConfig = require('registerGeneratedViewConfig'); + +const ExcludedAndroidIosComponentViewConfig = { + uiViewClassName: 'ExcludedAndroidIosComponent', + validAttributes: {}, +}; + +let nativeComponentName = 'ExcludedAndroidIosComponent'; + +registerGeneratedViewConfig(nativeComponentName, ExcludedAndroidIosComponentViewConfig); + +export const __INTERNAL_VIEW_CONFIG = ExcludedAndroidIosComponentViewConfig; + +export default nativeComponentName; +", +} +`; + exports[`GenerateViewConfigJs can generate fixture FLOAT_PROPS 1`] = ` Map { "FLOAT_PROPSNativeViewConfig.js" => " diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js index 87e9367bae09dd..474927f779940e 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleHObjCpp.js @@ -24,14 +24,15 @@ const { type FilesOutput = Map; -const moduleTemplate = ` -class JSI_EXPORT Native::_MODULE_NAME_::SpecJSI : public ObjCTurboModule { -public: - Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms); -};`; +const moduleTemplate = ` /** + * ObjC++ class for module '::_MODULE_NAME_::' + */ + class JSI_EXPORT Native::_MODULE_NAME_::SpecJSI : public ObjCTurboModule { + public: + Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms); + };`; -const protocolTemplate = ` -::_STRUCTS_:: +const protocolTemplate = `::_STRUCTS_:: @protocol Native::_MODULE_NAME_::Spec ::_MODULE_PROPERTIES_:: @@ -53,30 +54,36 @@ const template = ` * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * ${'@'}generated by codegen project: GenerateModuleHObjCpp.js */ -// NOTE: This entire file should be codegen'ed. +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif #import #import -#import +#import -#import #import +#import #import + +#import #import #import -#import + +#import ::_PROTOCOLS_:: namespace facebook { -namespace react { + namespace react { ::_MODULES_:: - -} // namespace react + } // namespace react } // namespace facebook `; @@ -184,6 +191,7 @@ module.exports = { moduleSpecName: string, ): FilesOutput { const nativeModules = Object.keys(schema.modules) + .sort() .map(moduleName => { const modules = schema.modules[moduleName].nativeModules; if (modules == null) { @@ -200,6 +208,7 @@ module.exports = { .join('\n'); const protocols = Object.keys(nativeModules) + .sort() .map(name => { const objectForGeneratingStructs: Array = []; const {properties} = nativeModules[name]; diff --git a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js index a0807282399c0f..448541cd995e96 100644 --- a/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js +++ b/packages/react-native-codegen/src/generators/modules/GenerateModuleMm.js @@ -18,38 +18,38 @@ const {flatObjects} = require('./ObjCppUtils/Utils'); type FilesOutput = Map; const propertyHeaderTemplate = - 'static facebook::jsi::Value __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {'; + ' static facebook::jsi::Value __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) {'; const propertyCastTemplate = `static_cast(turboModule) .invokeObjCMethod(rt, ::_KIND_::, "::_PROPERTY_NAME_::", @selector(::_PROPERTY_NAME_::::_ARGS_::), args, count);`; const propertyTemplate = ` ${propertyHeaderTemplate} - return ${propertyCastTemplate} -}`.trim(); + return ${propertyCastTemplate} + }`; -const proprertyDefTemplate = - ' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::};'; +const propertyDefTemplate = + ' methodMap_["::_PROPERTY_NAME_::"] = MethodMetadata {::_ARGS_COUNT_::, __hostFunction_Native::_MODULE_NAME_::SpecJSI_::_PROPERTY_NAME_::};'; const moduleTemplate = ` -::_TURBOMODULE_METHOD_INVOKERS_:: + ::_TURBOMODULE_METHOD_INVOKERS_:: -Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { -::_PROPERTIES_MAP_::::_CONVERSION_SELECTORS_:: -}`.trim(); + Native::_MODULE_NAME_::SpecJSI::Native::_MODULE_NAME_::SpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + ::_PROPERTIES_MAP_::::_CONVERSION_SELECTORS_:: + }`.trim(); const getterTemplate = ` - @implementation RCTCxxConvert (Native::_MODULE_NAME_::_Spec::_GETTER_NAME_::) +@implementation RCTCxxConvert (Native::_MODULE_NAME_::_Spec::_GETTER_NAME_::) + (RCTManagedPointer *)JS_Native::_MODULE_NAME_::_Spec::_GETTER_NAME_:::(id)json { return facebook::react::managedPointer(json); } @end -`.trim(); +`; const argConvertionTemplate = - '\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_Spec::_SELECTOR_NAME_:::");'; + '\n setMethodArgConversionSelector(@"::_ARG_NAME_::", ::_ARG_NUMBER_::, @"JS_Native::_MODULE_NAME_::_Spec::_SELECTOR_NAME_:::");'; const template = ` /** @@ -57,17 +57,18 @@ const template = ` * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * ${'@'}generated by codegen project: GenerateModuleMm.js */ #include <::_INCLUDE_::> +#import + ::_GETTERS_:: namespace facebook { -namespace react { - + namespace react { ::_MODULES_:: - - -} // namespace react + } // namespace react } // namespace facebook `; @@ -242,7 +243,7 @@ module.exports = { returnTypeAnnotation.properties && returnTypeAnnotation.properties.length === 0 ? '' - : proprertyDefTemplate + : propertyDefTemplate .replace(/::_PROPERTY_NAME_::/g, propertyName) .replace(/::_ARGS_COUNT_::/g, params.length.toString()), ) diff --git a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js index ae924598b0ee1f..416e7c549fb03d 100644 --- a/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js +++ b/packages/react-native-codegen/src/generators/modules/ObjCppUtils/GenerateStructs.js @@ -44,37 +44,65 @@ inline ::_RETURN_TYPE_::JS::Native::_MODULE_NAME_::::Spec::_STRUCT_NAME_::::::_P } `; +function getSafePropertyName(name: string) { + if (name === 'id') { + return `${name}_`; + } + return name; +} + function getInlineMethodSignature( property: ObjectParamTypeAnnotation, name: string, ): string { const {typeAnnotation} = property; + function markOptionalTypeIfNecessary(type) { + if (property.optional) { + return `folly::Optional<${type}>`; + } + return type; + } switch (typeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': switch (typeAnnotation.name) { case 'RootTag': - return `double ${property.name}() const;`; + return `double ${getSafePropertyName(property.name)}() const;`; default: (typeAnnotation.name: empty); throw new Error(`Unknown prop type, found: ${typeAnnotation.name}"`); } case 'StringTypeAnnotation': - return `NSString *${property.name}() const;`; + return `NSString *${getSafePropertyName(property.name)}() const;`; case 'NumberTypeAnnotation': case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': - return `double ${property.name}() const;`; + return `${markOptionalTypeIfNecessary('double')} ${getSafePropertyName( + property.name, + )}() const;`; case 'BooleanTypeAnnotation': - return `bool ${property.name}() const;`; - case 'ObjectTypeAnnotation': - return `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( + return `${markOptionalTypeIfNecessary('bool')} ${getSafePropertyName( property.name, - )} ${property.name}() const;`; + )}() const;`; + case 'ObjectTypeAnnotation': + return ( + markOptionalTypeIfNecessary( + `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( + getSafePropertyName(property.name), + )}`, + ) + ` ${getSafePropertyName(property.name)}() const;` + ); case 'GenericObjectTypeAnnotation': case 'AnyTypeAnnotation': - return `id ${property.name}() const;`; + if (property.optional) { + return `id _Nullable ${getSafePropertyName( + property.name, + )}() const;`; + } + return `id ${getSafePropertyName(property.name)}() const;`; case 'ArrayTypeAnnotation': - return `facebook::react::LazyVector> ${property.name}() const;`; + return `${markOptionalTypeIfNecessary( + 'facebook::react::LazyVector>', + )} ${getSafePropertyName(property.name)}() const;`; case 'FunctionTypeAnnotation': default: throw new Error(`Unknown prop type, found: ${typeAnnotation.type}"`); @@ -86,6 +114,19 @@ function getInlineMethodImplementation( name: string, ): string { const {typeAnnotation} = property; + function markOptionalTypeIfNecessary(type) { + if (property.optional) { + return `folly::Optional<${type}> `; + } + return `${type} `; + } + function markOptionalValueIfNecessary(value) { + if (property.optional) { + return `RCTBridgingToOptional${capitalizeFirstLetter(value)}`; + } + return `RCTBridgingTo${capitalizeFirstLetter(value)}`; + } + switch (typeAnnotation.type) { case 'ReservedFunctionValueTypeAnnotation': switch (typeAnnotation.name) { @@ -105,40 +146,59 @@ function getInlineMethodImplementation( case 'FloatTypeAnnotation': case 'Int32TypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'double ') - .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToDouble(p)'); + .replace(/::_RETURN_TYPE_::/, markOptionalTypeIfNecessary('double')) + .replace( + /::_RETURN_VALUE_::/, + `${markOptionalValueIfNecessary('double')}(p)`, + ); case 'BooleanTypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'bool ') - .replace(/::_RETURN_VALUE_::/, 'RCTBridgingToBool(p)'); + .replace(/::_RETURN_TYPE_::/, markOptionalTypeIfNecessary('bool')) + .replace( + /::_RETURN_VALUE_::/, + `${markOptionalValueIfNecessary('bool')}(p)`, + ); case 'GenericObjectTypeAnnotation': case 'AnyTypeAnnotation': return inlineTemplate - .replace(/::_RETURN_TYPE_::/, 'id ') + .replace( + /::_RETURN_TYPE_::/, + property.optional ? 'id _Nullable ' : 'id ', + ) .replace(/::_RETURN_VALUE_::/, 'p'); case 'ObjectTypeAnnotation': return inlineTemplate .replace( /::_RETURN_TYPE_::/, - `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( - property.name, - )} `, + markOptionalTypeIfNecessary( + `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( + getSafePropertyName(property.name), + )}`, + ), ) .replace( /::_RETURN_VALUE_::/, - `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( - property.name, - )}(p)`, + property.optional + ? `(p == nil ? folly::none : folly::make_optional(JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( + getSafePropertyName(property.name), + )}(p)))` + : `JS::Native::_MODULE_NAME_::::Spec${name}${capitalizeFirstLetter( + getSafePropertyName(property.name), + )}(p)`, ); case 'ArrayTypeAnnotation': return inlineTemplate .replace( /::_RETURN_TYPE_::/, - 'facebook::react::LazyVector> ', + markOptionalTypeIfNecessary( + 'facebook::react::LazyVector>', + ), ) .replace( /::_RETURN_VALUE_::/, - 'RCTBridgingToVec(p, ^id(id itemValue_0) { return itemValue_0; })', + `${markOptionalValueIfNecessary( + 'vec', + )}(p, ^id(id itemValue_0) { return itemValue_0; })`, ); case 'FunctionTypeAnnotation': default: @@ -165,7 +225,10 @@ function translateObjectsForStructs( acc.concat( object.properties.map(property => getInlineMethodImplementation(property, object.name) - .replace(/::_PROPERTY_NAME_::/g, property.name) + .replace( + /::_PROPERTY_NAME_::/g, + getSafePropertyName(property.name), + ) .replace(/::_STRUCT_NAME_::/g, object.name), ), ), diff --git a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js index 25725ebaa42c26..fd534a9af516fb 100644 --- a/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/generators/modules/__test_fixtures__/fixtures.js @@ -463,6 +463,13 @@ const COMPLEX_OBJECTS: SchemaType = { type: 'StringTypeAnnotation', }, }, + { + optional: false, + name: 'id', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, ], }, }, @@ -480,6 +487,128 @@ const COMPLEX_OBJECTS: SchemaType = { optional: false, }, }, + { + name: 'optionals', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'A', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: true, + name: 'optionalNumberProperty', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: true, + name: 'optionalArrayProperty', + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'NumberTypeAnnotation', + }, + }, + }, + { + optional: true, + name: 'optionalObjectProperty', + typeAnnotation: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'x', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + { + optional: false, + name: 'y', + typeAnnotation: { + type: 'NumberTypeAnnotation', + }, + }, + ], + }, + }, + { + optional: true, + name: 'optionalGenericObjectProperty', + typeAnnotation: { + type: 'GenericObjectTypeAnnotation', + }, + }, + { + optional: true, + name: 'optionalBooleanTypeProperty', + typeAnnotation: { + type: 'BooleanTypeAnnotation', + }, + }, + ], + }, + }, + ], + optional: false, + }, + }, + { + name: 'optionalMethod', + typeAnnotation: { + type: 'FunctionTypeAnnotation', + returnTypeAnnotation: { + nullable: false, + type: 'VoidTypeAnnotation', + }, + params: [ + { + nullable: false, + name: 'options', + typeAnnotation: { + type: 'GenericObjectTypeAnnotation', + }, + }, + { + name: 'callback', + nullable: false, + typeAnnotation: { + type: 'FunctionTypeAnnotation', + }, + }, + { + name: 'extras', + nullable: true, + typeAnnotation: { + type: 'ArrayTypeAnnotation', + elementType: { + type: 'ObjectTypeAnnotation', + properties: [ + { + optional: false, + name: 'key', + typeAnnotation: { + type: 'StringTypeAnnotation', + }, + }, + ], + }, + }, + }, + ], + optional: true, + }, + }, ], }, }, diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap index f79507df8b3d3a..e3b257ba994b24 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleCpp-test.js.snap @@ -19,9 +19,21 @@ static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_difficult(jsi return static_cast(&turboModule)->difficult(rt, args[0].getObject(rt)); } +static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionals(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->optionals(rt, args[0].getObject(rt)); + return jsi::Value::undefined(); +} + +static jsi::Value __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionalMethod(jsi::Runtime &rt, TurboModule &turboModule, const jsi::Value* args, size_t count) { + static_cast(&turboModule)->optionalMethod(rt, args[0].getObject(rt), std::move(args[1].getObject(rt).getFunction(rt)), args[2].getObject(rt).getArray(rt)); + return jsi::Value::undefined(); +} + NativeSampleTurboModuleCxxSpecJSI::NativeSampleTurboModuleCxxSpecJSI(std::shared_ptr jsInvoker) : TurboModule(\\"SampleTurboModule\\", jsInvoker) { methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_difficult}; + methodMap_[\\"optionals\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionals}; + methodMap_[\\"optionalMethod\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleCxxSpecJSI_optionalMethod}; } diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap index 2fcc8834fa2372..308af3d47cdc32 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleH-test.js.snap @@ -23,6 +23,8 @@ protected: public: virtual jsi::Object difficult(jsi::Runtime &rt, const jsi::Object &A) = 0; +virtual void optionals(jsi::Runtime &rt, const jsi::Object &A) = 0; +virtual void optionalMethod(jsi::Runtime &rt, const jsi::Object &options, const jsi::Function &callback, const jsi::Array &extras) = 0; }; diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap index 948c86afc4f0e8..6005fc72f622f0 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleHObjCpp-test.js.snap @@ -8,32 +8,57 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js */ -// NOTE: This entire file should be codegen'ed. +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif #import #import -#import +#import -#import #import +#import #import + +#import #import #import -#import +#import +namespace JS { + namespace NativeSampleTurboModule { + struct SpecOptionalsAOptionalObjectProperty { + double x() const; + double y() const; + + SpecOptionalsAOptionalObjectProperty(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json; +@end + + namespace JS { namespace NativeSampleTurboModule { struct SpecDifficultAE { bool D() const; double E() const; NSString *F() const; + double id_() const; SpecDifficultAE(NSDictionary *const v) : _v(v) {} private: @@ -47,6 +72,27 @@ namespace JS { @end +namespace JS { + namespace NativeSampleTurboModule { + struct SpecOptionalsA { + folly::Optional optionalNumberProperty() const; + folly::Optional>> optionalArrayProperty() const; + folly::Optional optionalObjectProperty() const; + id _Nullable optionalGenericObjectProperty() const; + folly::Optional optionalBooleanTypeProperty() const; + + SpecOptionalsA(NSDictionary *const v) : _v(v) {} + private: + NSDictionary *_v; + }; + } +} + +@interface RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(id)json; +@end + + namespace JS { namespace NativeSampleTurboModule { struct SpecDifficultReturnType { @@ -126,6 +172,41 @@ inline NSString *JS::NativeSampleTurboModule::SpecDifficultReturnType::F() const } +inline folly::Optional JS::NativeSampleTurboModule::SpecOptionalsA::optionalNumberProperty() const +{ + id const p = _v[@\\"optionalNumberProperty\\"]; + return RCTBridgingToOptionalDouble(p); +} + + +inline folly::Optional>> JS::NativeSampleTurboModule::SpecOptionalsA::optionalArrayProperty() const +{ + id const p = _v[@\\"optionalArrayProperty\\"]; + return RCTBridgingToOptionalVec(p, ^id(id itemValue_0) { return itemValue_0; }); +} + + +inline folly::Optional JS::NativeSampleTurboModule::SpecOptionalsA::optionalObjectProperty() const +{ + id const p = _v[@\\"optionalObjectProperty\\"]; + return (p == nil ? folly::none : folly::make_optional(JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty(p))); +} + + +inline id _Nullable JS::NativeSampleTurboModule::SpecOptionalsA::optionalGenericObjectProperty() const +{ + id const p = _v[@\\"optionalGenericObjectProperty\\"]; + return p; +} + + +inline folly::Optional JS::NativeSampleTurboModule::SpecOptionalsA::optionalBooleanTypeProperty() const +{ + id const p = _v[@\\"optionalBooleanTypeProperty\\"]; + return RCTBridgingToOptionalBool(p); +} + + inline bool JS::NativeSampleTurboModule::SpecDifficultAE::D() const { id const p = _v[@\\"D\\"]; @@ -147,21 +228,47 @@ inline NSString *JS::NativeSampleTurboModule::SpecDifficultAE::F() const } +inline double JS::NativeSampleTurboModule::SpecDifficultAE::id_() const +{ + id const p = _v[@\\"id_\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::x() const +{ + id const p = _v[@\\"x\\"]; + return RCTBridgingToDouble(p); +} + + +inline double JS::NativeSampleTurboModule::SpecOptionalsAOptionalObjectProperty::y() const +{ + id const p = _v[@\\"y\\"]; + return RCTBridgingToDouble(p); +} + + @protocol NativeSampleTurboModuleSpec - (NSDictionary *) difficult:(JS::NativeSampleTurboModule::SpecDifficultA&)A; +- (void) optionals:(JS::NativeSampleTurboModule::SpecOptionalsA&)A; +- (void) optionalMethod:(NSDictionary *)options + callback:(RCTResponseSenderBlock)callback + extras:(NSArray * _Nullable)extras; @end namespace facebook { -namespace react { - -class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -} // namespace react + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react } // namespace facebook ", } @@ -175,23 +282,29 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js */ -// NOTE: This entire file should be codegen'ed. +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif #import #import -#import +#import -#import #import +#import #import + +#import #import #import -#import +#import @@ -203,14 +316,15 @@ Map { namespace facebook { -namespace react { - -class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -} // namespace react + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react } // namespace facebook ", } @@ -224,23 +338,29 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js */ -// NOTE: This entire file should be codegen'ed. +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif #import #import -#import +#import -#import #import +#import #import + +#import #import #import -#import +#import @@ -310,14 +430,15 @@ inline JS::NativeSampleTurboModule::Constants::Builder::Builder(Constants i) : _ namespace facebook { -namespace react { - -class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -} // namespace react + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react } // namespace facebook ", } @@ -331,29 +452,36 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js */ -// NOTE: This entire file should be codegen'ed. +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif #import #import -#import +#import -#import #import +#import #import + +#import #import #import -#import +#import -@protocol NativeSampleTurboModuleSpec +@protocol NativeSample2TurboModuleSpec + - (void) voidFunc; @end @@ -361,27 +489,28 @@ Map { - -@protocol NativeSample2TurboModuleSpec - +@protocol NativeSampleTurboModuleSpec - (void) voidFunc; @end namespace facebook { -namespace react { - -class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -} // namespace react + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + /** + * ObjC++ class for module 'Sample2TurboModule' + */ + class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react } // namespace facebook ", } @@ -395,29 +524,35 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleHObjCpp.js */ -// NOTE: This entire file should be codegen'ed. +#ifndef __cplusplus +#error This file must be compiled as Obj-C++. If you are importing it, you must change your file extension to .mm. +#endif #import #import -#import +#import -#import #import +#import #import + +#import #import #import -#import +#import -@protocol NativeSampleTurboModuleSpec +@protocol NativeSample2TurboModuleSpec - (void) voidFunc; @end @@ -425,26 +560,28 @@ Map { - -@protocol NativeSample2TurboModuleSpec +@protocol NativeSampleTurboModuleSpec - (void) voidFunc; @end namespace facebook { -namespace react { - -class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { -public: - NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); -}; - -} // namespace react + namespace react { + /** + * ObjC++ class for module 'SampleTurboModule' + */ + class JSI_EXPORT NativeSampleTurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + /** + * ObjC++ class for module 'Sample2TurboModule' + */ + class JSI_EXPORT NativeSample2TurboModuleSpecJSI : public ObjCTurboModule { + public: + NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms); + }; + } // namespace react } // namespace facebook ", } diff --git a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap index 7b9ffc955e1b8d..86abf78460cec5 100644 --- a/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap +++ b/packages/react-native-codegen/src/generators/modules/__tests__/__snapshots__/GenerateModuleMm-test.js.snap @@ -8,43 +8,80 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js */ #include +#import + + @implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultReturnType) + (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultReturnType:(id)json { return facebook::react::managedPointer(json); } @end + + @implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultA) + (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultA:(id)json { return facebook::react::managedPointer(json); } @end + + +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsA) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsA:(id)json +{ + return facebook::react::managedPointer(json); +} +@end + + @implementation RCTCxxConvert (NativeSampleTurboModule_SpecDifficultAE) + (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecDifficultAE:(id)json { return facebook::react::managedPointer(json); } @end -namespace facebook { -namespace react { -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"difficult\\", @selector(difficult:), args, count); -} -NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; - setMethodArgConversionSelector(@\\"difficult\\", 0, @\\"JS_NativeSampleTurboModule_SpecDifficultA:\\"); +@implementation RCTCxxConvert (NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty) ++ (RCTManagedPointer *)JS_NativeSampleTurboModule_SpecOptionalsAOptionalObjectProperty:(id)json +{ + return facebook::react::managedPointer(json); } +@end +namespace facebook { + namespace react { -} // namespace react + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_difficult(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, ObjectKind, \\"difficult\\", @selector(difficult:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionals(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"optionals\\", @selector(optionals:), args, count); + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"optionalMethod\\", @selector(optionalMethod:callback:extras:), args, count); + } + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"difficult\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_difficult}; + methodMap_[\\"optionals\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_optionals}; + methodMap_[\\"optionalMethod\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_optionalMethod}; + setMethodArgConversionSelector(@\\"difficult\\", 0, @\\"JS_NativeSampleTurboModule_SpecDifficultA:\\"); + setMethodArgConversionSelector(@\\"optionals\\", 0, @\\"JS_NativeSampleTurboModule_SpecOptionalsA:\\"); + } + } // namespace react } // namespace facebook ", } @@ -58,22 +95,23 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js */ #include +#import -namespace facebook { -namespace react { - - - -NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { -} +namespace facebook { + namespace react { -} // namespace react + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + } + } // namespace react } // namespace facebook ", } @@ -87,75 +125,87 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js */ #include +#import + namespace facebook { -namespace react { + namespace react { -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, ObjectKind, \\"getConstants\\", @selector(getConstants), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getBool(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, BooleanKind, \\"getBool\\", @selector(getBool:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, NumberKind, \\"getNumber\\", @selector(getNumber:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getString(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, StringKind, \\"getString\\", @selector(getString:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getArray(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, ArrayKind, \\"getArray\\", @selector(getArray:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getObject(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, ObjectKind, \\"getObject\\", @selector(getObject:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + } + + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, NumberKind, \\"getRootTag\\", @selector(getRootTag:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); -} -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); -} + } -NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; - methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; - methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; - methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; - methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; - methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; - methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; - methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; - methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; - methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; -} + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValue(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, ObjectKind, \\"getValue\\", @selector(getValue:y:z:), args, count); + } + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"getValueWithCallback\\", @selector(getValueWithCallback:), args, count); + } -} // namespace react + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, PromiseKind, \\"getValueWithPromise\\", @selector(getValueWithPromise:resolve:reject:), args, count); + } + + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"getConstants\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_getConstants}; + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + methodMap_[\\"getBool\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getBool}; + methodMap_[\\"getNumber\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getNumber}; + methodMap_[\\"getString\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getString}; + methodMap_[\\"getArray\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getArray}; + methodMap_[\\"getObject\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getObject}; + methodMap_[\\"getRootTag\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getRootTag}; + methodMap_[\\"getValue\\"] = MethodMetadata {3, __hostFunction_NativeSampleTurboModuleSpecJSI_getValue}; + methodMap_[\\"getValueWithCallback\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithCallback}; + methodMap_[\\"getValueWithPromise\\"] = MethodMetadata {1, __hostFunction_NativeSampleTurboModuleSpecJSI_getValueWithPromise}; + } + } // namespace react } // namespace facebook ", } @@ -169,37 +219,40 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js */ #include +#import -namespace facebook { -namespace react { - -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); -} -NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; -} +namespace facebook { + namespace react { -static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); -} - -NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { + } - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; -} + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + } -} // namespace react + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } + + NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + } + } // namespace react } // namespace facebook ", } @@ -213,35 +266,38 @@ Map { * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. + * + * @generated by codegen project: GenerateModuleMm.js */ #include +#import + namespace facebook { -namespace react { + namespace react { -static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) + static facebook::jsi::Value __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); -} + } -NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; -} -static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { - return static_cast(turboModule) - .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); -} - -NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) - : ObjCTurboModule(params) { - methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; -} + NativeSampleTurboModuleSpecJSI::NativeSampleTurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSampleTurboModuleSpecJSI_voidFunc}; + } + static facebook::jsi::Value __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc(facebook::jsi::Runtime& rt, TurboModule &turboModule, const facebook::jsi::Value* args, size_t count) { + return static_cast(turboModule) + .invokeObjCMethod(rt, VoidKind, \\"voidFunc\\", @selector(voidFunc), args, count); + } -} // namespace react + NativeSample2TurboModuleSpecJSI::NativeSample2TurboModuleSpecJSI(const ObjCTurboModule::InitParams ¶ms) + : ObjCTurboModule(params) { + methodMap_[\\"voidFunc\\"] = MethodMetadata {0, __hostFunction_NativeSample2TurboModuleSpecJSI_voidFunc}; + } + } // namespace react } // namespace facebook ", } diff --git a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js index 13e5131953358b..851257da1d052f 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js +++ b/packages/react-native-codegen/src/parsers/flow/components/__test_fixtures__/fixtures.js @@ -144,6 +144,7 @@ type ModuleProps = $ReadOnly<{| export default codegenNativeComponent('Module', { interfaceOnly: true, + excludedPlatforms: ['android'], paperComponentName: 'RCTModule', }); `; diff --git a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap index 8192bb77cdf40a..6437404dd14201 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap +++ b/packages/react-native-codegen/src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap @@ -5935,6 +5935,9 @@ Object { }, }, ], + "excludedPlatforms": Array [ + "android", + ], "extendsProps": Array [ Object { "knownTypeName": "ReactNativeCoreViewProps", diff --git a/packages/react-native-codegen/src/parsers/flow/components/options.js b/packages/react-native-codegen/src/parsers/flow/components/options.js index f455a5f060a3f2..8044575db15913 100644 --- a/packages/react-native-codegen/src/parsers/flow/components/options.js +++ b/packages/react-native-codegen/src/parsers/flow/components/options.js @@ -54,7 +54,13 @@ function getOptions(optionsExpression: OptionsAST): ?OptionsShape { let foundOptions; try { foundOptions = optionsExpression.properties.reduce((options, prop) => { - options[prop.key.name] = prop.value.value; + if (prop.value.type === 'ArrayExpression') { + options[prop.key.name] = prop.value.elements.map( + element => element.value, + ); + } else { + options[prop.key.name] = prop.value.value; + } return options; }, {}); } catch (e) { diff --git a/scripts/generate-native-modules-specs.sh b/scripts/generate-native-modules-specs.sh new file mode 100755 index 00000000000000..505a7769a338b0 --- /dev/null +++ b/scripts/generate-native-modules-specs.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# Copyright (c) Facebook, Inc. and its affiliates. +# +# This source code is licensed under the MIT license found in the +# LICENSE file in the root directory of this source tree. + +# This script collects the JavaScript spec definitions for native +# modules, then uses react-native-codegen to generate native code. +# The script will copy the generated code to the final location by +# default. Optionally, call the script with a path to the desired +# output location. +# +# Usage: +# ./scripts/generate-native-modules-specs.sh [output-dir] +# +# Example: +# ./scripts/generate-native-modules-specs.sh ./codegen-out + +# shellcheck disable=SC2038 + +set -e + +describe () { + printf "\\n\\n>>>>> %s\\n\\n\\n" "$1" +} + +THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd) +RN_DIR=$(cd "$THIS_DIR/.." && pwd) + +TEMP_DIR=$(mktemp -d /tmp/react-native-codegen-XXXXXXXX) + +SRCS_DIR=$(cd "$RN_DIR/Libraries" && pwd) +LIBRARY_NAME="FBReactNativeSpec" +MODULE_SPEC_NAME="FBReactNativeSpec" + +SCHEMA_FILE="$RN_DIR/schema-native-modules.json" +OUTPUT_DIR="$SRCS_DIR/$LIBRARY_NAME/$MODULE_SPEC_NAME" + +describe "Generating schema from flow types" +grep --exclude NativeUIManager.js --include=Native\*.js -rnwl "$SRCS_DIR" -e 'export interface Spec extends TurboModule' -e "export default \(TurboModuleRegistry.get(Enforcing)?\('.*\): Spec\);/" \ + | xargs yarn flow-node packages/react-native-codegen/src/cli/combine/combine-js-to-schema-cli.js "$SCHEMA_FILE" + +describe "Generating native code from schema" +yarn flow-node packages/react-native-codegen/buck_tests/generate-tests.js "$SCHEMA_FILE" "$LIBRARY_NAME" "$TEMP_DIR" "$MODULE_SPEC_NAME" + +if [ -n "$1" ]; then + OUTPUT_DIR="$1" + mkdir -p "$OUTPUT_DIR" +fi + +describe "Copying $MODULE_SPEC_NAME output to $OUTPUT_DIR" +cp "$TEMP_DIR"/$MODULE_SPEC_NAME* "$OUTPUT_DIR/." diff --git a/scripts/react-native-xcode.sh b/scripts/react-native-xcode.sh index 88aa2a5af45021..a87c68fec607fe 100755 --- a/scripts/react-native-xcode.sh +++ b/scripts/react-native-xcode.sh @@ -14,10 +14,12 @@ DEST=$CONFIGURATION_BUILD_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH # Enables iOS devices to get the IP address of the machine running Metro if [[ "$CONFIGURATION" = *Debug* && ! "$PLATFORM_NAME" == *simulator ]]; then - IP=$(ipconfig getifaddr en0) - if [[ -z "$IP" || -n "`ifconfig $value | grep 'baseT'`" ]]; then - IP=$(ipconfig getifaddr en1) - fi + for num in 0 1 2 3 4 5 6 7 8; do + IP=$(ipconfig getifaddr en${num}) + if [ ! -z "$IP" ]; then + break + fi + done if [ -z "$IP" ]; then IP=$(ifconfig | grep 'inet ' | grep -v ' 127.' | grep -v ' 169.254.' |cut -d\ -f2 | awk 'NR==1{print $1}') fi diff --git a/scripts/react_native_pods.rb b/scripts/react_native_pods.rb index 606d8f5dca7fb6..2cdade9df62ac7 100644 --- a/scripts/react_native_pods.rb +++ b/scripts/react_native_pods.rb @@ -45,6 +45,7 @@ def use_react_native! (options={}) pod 'React-jsiexecutor', :path => "#{prefix}/ReactCommon/jsiexecutor" pod 'React-jsinspector', :path => "#{prefix}/ReactCommon/jsinspector" pod 'React-callinvoker', :path => "#{prefix}/ReactCommon/callinvoker" + pod 'React-runtimeexecutor', :path => "#{prefix}/ReactCommon/runtimeexecutor" pod 'ReactCommon/turbomodule/core', :path => "#{prefix}/ReactCommon" pod 'Yoga', :path => "#{prefix}/ReactCommon/yoga", :modular_headers => true @@ -109,31 +110,4 @@ def flipper_post_install(installer) end end end - file_name = Dir.glob("*.xcodeproj")[0] - app_project = Xcodeproj::Project.open(file_name) - app_project.native_targets.each do |target| - target.build_configurations.each do |config| - cflags = config.build_settings['OTHER_CFLAGS'] || '$(inherited) ' - unless cflags.include? '-DFB_SONARKIT_ENABLED=1' - puts 'Adding -DFB_SONARKIT_ENABLED=1 in OTHER_CFLAGS...' - cflags << '-DFB_SONARKIT_ENABLED=1' - end - config.build_settings['OTHER_CFLAGS'] = cflags - if (config.build_settings['OTHER_SWIFT_FLAGS']) - unless config.build_settings['OTHER_SWIFT_FLAGS'].include? '-DFB_SONARKIT_ENABLED' - puts 'Adding -DFB_SONARKIT_ENABLED ...' - swift_flags = config.build_settings['OTHER_SWIFT_FLAGS'] - if swift_flags.split.last != '-Xcc' - config.build_settings['OTHER_SWIFT_FLAGS'] << ' -Xcc' - end - config.build_settings['OTHER_SWIFT_FLAGS'] << ' -DFB_SONARKIT_ENABLED' - end - else - puts 'OTHER_SWIFT_FLAGS does not exist thus assigning it to `$(inherited) -Xcc -DFB_SONARKIT_ENABLED`' - config.build_settings['OTHER_SWIFT_FLAGS'] = '$(inherited) -Xcc -DFB_SONARKIT_ENABLED' - end - app_project.save - end - end - installer.pods_project.save end diff --git a/scripts/run-ci-e2e-tests.js b/scripts/run-ci-e2e-tests.js index 8fb55c0834d064..ee16a0a4a5961f 100644 --- a/scripts/run-ci-e2e-tests.js +++ b/scripts/run-ci-e2e-tests.js @@ -13,7 +13,6 @@ * This script tests that React Native end to end installation/bootstrap works for different platforms * Available arguments: * --ios - 'react-native init' and check iOS app doesn't redbox - * --tvos - 'react-native init' and check tvOS app doesn't redbox * --android - 'react-native init' and check Android app doesn't redbox * --js - 'react-native init' and only check the packager returns a bundle * --skip-cli-install - to skip react-native-cli global installation (for local debugging) @@ -196,8 +195,7 @@ try { } } - if (argv.ios || argv.tvos) { - var iosTestType = argv.tvos ? 'tvOS' : 'iOS'; + if (argv.ios) { cd('ios'); // shelljs exec('', {async: true}) does not emit stdout events, so we rely on good old spawn const packagerEnv = Object.create(process.env); @@ -209,7 +207,7 @@ try { }); SERVER_PID = packagerProcess.pid; exec('sleep 15s'); - // prepare cache to reduce chances of possible red screen "Can't fibd variable __fbBatchedBridge..." + // prepare cache to reduce chances of possible red screen "Can't find variable __fbBatchedBridge..." exec( 'response=$(curl --write-out %{http_code} --silent --output /dev/null localhost:8081/index.bundle?platform=ios&dev=true)', ); @@ -218,32 +216,22 @@ try { describe('Install CocoaPod dependencies'); exec('pod install'); - describe('Test: ' + iosTestType + ' end-to-end test'); + describe('Test: iOS end-to-end test'); if ( // TODO: Get target OS and simulator from .tests.env tryExecNTimes( () => { - let destination = 'platform=iOS Simulator,name=iPhone 8,OS=13.3'; - let sdk = 'iphonesimulator'; - let scheme = 'HelloWorld'; - - if (argv.tvos) { - destination = 'platform=tvOS Simulator,name=Apple TV,OS=13.3'; - sdk = 'appletvsimulator'; - scheme = 'HelloWorld-tvOS'; - } - return exec( [ 'xcodebuild', '-workspace', '"HelloWorld.xcworkspace"', '-destination', - `"${destination}"`, + '"platform=iOS Simulator,name=iPhone 8,OS=13.3"', '-scheme', - `"${scheme}"`, + '"HelloWorld"', '-sdk', - sdk, + 'iphonesimulator', '-UseModernBuildSystem=NO', 'test', ].join(' ') + @@ -253,7 +241,7 @@ try { '--report', 'junit', '--output', - `"~/react-native/reports/junit/${iosTestType}-e2e/results.xml"`, + '"~/react-native/reports/junit/iOS-e2e/results.xml"', ].join(' ') + ' && exit ${PIPESTATUS[0]}', ).code; @@ -262,7 +250,7 @@ try { () => exec('sleep 10s'), ) ) { - echo('Failed to run ' + iosTestType + ' end-to-end tests'); + echo('Failed to run iOS end-to-end tests'); echo('Most likely the code is broken'); exitCode = 1; throw Error(exitCode); diff --git a/template/_flowconfig b/template/_flowconfig index b9e2438817bbf9..0296b285f8cf61 100644 --- a/template/_flowconfig +++ b/template/_flowconfig @@ -73,4 +73,4 @@ untyped-import untyped-type-import [version] -^0.123.0 +^0.124.0 diff --git a/template/android/app/src/debug/AndroidManifest.xml b/template/android/app/src/debug/AndroidManifest.xml index fa26aa56e1c144..b2f3ad9fce9234 100644 --- a/template/android/app/src/debug/AndroidManifest.xml +++ b/template/android/app/src/debug/AndroidManifest.xml @@ -4,5 +4,10 @@ - + + + diff --git a/template/android/app/src/main/AndroidManifest.xml b/template/android/app/src/main/AndroidManifest.xml index 0a7a9cfc66ce3f..6db8bad363a138 100644 --- a/template/android/app/src/main/AndroidManifest.xml +++ b/template/android/app/src/main/AndroidManifest.xml @@ -21,7 +21,5 @@ - - diff --git a/yarn.lock b/yarn.lock index 3defe0840ee560..1489a15c9d62ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,15 +9,6 @@ dependencies: "@babel/highlight" "^7.8.3" -"@babel/compat-data@^7.8.6", "@babel/compat-data@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.9.0.tgz#04815556fc90b0c174abd2c0c1bb966faa036a6c" - integrity sha512-zeFQrr+284Ekvd9e7KAX954LkapWiOmQtsfHirhxqfdlX6MEC32iRE+pqUGlYIBchdevaCwvzxWGSy/YBNI85g== - dependencies: - browserslist "^4.9.1" - invariant "^2.2.4" - semver "^5.5.0" - "@babel/core@^7.0.0", "@babel/core@^7.1.0", "@babel/core@^7.1.6", "@babel/core@^7.4.5", "@babel/core@^7.7.5": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.9.0.tgz#ac977b538b77e132ff706f3b8a4dbad09c03c56e" @@ -92,17 +83,6 @@ "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/types" "^7.9.0" -"@babel/helper-compilation-targets@^7.8.7": - version "7.8.7" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.8.7.tgz#dac1eea159c0e4bd46e309b5a1b04a66b53c1dde" - integrity sha512-4mWm8DCK2LugIS+p1yArqvG1Pf162upsIsjE7cNBjez+NjliQpVhj20obE520nao0o14DaTnFJv+Fw5a0JpoUw== - dependencies: - "@babel/compat-data" "^7.8.6" - browserslist "^4.9.1" - invariant "^2.2.4" - levenary "^1.1.1" - semver "^5.5.0" - "@babel/helper-create-class-features-plugin@^7.8.3": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.8.6.tgz#243a5b46e2f8f0f674dc1387631eb6b28b851de0" @@ -115,7 +95,7 @@ "@babel/helper-replace-supers" "^7.8.6" "@babel/helper-split-export-declaration" "^7.8.3" -"@babel/helper-create-regexp-features-plugin@^7.8.3", "@babel/helper-create-regexp-features-plugin@^7.8.8": +"@babel/helper-create-regexp-features-plugin@^7.8.3": version "7.8.8" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.8.8.tgz#5d84180b588f560b7864efaeea89243e58312087" integrity sha512-LYVPdwkrQEiX9+1R29Ld/wTrmQu1SSKYnuOk3g0CkcZMA1p0gsNxJFj/3gBdaJ7Cg0Fnek5z0DsMULePP7Lrqg== @@ -166,13 +146,6 @@ dependencies: "@babel/types" "^7.8.3" -"@babel/helper-hoist-variables@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.8.3.tgz#1dbe9b6b55d78c9b4183fc8cdc6e30ceb83b7134" - integrity sha512-ky1JLOjcDUtSc+xkt0xhYff7Z6ILTAHKmZLHPxAhOP0Nd77O+3nCsd6uSVYur6nJnCI029CrNbYlc0LoPfAPQg== - dependencies: - "@babel/types" "^7.8.3" - "@babel/helper-member-expression-to-functions@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz#659b710498ea6c1d9907e0c73f206eee7dadc24c" @@ -310,15 +283,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-proposal-async-generator-functions@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.8.3.tgz#bad329c670b382589721b27540c7d288601c6e6f" - integrity sha512-NZ9zLv848JsV3hs8ryEh7Uaz/0KsmPLqv0+PdkDJL1cJy0K4kOCFa8zc1E3mp+RHPQcpdfb/6GovEsW4VDrOMw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/helper-remap-async-to-generator" "^7.8.3" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-proposal-class-properties@^7.0.0", "@babel/plugin-proposal-class-properties@^7.1.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.8.3.tgz#5e06654af5cd04b608915aada9b2a6788004464e" @@ -327,14 +291,6 @@ "@babel/helper-create-class-features-plugin" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-proposal-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.8.3.tgz#38c4fe555744826e97e2ae930b0fb4cc07e66054" - integrity sha512-NyaBbyLFXFLT9FP+zk0kYlUlA8XtCUbehs67F0nnEg7KICgMc2mNkIeu9TYhKzyXMkrapZFwAhXLdnt4IYHy1w== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-proposal-export-default-from@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.8.3.tgz#4cb7c2fdeaed490b60d9bfd3dc8a20f81f9c2e7c" @@ -343,15 +299,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-export-default-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.8.3.tgz#da5216b238a98b58a1e05d6852104b10f9a70d6b" - integrity sha512-KGhQNZ3TVCQG/MjRbAUwuH+14y9q0tpxs1nWWs3pbSleRdDro9SAMMDyye8HhY1gqZ7/NqIc8SKhya0wRDgP1Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.0" - -"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": +"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0", "@babel/plugin-proposal-nullish-coalescing-operator@^7.1.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.8.3.tgz#e4572253fdeed65cddeecfdab3f928afeb2fd5d2" integrity sha512-TS9MlfzXpXKt6YYomudb/KU7nQI6/xnapG6in1uZxoxDghuSMZsPb6D2fyUwNYSAp4l1iR7QtFOjkqcRYcUsfw== @@ -359,15 +307,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-numeric-separator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.8.3.tgz#5d6769409699ec9b3b68684cd8116cedff93bad8" - integrity sha512-jWioO1s6R/R+wEHizfaScNsAx+xKgwTLNXSh7tTC4Usj3ItsPEhYkEpU4h+lpnBwq7NBVOJXfO6cRFYcX69JUQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - -"@babel/plugin-proposal-object-rest-spread@^7.0.0", "@babel/plugin-proposal-object-rest-spread@^7.9.0": +"@babel/plugin-proposal-object-rest-spread@^7.0.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.9.0.tgz#a28993699fc13df165995362693962ba6b061d6f" integrity sha512-UgqBv6bjq4fDb8uku9f+wcm1J7YxJ5nT7WO/jBr0cl0PLKb7t1O6RNR1kZbjgx2LQtsDI9hwoQVmn0yhXeQyow== @@ -375,7 +315,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" -"@babel/plugin-proposal-optional-catch-binding@^7.0.0", "@babel/plugin-proposal-optional-catch-binding@^7.8.3": +"@babel/plugin-proposal-optional-catch-binding@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.8.3.tgz#9dee96ab1650eed88646ae9734ca167ac4a9c5c9" integrity sha512-0gkX7J7E+AtAw9fcwlVQj8peP61qhdg/89D5swOkjYbkboA2CVckn3kiyum1DE0wskGb7KJJxBdyEBApDLLVdw== @@ -383,7 +323,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.9.0": +"@babel/plugin-proposal-optional-chaining@^7.0.0", "@babel/plugin-proposal-optional-chaining@^7.1.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.9.0.tgz#31db16b154c39d6b8a645292472b98394c292a58" integrity sha512-NDn5tu3tcv4W30jNhmc2hyD5c56G6cXx4TesJubhxrJeCvuuMpttxr0OnNCqbZGhFjLrg+NIhxxC+BK5F6yS3w== @@ -391,15 +331,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-unicode-property-regex@^7.4.4", "@babel/plugin-proposal-unicode-property-regex@^7.8.3": - version "7.8.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.8.8.tgz#ee3a95e90cdc04fe8cd92ec3279fa017d68a0d1d" - integrity sha512-EVhjVsMpbhLw9ZfHWSx2iy13Q8Z/eg8e8ccVWt23sWQK5l1UdkoLJPN5w69UA4uITGBnEZD2JOe4QOHycYKv8A== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.8" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-syntax-async-generators@^7.8.0", "@babel/plugin-syntax-async-generators@^7.8.4": +"@babel/plugin-syntax-async-generators@^7.8.4": version "7.8.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== @@ -420,7 +352,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.8.0": +"@babel/plugin-syntax-dynamic-import@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== @@ -441,7 +373,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-json-strings@^7.8.0", "@babel/plugin-syntax-json-strings@^7.8.3": +"@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== @@ -469,7 +401,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.8.0", "@babel/plugin-syntax-numeric-separator@^7.8.3": +"@babel/plugin-syntax-numeric-separator@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.8.3.tgz#0e3fb63e09bea1b11e96467271c8308007e7c41f" integrity sha512-H7dCMAdN83PcCmqmkHB5dtp+Xa9a6LKSvA2hiFBC/5alSHxM5VgWZXFqDi0YFe8XNGT6iCa+z4V4zSt/PdZ7Dw== @@ -497,13 +429,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.8.3.tgz#3acdece695e6b13aaf57fc291d1a800950c71391" - integrity sha512-kwj1j9lL/6Wd0hROD3b/OZZ7MSrZLqqn9RAZ5+cYYsflQ9HZBIKCUkr3+uL1MEJ1NePiUbf98jjiMQSv0NMR9g== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-typescript@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.8.3.tgz#c1f659dda97711a569cef75275f7e15dcaa6cabc" @@ -511,14 +436,14 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-arrow-functions@^7.0.0", "@babel/plugin-transform-arrow-functions@^7.8.3": +"@babel/plugin-transform-arrow-functions@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.8.3.tgz#82776c2ed0cd9e1a49956daeb896024c9473b8b6" integrity sha512-0MRF+KC8EqH4dbuITCWwPSzsyO3HIWWlm30v8BbbpOrS1B++isGxPnnuq/IZvOX5J2D/p7DQalQm+/2PnlKGxg== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-async-to-generator@^7.0.0", "@babel/plugin-transform-async-to-generator@^7.8.3": +"@babel/plugin-transform-async-to-generator@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.8.3.tgz#4308fad0d9409d71eafb9b1a6ee35f9d64b64086" integrity sha512-imt9tFLD9ogt56Dd5CI/6XgpukMwd/fLGSrix2httihVe7LOGVPhyhMh1BU5kDM7iHD08i8uUtmV2sWaBFlHVQ== @@ -527,14 +452,14 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-remap-async-to-generator" "^7.8.3" -"@babel/plugin-transform-block-scoped-functions@^7.0.0", "@babel/plugin-transform-block-scoped-functions@^7.8.3": +"@babel/plugin-transform-block-scoped-functions@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.8.3.tgz#437eec5b799b5852072084b3ae5ef66e8349e8a3" integrity sha512-vo4F2OewqjbB1+yaJ7k2EJFHlTP3jR634Z9Cj9itpqNjuLXvhlVxgnjsHsdRgASR8xYDrx6onw4vW5H6We0Jmg== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-block-scoping@^7.0.0", "@babel/plugin-transform-block-scoping@^7.8.3": +"@babel/plugin-transform-block-scoping@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.8.3.tgz#97d35dab66857a437c166358b91d09050c868f3a" integrity sha512-pGnYfm7RNRgYRi7bids5bHluENHqJhrV4bCZRwc5GamaWIIs07N4rZECcmJL6ZClwjDz1GbdMZFtPs27hTB06w== @@ -542,7 +467,7 @@ "@babel/helper-plugin-utils" "^7.8.3" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.0.0", "@babel/plugin-transform-classes@^7.9.0": +"@babel/plugin-transform-classes@^7.0.0": version "7.9.2" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.9.2.tgz#8603fc3cc449e31fdbdbc257f67717536a11af8d" integrity sha512-TC2p3bPzsfvSsqBZo0kJnuelnoK9O3welkUpqSqBQuBF6R5MN2rysopri8kNvtlGIb2jmUO7i15IooAZJjZuMQ== @@ -556,36 +481,21 @@ "@babel/helper-split-export-declaration" "^7.8.3" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.0.0", "@babel/plugin-transform-computed-properties@^7.8.3": +"@babel/plugin-transform-computed-properties@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.8.3.tgz#96d0d28b7f7ce4eb5b120bb2e0e943343c86f81b" integrity sha512-O5hiIpSyOGdrQZRQ2ccwtTVkgUDBBiCuK//4RJ6UfePllUTCENOzKxfh6ulckXKc0DixTFLCfb2HVkNA7aDpzA== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-destructuring@^7.0.0", "@babel/plugin-transform-destructuring@^7.8.3": +"@babel/plugin-transform-destructuring@^7.0.0": version "7.8.8" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.8.8.tgz#fadb2bc8e90ccaf5658de6f8d4d22ff6272a2f4b" integrity sha512-eRJu4Vs2rmttFCdhPUM3bV0Yo/xPSdPw6ML9KHs/bjB4bLA5HXlbvYXPOD5yASodGod+krjYx21xm1QmL8dCJQ== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-dotall-regex@^7.4.4", "@babel/plugin-transform-dotall-regex@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.8.3.tgz#c3c6ec5ee6125c6993c5cbca20dc8621a9ea7a6e" - integrity sha512-kLs1j9Nn4MQoBYdRXH6AeaXMbEJFaFu/v1nQkvib6QzTj8MZI5OQzqmD83/2jEM1z0DLilra5aWO5YpyC0ALIw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-duplicate-keys@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.8.3.tgz#8d12df309aa537f272899c565ea1768e286e21f1" - integrity sha512-s8dHiBUbcbSgipS4SMFuWGqCvyge5V2ZeAWzR6INTVC3Ltjig/Vw1G2Gztv0vU/hRG9X8IvKvYdoksnUfgXOEQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-exponentiation-operator@^7.0.0", "@babel/plugin-transform-exponentiation-operator@^7.8.3": +"@babel/plugin-transform-exponentiation-operator@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.8.3.tgz#581a6d7f56970e06bf51560cd64f5e947b70d7b7" integrity sha512-zwIpuIymb3ACcInbksHaNcR12S++0MDLKkiqXHl3AzpgdKlFNhog+z/K0+TGW+b0w5pgTq4H6IwV/WhxbGYSjQ== @@ -601,14 +511,14 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-flow" "^7.8.3" -"@babel/plugin-transform-for-of@^7.0.0", "@babel/plugin-transform-for-of@^7.9.0": +"@babel/plugin-transform-for-of@^7.0.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.9.0.tgz#0f260e27d3e29cd1bb3128da5e76c761aa6c108e" integrity sha512-lTAnWOpMwOXpyDx06N+ywmF3jNbafZEqZ96CGYabxHrxNX8l5ny7dt4bK/rGwAh9utyP2b2Hv7PlZh1AAS54FQ== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-function-name@^7.0.0", "@babel/plugin-transform-function-name@^7.8.3": +"@babel/plugin-transform-function-name@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.8.3.tgz#279373cb27322aaad67c2683e776dfc47196ed8b" integrity sha512-rO/OnDS78Eifbjn5Py9v8y0aR+aSYhDhqAwVfsTl0ERuMZyr05L1aFSCJnbv2mmsLkit/4ReeQ9N2BgLnOcPCQ== @@ -616,30 +526,21 @@ "@babel/helper-function-name" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-literals@^7.0.0", "@babel/plugin-transform-literals@^7.8.3": +"@babel/plugin-transform-literals@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.8.3.tgz#aef239823d91994ec7b68e55193525d76dbd5dc1" integrity sha512-3Tqf8JJ/qB7TeldGl+TT55+uQei9JfYaregDcEAyBZ7akutriFrt6C/wLYIer6OYhleVQvH/ntEhjE/xMmy10A== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-member-expression-literals@^7.0.0", "@babel/plugin-transform-member-expression-literals@^7.8.3": +"@babel/plugin-transform-member-expression-literals@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.8.3.tgz#963fed4b620ac7cbf6029c755424029fa3a40410" integrity sha512-3Wk2EXhnw+rP+IDkK6BdtPKsUE5IeZ6QOGrPYvw52NwBStw9V1ZVzxgK6fSKSxqUvH9eQPR3tm3cOq79HlsKYA== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-modules-amd@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.9.0.tgz#19755ee721912cf5bb04c07d50280af3484efef4" - integrity sha512-vZgDDF003B14O8zJy0XXLnPH4sg+9X5hFBBGN1V+B2rgrB+J2xIypSN6Rk9imB2hSTHQi5OHLrFWsZab1GMk+Q== - dependencies: - "@babel/helper-module-transforms" "^7.9.0" - "@babel/helper-plugin-utils" "^7.8.3" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-commonjs@^7.0.0", "@babel/plugin-transform-modules-commonjs@^7.9.0": +"@babel/plugin-transform-modules-commonjs@^7.0.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.0.tgz#e3e72f4cbc9b4a260e30be0ea59bdf5a39748940" integrity sha512-qzlCrLnKqio4SlgJ6FMMLBe4bySNis8DFn1VkGmOcxG9gqEyPIOzeQrA//u0HAKrWpJlpZbZMPB1n/OPa4+n8g== @@ -649,37 +550,15 @@ "@babel/helper-simple-access" "^7.8.3" babel-plugin-dynamic-import-node "^2.3.0" -"@babel/plugin-transform-modules-systemjs@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.9.0.tgz#e9fd46a296fc91e009b64e07ddaa86d6f0edeb90" - integrity sha512-FsiAv/nao/ud2ZWy4wFacoLOm5uxl0ExSQ7ErvP7jpoihLR6Cq90ilOFyX9UXct3rbtKsAiZ9kFt5XGfPe/5SQ== +"@babel/plugin-transform-modules-commonjs@^7.1.0": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.9.6.tgz#64b7474a4279ee588cacd1906695ca721687c277" + integrity sha512-7H25fSlLcn+iYimmsNe3uK1at79IE6SKW9q0/QeEHTMC9MdOZ+4bA+T1VFB5fgOqBWoqlifXRzYD0JPdmIrgSQ== dependencies: - "@babel/helper-hoist-variables" "^7.8.3" "@babel/helper-module-transforms" "^7.9.0" "@babel/helper-plugin-utils" "^7.8.3" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-umd@^7.9.0": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.9.0.tgz#e909acae276fec280f9b821a5f38e1f08b480697" - integrity sha512-uTWkXkIVtg/JGRSIABdBoMsoIeoHQHPTL0Y2E7xf5Oj7sLqwVsNXOkNk0VJc7vF0IMBsPeikHxFjGe+qmwPtTQ== - dependencies: - "@babel/helper-module-transforms" "^7.9.0" - "@babel/helper-plugin-utils" "^7.8.3" - -"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" - integrity sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.3" - -"@babel/plugin-transform-new-target@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.8.3.tgz#60cc2ae66d85c95ab540eb34babb6434d4c70c43" - integrity sha512-QuSGysibQpyxexRyui2vca+Cmbljo8bcRckgzYV4kRIsHpVeyeC3JDO63pY+xFZ6bWOBn7pfKZTqV4o/ix9sFw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" + "@babel/helper-simple-access" "^7.8.3" + babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-object-assign@^7.0.0": version "7.8.3" @@ -688,7 +567,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-object-super@^7.0.0", "@babel/plugin-transform-object-super@^7.8.3": +"@babel/plugin-transform-object-super@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.8.3.tgz#ebb6a1e7a86ffa96858bd6ac0102d65944261725" integrity sha512-57FXk+gItG/GejofIyLIgBKTas4+pEU47IXKDBWFTxdPd7F80H8zybyAY7UoblVfBhBGs2EKM+bJUu2+iUYPDQ== @@ -696,7 +575,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-replace-supers" "^7.8.3" -"@babel/plugin-transform-parameters@^7.0.0", "@babel/plugin-transform-parameters@^7.8.7": +"@babel/plugin-transform-parameters@^7.0.0": version "7.9.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.9.3.tgz#3028d0cc20ddc733166c6e9c8534559cee09f54a" integrity sha512-fzrQFQhp7mIhOzmOtPiKffvCYQSK10NR8t6BBz2yPbeUHb9OLW8RZGtgDRBn8z2hGcwvKDL3vC7ojPTLNxmqEg== @@ -704,7 +583,7 @@ "@babel/helper-get-function-arity" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-property-literals@^7.0.0", "@babel/plugin-transform-property-literals@^7.8.3": +"@babel/plugin-transform-property-literals@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.8.3.tgz#33194300d8539c1ed28c62ad5087ba3807b98263" integrity sha512-uGiiXAZMqEoQhRWMK17VospMZh5sXWg+dlh2soffpkAl96KAm+WZuJfa6lcELotSRmooLqg0MWdH6UUq85nmmg== @@ -744,20 +623,13 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-jsx" "^7.8.3" -"@babel/plugin-transform-regenerator@^7.0.0", "@babel/plugin-transform-regenerator@^7.8.7": +"@babel/plugin-transform-regenerator@^7.0.0": version "7.8.7" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.8.7.tgz#5e46a0dca2bee1ad8285eb0527e6abc9c37672f8" integrity sha512-TIg+gAl4Z0a3WmD3mbYSk+J9ZUH6n/Yc57rtKRnlA/7rcCvpekHXe0CMZHP1gYp7/KLe9GHTuIba0vXmls6drA== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.8.3.tgz#9a0635ac4e665d29b162837dd3cc50745dfdf1f5" - integrity sha512-mwMxcycN3omKFDjDQUl+8zyMsBfjRFr0Zn/64I41pmjv4NJuqcYlEtezwYtw9TFd9WR1vN5kiM+O0gMZzO6L0A== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-transform-runtime@^7.0.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.9.0.tgz#45468c0ae74cc13204e1d3b1f4ce6ee83258af0b" @@ -768,21 +640,21 @@ resolve "^1.8.1" semver "^5.5.1" -"@babel/plugin-transform-shorthand-properties@^7.0.0", "@babel/plugin-transform-shorthand-properties@^7.8.3": +"@babel/plugin-transform-shorthand-properties@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.8.3.tgz#28545216e023a832d4d3a1185ed492bcfeac08c8" integrity sha512-I9DI6Odg0JJwxCHzbzW08ggMdCezoWcuQRz3ptdudgwaHxTjxw5HgdFJmZIkIMlRymL6YiZcped4TTCB0JcC8w== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-spread@^7.0.0", "@babel/plugin-transform-spread@^7.8.3": +"@babel/plugin-transform-spread@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.8.3.tgz#9c8ffe8170fdfb88b114ecb920b82fb6e95fe5e8" integrity sha512-CkuTU9mbmAoFOI1tklFWYYbzX5qCIZVXPVy0jpXgGwkplCndQAa58s2jr66fTeQnA64bDox0HL4U56CFYoyC7g== dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-sticky-regex@^7.0.0", "@babel/plugin-transform-sticky-regex@^7.8.3": +"@babel/plugin-transform-sticky-regex@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.8.3.tgz#be7a1290f81dae767475452199e1f76d6175b100" integrity sha512-9Spq0vGCD5Bb4Z/ZXXSK5wbbLFMG085qd2vhL1JYu1WcQ5bXqZBAYRzU1d+p79GcHs2szYv5pVQCX13QgldaWw== @@ -790,7 +662,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/helper-regex" "^7.8.3" -"@babel/plugin-transform-template-literals@^7.0.0", "@babel/plugin-transform-template-literals@^7.8.3": +"@babel/plugin-transform-template-literals@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.8.3.tgz#7bfa4732b455ea6a43130adc0ba767ec0e402a80" integrity sha512-820QBtykIQOLFT8NZOcTRJ1UNuztIELe4p9DCgvj4NK+PwluSJ49we7s9FB1HIGNIYT7wFUJ0ar2QpCDj0escQ== @@ -798,13 +670,6 @@ "@babel/helper-annotate-as-pure" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-typeof-symbol@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.8.4.tgz#ede4062315ce0aaf8a657a920858f1a2f35fc412" - integrity sha512-2QKyfjGdvuNfHsb7qnBBlKclbD4CfshH2KvDabiijLMGXPHJXGxtDzwIF7bQP+T0ysw8fYTtxPafgfs/c1Lrqg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-transform-typescript@^7.5.0", "@babel/plugin-transform-typescript@^7.9.0": version "7.9.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.4.tgz#4bb4dde4f10bbf2d787fce9707fb09b483e33359" @@ -814,7 +679,7 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-syntax-typescript" "^7.8.3" -"@babel/plugin-transform-unicode-regex@^7.0.0", "@babel/plugin-transform-unicode-regex@^7.8.3": +"@babel/plugin-transform-unicode-regex@^7.0.0": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.8.3.tgz#0cef36e3ba73e5c57273effb182f46b91a1ecaad" integrity sha512-+ufgJjYdmWfSQ+6NS9VGUR2ns8cjJjYbrbi11mZBTaWm+Fui/ncTLFF28Ei1okavY+xkojGr1eJxNsWYeA5aZw== @@ -822,72 +687,6 @@ "@babel/helper-create-regexp-features-plugin" "^7.8.3" "@babel/helper-plugin-utils" "^7.8.3" -"@babel/preset-env@^7.1.6": - version "7.9.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.9.0.tgz#a5fc42480e950ae8f5d9f8f2bbc03f52722df3a8" - integrity sha512-712DeRXT6dyKAM/FMbQTV/FvRCms2hPCx+3weRjZ8iQVQWZejWWk1wwG6ViWMyqb/ouBbGOl5b6aCk0+j1NmsQ== - dependencies: - "@babel/compat-data" "^7.9.0" - "@babel/helper-compilation-targets" "^7.8.7" - "@babel/helper-module-imports" "^7.8.3" - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-proposal-async-generator-functions" "^7.8.3" - "@babel/plugin-proposal-dynamic-import" "^7.8.3" - "@babel/plugin-proposal-json-strings" "^7.8.3" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-proposal-numeric-separator" "^7.8.3" - "@babel/plugin-proposal-object-rest-spread" "^7.9.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.8.3" - "@babel/plugin-proposal-optional-chaining" "^7.9.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.8.3" - "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-dynamic-import" "^7.8.0" - "@babel/plugin-syntax-json-strings" "^7.8.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.8.0" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" - "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.8.3" - "@babel/plugin-transform-arrow-functions" "^7.8.3" - "@babel/plugin-transform-async-to-generator" "^7.8.3" - "@babel/plugin-transform-block-scoped-functions" "^7.8.3" - "@babel/plugin-transform-block-scoping" "^7.8.3" - "@babel/plugin-transform-classes" "^7.9.0" - "@babel/plugin-transform-computed-properties" "^7.8.3" - "@babel/plugin-transform-destructuring" "^7.8.3" - "@babel/plugin-transform-dotall-regex" "^7.8.3" - "@babel/plugin-transform-duplicate-keys" "^7.8.3" - "@babel/plugin-transform-exponentiation-operator" "^7.8.3" - "@babel/plugin-transform-for-of" "^7.9.0" - "@babel/plugin-transform-function-name" "^7.8.3" - "@babel/plugin-transform-literals" "^7.8.3" - "@babel/plugin-transform-member-expression-literals" "^7.8.3" - "@babel/plugin-transform-modules-amd" "^7.9.0" - "@babel/plugin-transform-modules-commonjs" "^7.9.0" - "@babel/plugin-transform-modules-systemjs" "^7.9.0" - "@babel/plugin-transform-modules-umd" "^7.9.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" - "@babel/plugin-transform-new-target" "^7.8.3" - "@babel/plugin-transform-object-super" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.8.7" - "@babel/plugin-transform-property-literals" "^7.8.3" - "@babel/plugin-transform-regenerator" "^7.8.7" - "@babel/plugin-transform-reserved-words" "^7.8.3" - "@babel/plugin-transform-shorthand-properties" "^7.8.3" - "@babel/plugin-transform-spread" "^7.8.3" - "@babel/plugin-transform-sticky-regex" "^7.8.3" - "@babel/plugin-transform-template-literals" "^7.8.3" - "@babel/plugin-transform-typeof-symbol" "^7.8.4" - "@babel/plugin-transform-unicode-regex" "^7.8.3" - "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.9.0" - browserslist "^4.9.1" - core-js-compat "^3.6.2" - invariant "^2.2.2" - levenary "^1.1.1" - semver "^5.5.0" - "@babel/preset-flow@^7.0.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.9.0.tgz#fee847c3e090b0b2d9227c1949e4da1d1379280d" @@ -896,17 +695,6 @@ "@babel/helper-plugin-utils" "^7.8.3" "@babel/plugin-transform-flow-strip-types" "^7.9.0" -"@babel/preset-modules@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.3.tgz#13242b53b5ef8c883c3cf7dddd55b36ce80fbc72" - integrity sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" - "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - "@babel/preset-typescript@^7.1.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.9.0.tgz#87705a72b1f0d59df21c179f7c3d2ef4b16ce192" @@ -933,7 +721,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.0.0", "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": +"@babel/template@^7.0.0", "@babel/template@^7.3.3", "@babel/template@^7.7.4", "@babel/template@^7.8.3", "@babel/template@^7.8.6": version "7.8.6" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== @@ -972,7 +760,7 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": version "7.9.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.0.tgz#00b064c3df83ad32b2dbf5ff07312b15c7f1efb5" integrity sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng== @@ -981,6 +769,15 @@ lodash "^4.17.13" to-fast-properties "^2.0.0" +"@babel/types@^7.3.3": + version "7.9.6" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.6.tgz#2c5502b427251e9de1bd2dff95add646d95cc9f7" + integrity sha512-qxXzvBO//jO9ZnoasKF1uJzHd2+M6Q2ZPIVfnFps8JJvXy0ZBbwbNOmE6SGIY5XOY6d1Bo5lb9d9RJ8nv3WSeA== + dependencies: + "@babel/helper-validator-identifier" "^7.9.5" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + "@babel/types@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.9.5.tgz#89231f82915a8a566a703b3b20133f73da6b9444" @@ -1064,59 +861,58 @@ chalk "^2.0.1" slash "^2.0.0" -"@jest/console@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-25.4.0.tgz#e2760b532701137801ba824dcff6bc822c961bac" - integrity sha512-CfE0erx4hdJ6t7RzAcE1wLG6ZzsHSmybvIBQDoCkDM1QaSeWL9wJMzID/2BbHHa7ll9SsbbK43HjbERbBaFX2A== +"@jest/console@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-26.0.1.tgz#62b3b2fa8990f3cbffbef695c42ae9ddbc8f4b39" + integrity sha512-9t1KUe/93coV1rBSxMmBAOIK3/HVpwxArCA1CxskKyRiv6o8J70V8C/V3OJminVCTa2M0hQI9AWRd5wxu2dAHw== dependencies: - "@jest/types" "^25.4.0" - chalk "^3.0.0" - jest-message-util "^25.4.0" - jest-util "^25.4.0" + "@jest/types" "^26.0.1" + chalk "^4.0.0" + jest-message-util "^26.0.1" + jest-util "^26.0.1" slash "^3.0.0" -"@jest/core@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-25.4.0.tgz#cc1fe078df69b8f0fbb023bb0bcee23ef3b89411" - integrity sha512-h1x9WSVV0+TKVtATGjyQIMJENs8aF6eUjnCoi4jyRemYZmekLr8EJOGQqTWEX8W6SbZ6Skesy9pGXrKeAolUJw== +"@jest/core@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-26.0.1.tgz#aa538d52497dfab56735efb00e506be83d841fae" + integrity sha512-Xq3eqYnxsG9SjDC+WLeIgf7/8KU6rddBxH+SCt18gEpOhAGYC/Mq+YbtlNcIdwjnnT+wDseXSbU0e5X84Y4jTQ== dependencies: - "@jest/console" "^25.4.0" - "@jest/reporters" "^25.4.0" - "@jest/test-result" "^25.4.0" - "@jest/transform" "^25.4.0" - "@jest/types" "^25.4.0" + "@jest/console" "^26.0.1" + "@jest/reporters" "^26.0.1" + "@jest/test-result" "^26.0.1" + "@jest/transform" "^26.0.1" + "@jest/types" "^26.0.1" ansi-escapes "^4.2.1" - chalk "^3.0.0" + chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.2.3" - jest-changed-files "^25.4.0" - jest-config "^25.4.0" - jest-haste-map "^25.4.0" - jest-message-util "^25.4.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.4.0" - jest-resolve-dependencies "^25.4.0" - jest-runner "^25.4.0" - jest-runtime "^25.4.0" - jest-snapshot "^25.4.0" - jest-util "^25.4.0" - jest-validate "^25.4.0" - jest-watcher "^25.4.0" + graceful-fs "^4.2.4" + jest-changed-files "^26.0.1" + jest-config "^26.0.1" + jest-haste-map "^26.0.1" + jest-message-util "^26.0.1" + jest-regex-util "^26.0.0" + jest-resolve "^26.0.1" + jest-resolve-dependencies "^26.0.1" + jest-runner "^26.0.1" + jest-runtime "^26.0.1" + jest-snapshot "^26.0.1" + jest-util "^26.0.1" + jest-validate "^26.0.1" + jest-watcher "^26.0.1" micromatch "^4.0.2" p-each-series "^2.1.0" - realpath-native "^2.0.0" rimraf "^3.0.0" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-25.4.0.tgz#45071f525f0d8c5a51ed2b04fd42b55a8f0c7cb3" - integrity sha512-KDctiak4mu7b4J6BIoN/+LUL3pscBzoUCP+EtSPd2tK9fqyDY5OF+CmkBywkFWezS9tyH5ACOQNtpjtueEDH6Q== +"@jest/environment@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-26.0.1.tgz#82f519bba71959be9b483675ee89de8c8f72a5c8" + integrity sha512-xBDxPe8/nx251u0VJ2dFAFz2H23Y98qdIaNwnMK6dFQr05jc+Ne/2np73lOAx+5mSBO/yuQldRrQOf6hP1h92g== dependencies: - "@jest/fake-timers" "^25.4.0" - "@jest/types" "^25.4.0" - jest-mock "^25.4.0" + "@jest/fake-timers" "^26.0.1" + "@jest/types" "^26.0.1" + jest-mock "^26.0.1" "@jest/fake-timers@^24.8.0": version "24.8.0" @@ -1127,47 +923,57 @@ jest-message-util "^24.8.0" jest-mock "^24.8.0" -"@jest/fake-timers@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-25.4.0.tgz#3a9a4289ba836abd084953dca406389a57e00fbd" - integrity sha512-lI9z+VOmVX4dPPFzyj0vm+UtaB8dCJJ852lcDnY0uCPRvZAaVGnMwBBc1wxtf+h7Vz6KszoOvKAt4QijDnHDkg== +"@jest/fake-timers@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-26.0.1.tgz#f7aeff13b9f387e9d0cac9a8de3bba538d19d796" + integrity sha512-Oj/kCBnTKhm7CR+OJSjZty6N1bRDr9pgiYQr4wY221azLz5PHi08x/U+9+QpceAYOWheauLP8MhtSVFrqXQfhg== dependencies: - "@jest/types" "^25.4.0" - jest-message-util "^25.4.0" - jest-mock "^25.4.0" - jest-util "^25.4.0" - lolex "^5.0.0" + "@jest/types" "^26.0.1" + "@sinonjs/fake-timers" "^6.0.1" + jest-message-util "^26.0.1" + jest-mock "^26.0.1" + jest-util "^26.0.1" -"@jest/reporters@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-25.4.0.tgz#836093433b32ce4e866298af2d6fcf6ed351b0b0" - integrity sha512-bhx/buYbZgLZm4JWLcRJ/q9Gvmd3oUh7k2V7gA4ZYBx6J28pIuykIouclRdiAC6eGVX1uRZT+GK4CQJLd/PwPg== +"@jest/globals@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-26.0.1.tgz#3f67b508a7ce62b6e6efc536f3d18ec9deb19a9c" + integrity sha512-iuucxOYB7BRCvT+TYBzUqUNuxFX1hqaR6G6IcGgEqkJ5x4htNKo1r7jk1ji9Zj8ZMiMw0oB5NaA7k5Tx6MVssA== + dependencies: + "@jest/environment" "^26.0.1" + "@jest/types" "^26.0.1" + expect "^26.0.1" + +"@jest/reporters@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-26.0.1.tgz#14ae00e7a93e498cec35b0c00ab21c375d9b078f" + integrity sha512-NWWy9KwRtE1iyG/m7huiFVF9YsYv/e+mbflKRV84WDoJfBqUrNRyDbL/vFxQcYLl8IRqI4P3MgPn386x76Gf2g== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^25.4.0" - "@jest/test-result" "^25.4.0" - "@jest/transform" "^25.4.0" - "@jest/types" "^25.4.0" - chalk "^3.0.0" + "@jest/console" "^26.0.1" + "@jest/test-result" "^26.0.1" + "@jest/transform" "^26.0.1" + "@jest/types" "^26.0.1" + chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.2" + graceful-fs "^4.2.4" istanbul-lib-coverage "^3.0.0" istanbul-lib-instrument "^4.0.0" istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.0.2" - jest-haste-map "^25.4.0" - jest-resolve "^25.4.0" - jest-util "^25.4.0" - jest-worker "^25.4.0" + jest-haste-map "^26.0.1" + jest-resolve "^26.0.1" + jest-util "^26.0.1" + jest-worker "^26.0.0" slash "^3.0.0" source-map "^0.6.0" - string-length "^3.1.0" + string-length "^4.0.1" terminal-link "^2.0.0" v8-to-istanbul "^4.1.3" optionalDependencies: - node-notifier "^6.0.0" + node-notifier "^7.0.0" "@jest/source-map@^24.3.0": version "24.3.0" @@ -1178,13 +984,13 @@ graceful-fs "^4.1.15" source-map "^0.6.0" -"@jest/source-map@^25.2.6": - version "25.2.6" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-25.2.6.tgz#0ef2209514c6d445ebccea1438c55647f22abb4c" - integrity sha512-VuIRZF8M2zxYFGTEhkNSvQkUKafQro4y+mwUxy5ewRqs5N/ynSFUODYp3fy1zCnbCMy1pz3k+u57uCqx8QRSQQ== +"@jest/source-map@^26.0.0": + version "26.0.0" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-26.0.0.tgz#fd7706484a7d3faf7792ae29783933bbf48a4749" + integrity sha512-S2Z+Aj/7KOSU2TfW0dyzBze7xr95bkm5YXNUqqCek+HE0VbNNSNzrRwfIi5lf7wvzDTSS0/ib8XQ1krFNyYgbQ== dependencies: callsites "^3.0.0" - graceful-fs "^4.2.3" + graceful-fs "^4.2.4" source-map "^0.6.0" "@jest/test-result@^24.8.0": @@ -1196,44 +1002,44 @@ "@jest/types" "^24.8.0" "@types/istanbul-lib-coverage" "^2.0.0" -"@jest/test-result@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-25.4.0.tgz#6f2ec2c8da9981ef013ad8651c1c6f0cb20c6324" - integrity sha512-8BAKPaMCHlL941eyfqhWbmp3MebtzywlxzV+qtngQ3FH+RBqnoSAhNEPj4MG7d2NVUrMOVfrwuzGpVIK+QnMAA== +"@jest/test-result@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-26.0.1.tgz#1ffdc1ba4bc289919e54b9414b74c9c2f7b2b718" + integrity sha512-oKwHvOI73ICSYRPe8WwyYPTtiuOAkLSbY8/MfWF3qDEd/sa8EDyZzin3BaXTqufir/O/Gzea4E8Zl14XU4Mlyg== dependencies: - "@jest/console" "^25.4.0" - "@jest/types" "^25.4.0" + "@jest/console" "^26.0.1" + "@jest/types" "^26.0.1" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-25.4.0.tgz#2b96f9d37f18dc3336b28e3c8070f97f9f55f43b" - integrity sha512-240cI+nsM3attx2bMp9uGjjHrwrpvxxrZi8Tyqp/cfOzl98oZXVakXBgxODGyBYAy/UGXPKXLvNc2GaqItrsJg== +"@jest/test-sequencer@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-26.0.1.tgz#b0563424728f3fe9e75d1442b9ae4c11da73f090" + integrity sha512-ssga8XlwfP8YjbDcmVhwNlrmblddMfgUeAkWIXts1V22equp2GMIHxm7cyeD5Q/B0ZgKPK/tngt45sH99yLLGg== dependencies: - "@jest/test-result" "^25.4.0" - jest-haste-map "^25.4.0" - jest-runner "^25.4.0" - jest-runtime "^25.4.0" + "@jest/test-result" "^26.0.1" + graceful-fs "^4.2.4" + jest-haste-map "^26.0.1" + jest-runner "^26.0.1" + jest-runtime "^26.0.1" -"@jest/transform@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-25.4.0.tgz#eef36f0367d639e2fd93dccd758550377fbb9962" - integrity sha512-t1w2S6V1sk++1HHsxboWxPEuSpN8pxEvNrZN+Ud/knkROWtf8LeUmz73A4ezE8476a5AM00IZr9a8FO9x1+j3g== +"@jest/transform@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.0.1.tgz#0e3ecbb34a11cd4b2080ed0a9c4856cf0ceb0639" + integrity sha512-pPRkVkAQ91drKGbzCfDOoHN838+FSbYaEAvBXvKuWeeRRUD8FjwXkqfUNUZL6Ke48aA/1cqq/Ni7kVMCoqagWA== dependencies: "@babel/core" "^7.1.0" - "@jest/types" "^25.4.0" + "@jest/types" "^26.0.1" babel-plugin-istanbul "^6.0.0" - chalk "^3.0.0" + chalk "^4.0.0" convert-source-map "^1.4.0" fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.3" - jest-haste-map "^25.4.0" - jest-regex-util "^25.2.6" - jest-util "^25.4.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.0.1" + jest-regex-util "^26.0.0" + jest-util "^26.0.1" micromatch "^4.0.2" pirates "^4.0.1" - realpath-native "^2.0.0" slash "^3.0.0" source-map "^0.6.1" write-file-atomic "^3.0.0" @@ -1257,25 +1063,25 @@ "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@jest/types@^25.4.0": - version "25.4.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.4.0.tgz#5afeb8f7e1cba153a28e5ac3c9fe3eede7206d59" - integrity sha512-XBeaWNzw2PPnGW5aXvZt3+VO60M+34RY3XDsCK5tW7kyj3RK0XClRutCfjqcBuaR2aBQTbluEDME9b5MB9UAPw== +"@jest/types@^25.5.0": + version "25.5.0" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" + integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^15.0.0" chalk "^3.0.0" -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== +"@jest/types@^26.0.1": + version "26.0.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.0.1.tgz#b78333fbd113fa7aec8d39de24f88de8686dac67" + integrity sha512-IbtjvqI9+eS1qFnOIEL7ggWmT+iK/U+Vde9cGWtYb/b6XgKb3X44ZAe/z9YZzoAAZ/E92m0DqrilF934IGNnQA== dependencies: "@types/istanbul-lib-coverage" "^2.0.0" "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^15.0.0" - chalk "^3.0.0" + chalk "^4.0.0" "@react-native-community/cli-debugger-ui@^4.9.0": version "4.9.0" @@ -1398,6 +1204,13 @@ dependencies: type-detect "4.0.8" +"@sinonjs/fake-timers@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz#293674fccb3262ac782c7aadfdeca86b10c75c40" + integrity sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA== + dependencies: + "@sinonjs/commons" "^1.7.0" + "@types/babel__core@^7.1.7": version "7.1.7" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.7.tgz#1dacad8840364a57c98d0dd4855c6dd3752c6b89" @@ -1436,6 +1249,13 @@ resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== +"@types/graceful-fs@^4.1.2": + version "4.1.3" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.3.tgz#039af35fe26bec35003e8d86d2ee9c586354348f" + integrity sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ== + dependencies: + "@types/node" "*" + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff" @@ -1461,15 +1281,20 @@ "@types/istanbul-lib-coverage" "*" "@types/istanbul-lib-report" "*" +"@types/node@*": + version "13.13.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.4.tgz#1581d6c16e3d4803eb079c87d4ac893ee7501c2c" + integrity sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA== + "@types/normalize-package-data@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== -"@types/prettier@^1.19.0": - version "1.19.1" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" - integrity sha512-5qOlnZscTn4xxM5MeGXAMOsIOIKIbh9e85zJWfBRVPlRMEVawzoPhINYbRGkBZCI8LxvBe7tJCdWiarA99OZfQ== +"@types/prettier@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.0.0.tgz#dc85454b953178cc6043df5208b9e949b54a3bc4" + integrity sha512-/rM+sWiuOZ5dvuVzV37sUuklsbg+JPOP8d+nNFlo2ZtfpzPiPvh1/gc8liWOLBqe+sR+ZM7guPaIcTt6UZTo7Q== "@types/stack-utils@^1.0.1": version "1.0.1" @@ -1495,10 +1320,10 @@ dependencies: "@types/yargs-parser" "*" -abab@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" - integrity sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w== +abab@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.3.tgz#623e2075e02eb2d3f2475e49f99c91846467907a" + integrity sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg== abbrev@1: version "1.1.1" @@ -1525,35 +1350,30 @@ accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" -acorn-globals@^4.3.2: - version "4.3.4" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.3.4.tgz#9fa1926addc11c97308c4e66d7add0d40c3272e7" - integrity sha512-clfQEh21R+D0leSbUdWf3OcfqyaCSAQ8Ryq00bofSekfr9W8u1jyYZo6ir0xu9Gtcf7BjcHJpnbZH7JOCpP60A== +acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== dependencies: - acorn "^6.0.1" - acorn-walk "^6.0.1" + acorn "^7.1.1" + acorn-walk "^7.1.1" acorn-jsx@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.0.1.tgz#32a064fd925429216a09b141102bfdd185fae40e" integrity sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg== -acorn-walk@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.0.tgz#c957f4a1460da46af4a0388ce28b4c99355b0cbc" - integrity sha512-ugTb7Lq7u4GfWSqqpwE0bGyoBZNMTok/zDBXxfEG0QM50jNlGhIWjRC1pPN7bvV1anhF+bs+/gNcRw+o55Evbg== - -acorn@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.0.2.tgz#6a459041c320ab17592c6317abbfdf4bbaa98ca4" - integrity sha512-GXmKIvbrN3TV7aVqAzVFaMW8F8wzVX7voEBRO3bDA64+EX37YSayggRJP5Xig6HYHBkWKpFg9W5gg6orklubhg== +acorn-walk@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.1.1.tgz#345f0dffad5c735e7373d2fec9a1023e6a44b83e" + integrity sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ== acorn@^6.0.2: version "6.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.1.1.tgz#7d25ae05bb8ad1f9b699108e1094ecd7884adc1f" integrity sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA== -acorn@^7.1.0: +acorn@^7.1.1: version "7.1.1" resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.1.1.tgz#e35668de0b402f359de515c5482a1ab9f89a69bf" integrity sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg== @@ -1769,11 +1589,6 @@ arr-union@^3.1.0: resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= -array-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" - integrity sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM= - array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -1914,17 +1729,18 @@ babel-eslint@10.0.1: eslint-scope "3.7.1" eslint-visitor-keys "^1.0.0" -babel-jest@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-25.4.0.tgz#409eb3e2ddc2ad9a92afdbb00991f1633f8018d0" - integrity sha512-p+epx4K0ypmHuCnd8BapfyOwWwosNCYhedetQey1awddtfmEX0MmdxctGl956uwUmjwXR5VSS5xJcGX9DvdIog== +babel-jest@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.0.1.tgz#450139ce4b6c17174b136425bda91885c397bc46" + integrity sha512-Z4GGmSNQ8pX3WS1O+6v3fo41YItJJZsVxG5gIQ+HuB/iuAQBJxMTHTwz292vuYws1LnHfwSRgoqI+nxdy/pcvw== dependencies: - "@jest/transform" "^25.4.0" - "@jest/types" "^25.4.0" + "@jest/transform" "^26.0.1" + "@jest/types" "^26.0.1" "@types/babel__core" "^7.1.7" babel-plugin-istanbul "^6.0.0" - babel-preset-jest "^25.4.0" - chalk "^3.0.0" + babel-preset-jest "^26.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" slash "^3.0.0" babel-plugin-dynamic-import-node@^2.3.0: @@ -1934,6 +1750,13 @@ babel-plugin-dynamic-import-node@^2.3.0: dependencies: object.assign "^4.1.0" +babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== + dependencies: + object.assign "^4.1.0" + babel-plugin-istanbul@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz#e159ccdc9af95e0b570c75b4573b7c34d671d765" @@ -1945,11 +1768,13 @@ babel-plugin-istanbul@^6.0.0: istanbul-lib-instrument "^4.0.0" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-25.4.0.tgz#0c122c1b93fb76f52d2465be2e8069e798e9d442" - integrity sha512-M3a10JCtTyKevb0MjuH6tU+cP/NVQZ82QPADqI1RQYY1OphztsCeIeQmTsHmF/NS6m0E51Zl4QNsI3odXSQF5w== +babel-plugin-jest-hoist@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-26.0.0.tgz#fd1d35f95cf8849fc65cb01b5e58aedd710b34a8" + integrity sha512-+AuoehOrjt9irZL7DOt2+4ZaTM6dlu1s5TTS46JBa0/qem4dy7VNW3tMb96qeEqcIh20LD73TVNtmVEeymTG7w== dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" "@types/babel__traverse" "^7.0.6" babel-plugin-syntax-trailing-function-commas@^7.0.0-beta.0: @@ -2040,12 +1865,12 @@ babel-preset-fbjs@^3.3.0: "@babel/plugin-transform-template-literals" "^7.0.0" babel-plugin-syntax-trailing-function-commas "^7.0.0-beta.0" -babel-preset-jest@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-25.4.0.tgz#10037cc32b751b994b260964629e49dc479abf4c" - integrity sha512-PwFiEWflHdu3JCeTr0Pb9NcHHE34qWFnPQRVPvqQITx4CsDCzs6o05923I10XvLvn9nNsRHuiVgB72wG/90ZHQ== +babel-preset-jest@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-26.0.0.tgz#1eac82f513ad36c4db2e9263d7c485c825b1faa6" + integrity sha512-9ce+DatAa31DpR4Uir8g4Ahxs5K4W4L8refzt+qHWQANb6LhGcAEfIFgLUwk67oya2cCUd6t4eUMtO/z64ocNw== dependencies: - babel-plugin-jest-hoist "^25.4.0" + babel-plugin-jest-hoist "^26.0.0" babel-preset-current-node-syntax "^0.1.2" babylon@^6.15.0: @@ -2138,27 +1963,10 @@ braces@^3.0.1: dependencies: fill-range "^7.0.1" -browser-process-hrtime@^0.1.2: - version "0.1.3" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz#616f00faef1df7ec1b5bf9cfe2bdc3170f26c7b4" - integrity sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw== - -browser-resolve@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" - integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== - dependencies: - resolve "1.1.7" - -browserslist@^4.8.3, browserslist@^4.9.1: - version "4.11.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.11.1.tgz#92f855ee88d6e050e7e7311d987992014f1a1f1b" - integrity sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g== - dependencies: - caniuse-lite "^1.0.30001038" - electron-to-chromium "^1.3.390" - node-releases "^1.1.53" - pkg-up "^2.0.0" +browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== bser@^2.0.0: version "2.0.0" @@ -2261,10 +2069,10 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001038: - version "1.0.30001038" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz#44da3cbca2ab6cb6aa83d1be5d324e17f141caff" - integrity sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ== +camelcase@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.0.0.tgz#5259f7c30e35e278f1bdc2a4d91230b37cad981e" + integrity sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w== capture-exit@^1.2.0: version "1.2.0" @@ -2315,6 +2123,19 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" +chalk@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.0.0.tgz#6e98081ed2d17faab615eb52ac66ec1fe6209e72" + integrity sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + +char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + chardet@^0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" @@ -2575,14 +2396,6 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.6.2: - version "3.6.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.4.tgz#938476569ebb6cda80d339bcf199fae4f16fff17" - integrity sha512-zAa3IZPvsJ0slViBQ2z+vgyyTuhd3MFn1rBQjZSKVEgB0UMYhUkCj9jJUVPgGTGqWvsBVmfnruXgTcNyTlEiSA== - dependencies: - browserslist "^4.8.3" - semver "7.0.0" - core-js@^2.2.2, core-js@^2.4.1: version "2.5.7" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" @@ -2661,7 +2474,7 @@ cross-spawn@^7.0.0: shebang-command "^2.0.0" which "^2.0.1" -cssom@^0.4.1: +cssom@^0.4.4: version "0.4.4" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== @@ -2671,10 +2484,10 @@ cssom@~0.3.6: resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== -cssstyle@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.2.0.tgz#e4c44debccd6b7911ed617a4395e5754bba59992" - integrity sha512-sEb3XFPx3jNnCAMtqrXPDeSgQr+jojtCeNf8cvMNMh1cG970+lljssvQDzPq6lmmJu2Vhqood/gtEomBiHOGnA== +cssstyle@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== dependencies: cssom "~0.3.6" @@ -2690,14 +2503,14 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -data-urls@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.1.0.tgz#15ee0582baa5e22bb59c77140da8f9c76963bbfe" - integrity sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ== +data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== dependencies: - abab "^2.0.0" - whatwg-mimetype "^2.2.0" - whatwg-url "^7.0.0" + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" dayjs@^1.8.15: version "1.8.15" @@ -2737,6 +2550,11 @@ decamelize@^1.2.0: resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= +decimal.js@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.0.tgz#39466113a9e036111d02f82489b5fd6b0b5ed231" + integrity sha512-vDPw+rDgn3bZe1+F/pyEwb1oMG2XTlRVgAa6B4KccTEpYgF8w6eQllVbQcfIJnZyvzFtFpxnpGtx8dd7DJp/Rw== + decode-uri-component@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" @@ -2861,10 +2679,10 @@ detox@16.7.2: yargs "^13.0.0" yargs-parser "^13.0.0" -diff-sequences@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" - integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== +diff-sequences@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.0.0.tgz#0760059a5c287637b842bd7085311db7060e88a6" + integrity sha512-JC/eHYEC3aSS0vZGjuoc4vHA0yAQTzhQQldXMeMF+JlxLGJlCO38Gma82NV9gk1jGFz8mDzUMeaKXvjRRdJ2dg== doctrine@^2.1.0: version "2.1.0" @@ -2873,12 +2691,12 @@ doctrine@^2.1.0: dependencies: esutils "^2.0.2" -domexception@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" - integrity sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug== +domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== dependencies: - webidl-conversions "^4.0.2" + webidl-conversions "^5.0.0" dtrace-provider@~0.8: version "0.8.7" @@ -2900,11 +2718,6 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.3.390: - version "1.3.392" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.392.tgz#280ab4f7a3ae47419cfabb15dbfc1567be7f1111" - integrity sha512-/hsgeVdReDsyTBE0aU9FRdh1wnNPrX3xlz3t61F+CJPOT+Umfi9DXHsCX85TEgWZQqlow0Rw44/4/jbU2Sqgkg== - emoji-regex@^7.0.1, emoji-regex@^7.0.2: version "7.0.3" resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" @@ -2996,7 +2809,12 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^1.11.1: +escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + +escodegen@^1.14.1: version "1.14.1" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457" integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ== @@ -3111,12 +2929,12 @@ eslint-plugin-react@7.12.4: prop-types "^15.6.2" resolve "^1.9.0" -eslint-plugin-relay@1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.7.0.tgz#f6cfae681381dc96db9bd700d8c33fbe9783143e" - integrity sha512-JmAMQFr9CxXFLo5BppdN/sleofrE1J/cERIgkFqnYdTq0KAeUNGnz3jO41cqcp1y92/D+KJdmEKFsPfnqnDByQ== +eslint-plugin-relay@1.7.1: + version "1.7.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.7.1.tgz#70f479becb06320e57dd86ebc0d38938cb8a5e6e" + integrity sha512-K7j5BF8raseLfgA97udZMGKEtWan+y5BLrBYlApy952saStF0ghYzU9WElIwoVIkcBO8QP+pT4AOuNFFNRzcUw== dependencies: - graphql "^14.0.0 | ^15.0.0-rc.1" + graphql "^14.0.0 || ^15.0.0-rc.1" eslint-rule-composer@^0.3.0: version "0.3.0" @@ -3272,10 +3090,10 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" -execa@^3.2.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-3.4.0.tgz#c08ed4550ef65d858fac269ffc8572446f37eb89" - integrity sha512-r9vdGQk4bmCuK1yKQu1KTwcT2zwfWdbdaXfCtAh+5nU/4fSX+JAb7vZGvI5naJrQlvONrEB20jeruESI69530g== +execa@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.0.0.tgz#7f37d6ec17f09e6b8fc53288611695b6d12b9daf" + integrity sha512-JbDUxwV3BoT5ZVXQrSVbAiaXhXUkIwvbhPIwZ0N13kX+5yCzOhUNdocxB/UQRuYOHRYYwAxKYwJYc0T4D12pDA== dependencies: cross-spawn "^7.0.0" get-stream "^5.0.0" @@ -3284,7 +3102,6 @@ execa@^3.2.0: merge-stream "^2.0.0" npm-run-path "^4.0.0" onetime "^5.1.0" - p-finally "^2.0.0" signal-exit "^3.0.2" strip-final-newline "^2.0.0" @@ -3306,17 +3123,17 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -expect@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-25.4.0.tgz#0b16c17401906d1679d173e59f0d4580b22f8dc8" - integrity sha512-7BDIX99BTi12/sNGJXA9KMRcby4iAmu1xccBOhyKCyEhjcVKS3hPmHdA/4nSI9QGIOkUropKqr3vv7WMDM5lvQ== +expect@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-26.0.1.tgz#18697b9611a7e2725e20ba3ceadda49bc9865421" + integrity sha512-QcCy4nygHeqmbw564YxNbHTJlXh47dVID2BUP52cZFpLU9zHViMFK6h07cC1wf7GYCTIigTdAXhVua8Yl1FkKg== dependencies: - "@jest/types" "^25.4.0" + "@jest/types" "^26.0.1" ansi-styles "^4.0.0" - jest-get-type "^25.2.6" - jest-matcher-utils "^25.4.0" - jest-message-util "^25.4.0" - jest-regex-util "^25.2.6" + jest-get-type "^26.0.0" + jest-matcher-utils "^26.0.1" + jest-message-util "^26.0.1" + jest-regex-util "^26.0.0" extend-shallow@^1.1.2: version "1.1.4" @@ -3508,13 +3325,6 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" -find-up@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha1-RdG35QbHF93UgndaK3eSCjwMV6c= - dependencies: - locate-path "^2.0.0" - find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -3540,10 +3350,10 @@ flat-cache@^1.2.1: rimraf "~2.6.2" write "^0.2.1" -flow-bin@^0.123.0: - version "0.123.0" - resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.123.0.tgz#7ba61a0b8775928cf4943ccf78eed2b1b05f7b3a" - integrity sha512-Ylcf8YDIM/KrqtxkPuq+f8O+6sdYA2Nuz5f+sWHlp539DatZz3YMcsO1EiXaf1C11HJgpT/3YGYe7xZ9/UZmvQ== +flow-bin@^0.124.0: + version "0.124.0" + resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.124.0.tgz#24b2e55874e1e2041f9247f42473b3db2ef32758" + integrity sha512-KEtDJ7CFUjcuhw6N52FTZshDd1krf1fxpp4APSIrwhVm+IrlcKJ+EMXpeXKM1kKNSZ347dYGh8wEvXQl4pHZEA== flow-parser@0.*: version "0.89.0" @@ -3768,15 +3578,20 @@ graceful-fs@^4.1.15: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.15.tgz#ffb703e1066e8a0eeaa4c8b80ba9253eeefbfb00" integrity sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA== -graceful-fs@^4.2.0, graceful-fs@^4.2.3: +graceful-fs@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== -"graphql@^14.0.0 | ^15.0.0-rc.1": - version "15.0.0-rc.2" - resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.0.0-rc.2.tgz#6549e52e5415ac08900c432b22d34500c0c3635f" - integrity sha512-X9ZybETBiZ5zndyXm/Yn3dd0nJqiCNZ7w06lnd0zMiCtBR/KQGgxJmnf47Y/P/Fy7JXM4QDF+MeeoH724yc3DQ== +graceful-fs@^4.2.4: + version "4.2.4" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" + integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== + +"graphql@^14.0.0 || ^15.0.0-rc.1": + version "15.0.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.0.0.tgz#042a5eb5e2506a2e2111ce41eb446a8e570b8be9" + integrity sha512-ZyVO1xIF9F+4cxfkdhOJINM+51B06Friuv4M66W7HzUOeFd+vNzUn4vtswYINPi6sysjf1M2Ri/rwZALqgwbaQ== "growl@~> 1.10.0": version "1.10.5" @@ -3889,12 +3704,12 @@ hosted-git-info@^2.1.4: resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== -html-encoding-sniffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" - integrity sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw== +html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== dependencies: - whatwg-encoding "^1.0.1" + whatwg-encoding "^1.0.5" html-escaper@^2.0.0: version "2.0.0" @@ -4037,7 +3852,7 @@ interpret@^1.0.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" integrity sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ= -invariant@^2.2.2, invariant@^2.2.4: +invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -4185,6 +4000,11 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" +is-potential-custom-element-name@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" + integrity sha1-DFLlS8yjkbssSUsh6GJtczbG45c= + is-promise@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" @@ -4318,114 +4138,113 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-25.4.0.tgz#e573db32c2fd47d2b90357ea2eda0622c5c5cbd6" - integrity sha512-VR/rfJsEs4BVMkwOTuStRyS630fidFVekdw/lBaBQjx9KK3VZFOZ2c0fsom2fRp8pMCrCTP6LGna00o/DXGlqA== +jest-changed-files@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-26.0.1.tgz#1334630c6a1ad75784120f39c3aa9278e59f349f" + integrity sha512-q8LP9Sint17HaE2LjxQXL+oYWW/WeeXMPE2+Op9X3mY8IEGFVc14xRxFjUuXUbcPAlDLhtWdIEt59GdQbn76Hw== dependencies: - "@jest/types" "^25.4.0" - execa "^3.2.0" + "@jest/types" "^26.0.1" + execa "^4.0.0" throat "^5.0.0" -jest-cli@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-25.4.0.tgz#5dac8be0fece6ce39f0d671395a61d1357322bab" - integrity sha512-usyrj1lzCJZMRN1r3QEdnn8e6E6yCx/QN7+B1sLoA68V7f3WlsxSSQfy0+BAwRiF4Hz2eHauf11GZG3PIfWTXQ== +jest-cli@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-26.0.1.tgz#3a42399a4cbc96a519b99ad069a117d955570cac" + integrity sha512-pFLfSOBcbG9iOZWaMK4Een+tTxi/Wcm34geqZEqrst9cZDkTQ1LZ2CnBrTlHWuYAiTMFr0EQeK52ScyFU8wK+w== dependencies: - "@jest/core" "^25.4.0" - "@jest/test-result" "^25.4.0" - "@jest/types" "^25.4.0" - chalk "^3.0.0" + "@jest/core" "^26.0.1" + "@jest/test-result" "^26.0.1" + "@jest/types" "^26.0.1" + chalk "^4.0.0" exit "^0.1.2" + graceful-fs "^4.2.4" import-local "^3.0.2" is-ci "^2.0.0" - jest-config "^25.4.0" - jest-util "^25.4.0" - jest-validate "^25.4.0" + jest-config "^26.0.1" + jest-util "^26.0.1" + jest-validate "^26.0.1" prompts "^2.0.1" - realpath-native "^2.0.0" yargs "^15.3.1" -jest-config@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-25.4.0.tgz#56e5df3679a96ff132114b44fb147389c8c0a774" - integrity sha512-egT9aKYxMyMSQV1aqTgam0SkI5/I2P9qrKexN5r2uuM2+68ypnc+zPGmfUxK7p1UhE7dYH9SLBS7yb+TtmT1AA== +jest-config@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-26.0.1.tgz#096a3d4150afadf719d1fab00e9a6fb2d6d67507" + integrity sha512-9mWKx2L1LFgOXlDsC4YSeavnblN6A4CPfXFiobq+YYLaBMymA/SczN7xYTSmLaEYHZOcB98UdoN4m5uNt6tztg== dependencies: "@babel/core" "^7.1.0" - "@jest/test-sequencer" "^25.4.0" - "@jest/types" "^25.4.0" - babel-jest "^25.4.0" - chalk "^3.0.0" + "@jest/test-sequencer" "^26.0.1" + "@jest/types" "^26.0.1" + babel-jest "^26.0.1" + chalk "^4.0.0" deepmerge "^4.2.2" glob "^7.1.1" - jest-environment-jsdom "^25.4.0" - jest-environment-node "^25.4.0" - jest-get-type "^25.2.6" - jest-jasmine2 "^25.4.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.4.0" - jest-util "^25.4.0" - jest-validate "^25.4.0" + graceful-fs "^4.2.4" + jest-environment-jsdom "^26.0.1" + jest-environment-node "^26.0.1" + jest-get-type "^26.0.0" + jest-jasmine2 "^26.0.1" + jest-regex-util "^26.0.0" + jest-resolve "^26.0.1" + jest-util "^26.0.1" + jest-validate "^26.0.1" micromatch "^4.0.2" - pretty-format "^25.4.0" - realpath-native "^2.0.0" + pretty-format "^26.0.1" -jest-diff@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.4.0.tgz#260b70f19a46c283adcad7f081cae71eb784a634" - integrity sha512-kklLbJVXW0y8UKOWOdYhI6TH5MG6QAxrWiBMgQaPIuhj3dNFGirKCd+/xfplBXICQ7fI+3QcqHm9p9lWu1N6ug== +jest-diff@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.0.1.tgz#c44ab3cdd5977d466de69c46929e0e57f89aa1de" + integrity sha512-odTcHyl5X+U+QsczJmOjWw5tPvww+y9Yim5xzqxVl/R1j4z71+fHW4g8qu1ugMmKdFdxw+AtQgs5mupPnzcIBQ== dependencies: - chalk "^3.0.0" - diff-sequences "^25.2.6" - jest-get-type "^25.2.6" - pretty-format "^25.4.0" + chalk "^4.0.0" + diff-sequences "^26.0.0" + jest-get-type "^26.0.0" + pretty-format "^26.0.1" jest-docblock@^21.0.0: version "21.2.0" resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-21.2.0.tgz#51529c3b30d5fd159da60c27ceedc195faf8d414" integrity sha512-5IZ7sY9dBAYSV+YjQ0Ovb540Ku7AO9Z5o2Cg789xj167iQuZ2cG+z0f3Uct6WeYLbU6aQiM2pCs7sZ+4dotydw== -jest-docblock@^25.3.0: - version "25.3.0" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-25.3.0.tgz#8b777a27e3477cd77a168c05290c471a575623ef" - integrity sha512-aktF0kCar8+zxRHxQZwxMy70stc9R1mOmrLsT5VO3pIT0uzGRSDAXxSlz4NqQWpuLjPpuMhPRl7H+5FRsvIQAg== +jest-docblock@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-26.0.0.tgz#3e2fa20899fc928cb13bd0ff68bd3711a36889b5" + integrity sha512-RDZ4Iz3QbtRWycd8bUEPxQsTlYazfYn/h5R65Fc6gOfwozFhoImx+affzky/FFBuqISPTqjXomoIGJVKBWoo0w== dependencies: detect-newline "^3.0.0" -jest-each@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-25.4.0.tgz#ad4e46164764e8e77058f169a0076a7f86f6b7d4" - integrity sha512-lwRIJ8/vQU/6vq3nnSSUw1Y3nz5tkYSFIywGCZpUBd6WcRgpn8NmJoQICojbpZmsJOJNHm0BKdyuJ6Xdx+eDQQ== - dependencies: - "@jest/types" "^25.4.0" - chalk "^3.0.0" - jest-get-type "^25.2.6" - jest-util "^25.4.0" - pretty-format "^25.4.0" - -jest-environment-jsdom@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-25.4.0.tgz#bbfc7f85bb6ade99089062a830c79cb454565cf0" - integrity sha512-KTitVGMDrn2+pt7aZ8/yUTuS333w3pWt1Mf88vMntw7ZSBNDkRS6/4XLbFpWXYfWfp1FjcjQTOKzbK20oIehWQ== - dependencies: - "@jest/environment" "^25.4.0" - "@jest/fake-timers" "^25.4.0" - "@jest/types" "^25.4.0" - jest-mock "^25.4.0" - jest-util "^25.4.0" - jsdom "^15.2.1" - -jest-environment-node@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-25.4.0.tgz#188aef01ae6418e001c03fdd1c299961e1439082" - integrity sha512-wryZ18vsxEAKFH7Z74zi/y/SyI1j6UkVZ6QsllBuT/bWlahNfQjLNwFsgh/5u7O957dYFoXj4yfma4n4X6kU9A== - dependencies: - "@jest/environment" "^25.4.0" - "@jest/fake-timers" "^25.4.0" - "@jest/types" "^25.4.0" - jest-mock "^25.4.0" - jest-util "^25.4.0" - semver "^6.3.0" +jest-each@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-26.0.1.tgz#633083061619302fc90dd8f58350f9d77d67be04" + integrity sha512-OTgJlwXCAR8NIWaXFL5DBbeS4QIYPuNASkzSwMCJO+ywo9BEa6TqkaSWsfR7VdbMLdgYJqSfQcIyjJCNwl5n4Q== + dependencies: + "@jest/types" "^26.0.1" + chalk "^4.0.0" + jest-get-type "^26.0.0" + jest-util "^26.0.1" + pretty-format "^26.0.1" + +jest-environment-jsdom@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-26.0.1.tgz#217690852e5bdd7c846a4e3b50c8ffd441dfd249" + integrity sha512-u88NJa3aptz2Xix2pFhihRBAatwZHWwSiRLBDBQE1cdJvDjPvv7ZGA0NQBxWwDDn7D0g1uHqxM8aGgfA9Bx49g== + dependencies: + "@jest/environment" "^26.0.1" + "@jest/fake-timers" "^26.0.1" + "@jest/types" "^26.0.1" + jest-mock "^26.0.1" + jest-util "^26.0.1" + jsdom "^16.2.2" + +jest-environment-node@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-26.0.1.tgz#584a9ff623124ff6eeb49e0131b5f7612b310b13" + integrity sha512-4FRBWcSn5yVo0KtNav7+5NH5Z/tEgDLp7VRQVS5tCouWORxj+nI+1tOLutM07Zb2Qi7ja+HEDoOUkjBSWZg/IQ== + dependencies: + "@jest/environment" "^26.0.1" + "@jest/fake-timers" "^26.0.1" + "@jest/types" "^26.0.1" + jest-mock "^26.0.1" + jest-util "^26.0.1" jest-get-type@^24.3.0: version "24.3.0" @@ -4437,10 +4256,10 @@ jest-get-type@^24.9.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== -jest-get-type@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" - integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== +jest-get-type@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.0.0.tgz#381e986a718998dbfafcd5ec05934be538db4039" + integrity sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg== jest-haste-map@^24.7.1: version "24.8.1" @@ -4461,18 +4280,19 @@ jest-haste-map@^24.7.1: optionalDependencies: fsevents "^1.2.7" -jest-haste-map@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-25.4.0.tgz#da7c309dd7071e0a80c953ba10a0ec397efb1ae2" - integrity sha512-5EoCe1gXfGC7jmXbKzqxESrgRcaO3SzWXGCnvp9BcT0CFMyrB1Q6LIsjl9RmvmJGQgW297TCfrdgiy574Rl9HQ== +jest-haste-map@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.0.1.tgz#40dcc03c43ac94d25b8618075804d09cd5d49de7" + integrity sha512-J9kBl/EdjmDsvyv7CiyKY5+DsTvVOScenprz/fGqfLg/pm1gdjbwwQ98nW0t+OIt+f+5nAVaElvn/6wP5KO7KA== dependencies: - "@jest/types" "^25.4.0" + "@jest/types" "^26.0.1" + "@types/graceful-fs" "^4.1.2" anymatch "^3.0.3" fb-watchman "^2.0.0" - graceful-fs "^4.2.3" - jest-serializer "^25.2.6" - jest-util "^25.4.0" - jest-worker "^25.4.0" + graceful-fs "^4.2.4" + jest-serializer "^26.0.0" + jest-util "^26.0.1" + jest-worker "^26.0.0" micromatch "^4.0.2" sane "^4.0.3" walker "^1.0.7" @@ -4480,27 +4300,27 @@ jest-haste-map@^25.4.0: optionalDependencies: fsevents "^2.1.2" -jest-jasmine2@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-25.4.0.tgz#3d3d19514022e2326e836c2b66d68b4cb63c5861" - integrity sha512-QccxnozujVKYNEhMQ1vREiz859fPN/XklOzfQjm2j9IGytAkUbSwjFRBtQbHaNZ88cItMpw02JnHGsIdfdpwxQ== +jest-jasmine2@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-26.0.1.tgz#947c40ee816636ba23112af3206d6fa7b23c1c1c" + integrity sha512-ILaRyiWxiXOJ+RWTKupzQWwnPaeXPIoLS5uW41h18varJzd9/7I0QJGqg69fhTT1ev9JpSSo9QtalriUN0oqOg== dependencies: "@babel/traverse" "^7.1.0" - "@jest/environment" "^25.4.0" - "@jest/source-map" "^25.2.6" - "@jest/test-result" "^25.4.0" - "@jest/types" "^25.4.0" - chalk "^3.0.0" + "@jest/environment" "^26.0.1" + "@jest/source-map" "^26.0.0" + "@jest/test-result" "^26.0.1" + "@jest/types" "^26.0.1" + chalk "^4.0.0" co "^4.6.0" - expect "^25.4.0" + expect "^26.0.1" is-generator-fn "^2.0.0" - jest-each "^25.4.0" - jest-matcher-utils "^25.4.0" - jest-message-util "^25.4.0" - jest-runtime "^25.4.0" - jest-snapshot "^25.4.0" - jest-util "^25.4.0" - pretty-format "^25.4.0" + jest-each "^26.0.1" + jest-matcher-utils "^26.0.1" + jest-message-util "^26.0.1" + jest-runtime "^26.0.1" + jest-snapshot "^26.0.1" + jest-util "^26.0.1" + pretty-format "^26.0.1" throat "^5.0.0" jest-junit@^10.0.0: @@ -4514,23 +4334,23 @@ jest-junit@^10.0.0: uuid "^3.3.3" xml "^1.0.1" -jest-leak-detector@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-25.4.0.tgz#cf94a160c78e53d810e7b2f40b5fd7ee263375b3" - integrity sha512-7Y6Bqfv2xWsB+7w44dvZuLs5SQ//fzhETgOGG7Gq3TTGFdYvAgXGwV8z159RFZ6fXiCPm/szQ90CyfVos9JIFQ== +jest-leak-detector@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-26.0.1.tgz#79b19ab3f41170e0a78eb8fa754a116d3447fb8c" + integrity sha512-93FR8tJhaYIWrWsbmVN1pQ9ZNlbgRpfvrnw5LmgLRX0ckOJ8ut/I35CL7awi2ecq6Ca4lL59bEK9hr7nqoHWPA== dependencies: - jest-get-type "^25.2.6" - pretty-format "^25.4.0" + jest-get-type "^26.0.0" + pretty-format "^26.0.1" -jest-matcher-utils@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-25.4.0.tgz#dc3e7aec402a1e567ed80b572b9ad285878895e6" - integrity sha512-yPMdtj7YDgXhnGbc66bowk8AkQ0YwClbbwk3Kzhn5GVDrciiCr27U4NJRbrqXbTdtxjImONITg2LiRIw650k5A== +jest-matcher-utils@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-26.0.1.tgz#12e1fc386fe4f14678f4cc8dbd5ba75a58092911" + integrity sha512-PUMlsLth0Azen8Q2WFTwnSkGh2JZ8FYuwijC8NR47vXKpsrKmA1wWvgcj1CquuVfcYiDEdj985u5Wmg7COEARw== dependencies: - chalk "^3.0.0" - jest-diff "^25.4.0" - jest-get-type "^25.2.6" - pretty-format "^25.4.0" + chalk "^4.0.0" + jest-diff "^26.0.1" + jest-get-type "^26.0.0" + pretty-format "^26.0.1" jest-message-util@^24.8.0: version "24.8.0" @@ -4546,18 +4366,19 @@ jest-message-util@^24.8.0: slash "^2.0.0" stack-utils "^1.0.1" -jest-message-util@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-25.4.0.tgz#2899e8bc43f5317acf8dfdfe89ea237d354fcdab" - integrity sha512-LYY9hRcVGgMeMwmdfh9tTjeux1OjZHMusq/E5f3tJN+dAoVVkJtq5ZUEPIcB7bpxDUt2zjUsrwg0EGgPQ+OhXQ== +jest-message-util@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-26.0.1.tgz#07af1b42fc450b4cc8e90e4c9cef11b33ce9b0ac" + integrity sha512-CbK8uQREZ8umUfo8+zgIfEt+W7HAHjQCoRaNs4WxKGhAYBGwEyvxuK81FXa7VeB9pwDEXeeKOB2qcsNVCAvB7Q== dependencies: "@babel/code-frame" "^7.0.0" - "@jest/types" "^25.4.0" + "@jest/types" "^26.0.1" "@types/stack-utils" "^1.0.1" - chalk "^3.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.4" micromatch "^4.0.2" slash "^3.0.0" - stack-utils "^1.0.1" + stack-utils "^2.0.2" jest-mock@^24.8.0: version "24.8.0" @@ -4566,98 +4387,99 @@ jest-mock@^24.8.0: dependencies: "@jest/types" "^24.8.0" -jest-mock@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-25.4.0.tgz#ded7d64b5328d81d78d2138c825d3a45e30ec8ca" - integrity sha512-MdazSfcYAUjJjuVTTnusLPzE0pE4VXpOUzWdj8sbM+q6abUjm3bATVPXFqTXrxSieR8ocpvQ9v/QaQCftioQFg== +jest-mock@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.0.1.tgz#7fd1517ed4955397cf1620a771dc2d61fad8fd40" + integrity sha512-MpYTBqycuPYSY6xKJognV7Ja46/TeRbAZept987Zp+tuJvMN0YBWyyhG9mXyYQaU3SBI0TUlSaO5L3p49agw7Q== dependencies: - "@jest/types" "^25.4.0" + "@jest/types" "^26.0.1" jest-pnp-resolver@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.1.tgz#ecdae604c077a7fbc70defb6d517c3c1c898923a" integrity sha512-pgFw2tm54fzgYvc/OHrnysABEObZCUNFnhjoRjaVOCN8NYc032/gVjPaHD4Aq6ApkSieWtfKAFQtmDKAmhupnQ== -jest-regex-util@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-25.2.6.tgz#d847d38ba15d2118d3b06390056028d0f2fd3964" - integrity sha512-KQqf7a0NrtCkYmZZzodPftn7fL1cq3GQAFVMn5Hg8uKx/fIenLEobNanUxb7abQ1sjADHBseG/2FGpsv/wr+Qw== +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== -jest-resolve-dependencies@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-25.4.0.tgz#783937544cfc40afcc7c569aa54748c4b3f83f5a" - integrity sha512-A0eoZXx6kLiuG1Ui7wITQPl04HwjLErKIJTt8GR3c7UoDAtzW84JtCrgrJ6Tkw6c6MwHEyAaLk7dEPml5pf48A== +jest-resolve-dependencies@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-26.0.1.tgz#607ba7ccc32151d185a477cff45bf33bce417f0b" + integrity sha512-9d5/RS/ft0vB/qy7jct/qAhzJsr6fRQJyGAFigK3XD4hf9kIbEH5gks4t4Z7kyMRhowU6HWm/o8ILqhaHdSqLw== dependencies: - "@jest/types" "^25.4.0" - jest-regex-util "^25.2.6" - jest-snapshot "^25.4.0" + "@jest/types" "^26.0.1" + jest-regex-util "^26.0.0" + jest-snapshot "^26.0.1" -jest-resolve@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-25.4.0.tgz#6f4540ce0d419c4c720e791e871da32ba4da7a60" - integrity sha512-wOsKqVDFWUiv8BtLMCC6uAJ/pHZkfFgoBTgPtmYlsprAjkxrr2U++ZnB3l5ykBMd2O24lXvf30SMAjJIW6k2aA== +jest-resolve@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-26.0.1.tgz#21d1ee06f9ea270a343a8893051aeed940cde736" + integrity sha512-6jWxk0IKZkPIVTvq6s72RH735P8f9eCJW3IM5CX/SJFeKq1p2cZx0U49wf/SdMlhaB/anann5J2nCJj6HrbezQ== dependencies: - "@jest/types" "^25.4.0" - browser-resolve "^1.11.3" - chalk "^3.0.0" + "@jest/types" "^26.0.1" + chalk "^4.0.0" + graceful-fs "^4.2.4" jest-pnp-resolver "^1.2.1" + jest-util "^26.0.1" read-pkg-up "^7.0.1" - realpath-native "^2.0.0" - resolve "^1.15.1" + resolve "^1.17.0" slash "^3.0.0" -jest-runner@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-25.4.0.tgz#6ca4a3d52e692bbc081228fa68f750012f1f29e5" - integrity sha512-wWQSbVgj2e/1chFdMRKZdvlmA6p1IPujhpLT7TKNtCSl1B0PGBGvJjCaiBal/twaU2yfk8VKezHWexM8IliBfA== +jest-runner@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-26.0.1.tgz#ea03584b7ae4bacfb7e533d680a575a49ae35d50" + integrity sha512-CApm0g81b49Znm4cZekYQK67zY7kkB4umOlI2Dx5CwKAzdgw75EN+ozBHRvxBzwo1ZLYZ07TFxkaPm+1t4d8jA== dependencies: - "@jest/console" "^25.4.0" - "@jest/environment" "^25.4.0" - "@jest/test-result" "^25.4.0" - "@jest/types" "^25.4.0" - chalk "^3.0.0" + "@jest/console" "^26.0.1" + "@jest/environment" "^26.0.1" + "@jest/test-result" "^26.0.1" + "@jest/types" "^26.0.1" + chalk "^4.0.0" exit "^0.1.2" - graceful-fs "^4.2.3" - jest-config "^25.4.0" - jest-docblock "^25.3.0" - jest-haste-map "^25.4.0" - jest-jasmine2 "^25.4.0" - jest-leak-detector "^25.4.0" - jest-message-util "^25.4.0" - jest-resolve "^25.4.0" - jest-runtime "^25.4.0" - jest-util "^25.4.0" - jest-worker "^25.4.0" + graceful-fs "^4.2.4" + jest-config "^26.0.1" + jest-docblock "^26.0.0" + jest-haste-map "^26.0.1" + jest-jasmine2 "^26.0.1" + jest-leak-detector "^26.0.1" + jest-message-util "^26.0.1" + jest-resolve "^26.0.1" + jest-runtime "^26.0.1" + jest-util "^26.0.1" + jest-worker "^26.0.0" source-map-support "^0.5.6" throat "^5.0.0" -jest-runtime@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-25.4.0.tgz#1e5227a9e2159d26ae27dcd426ca6bc041983439" - integrity sha512-lgNJlCDULtXu9FumnwCyWlOub8iytijwsPNa30BKrSNtgoT6NUMXOPrZvsH06U6v0wgD/Igwz13nKA2wEKU2VA== - dependencies: - "@jest/console" "^25.4.0" - "@jest/environment" "^25.4.0" - "@jest/source-map" "^25.2.6" - "@jest/test-result" "^25.4.0" - "@jest/transform" "^25.4.0" - "@jest/types" "^25.4.0" +jest-runtime@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-26.0.1.tgz#a121a6321235987d294168e282d52b364d7d3f89" + integrity sha512-Ci2QhYFmANg5qaXWf78T2Pfo6GtmIBn2rRaLnklRyEucmPccmCKvS9JPljcmtVamsdMmkyNkVFb9pBTD6si9Lw== + dependencies: + "@jest/console" "^26.0.1" + "@jest/environment" "^26.0.1" + "@jest/fake-timers" "^26.0.1" + "@jest/globals" "^26.0.1" + "@jest/source-map" "^26.0.0" + "@jest/test-result" "^26.0.1" + "@jest/transform" "^26.0.1" + "@jest/types" "^26.0.1" "@types/yargs" "^15.0.0" - chalk "^3.0.0" + chalk "^4.0.0" collect-v8-coverage "^1.0.0" exit "^0.1.2" glob "^7.1.3" - graceful-fs "^4.2.3" - jest-config "^25.4.0" - jest-haste-map "^25.4.0" - jest-message-util "^25.4.0" - jest-mock "^25.4.0" - jest-regex-util "^25.2.6" - jest-resolve "^25.4.0" - jest-snapshot "^25.4.0" - jest-util "^25.4.0" - jest-validate "^25.4.0" - realpath-native "^2.0.0" + graceful-fs "^4.2.4" + jest-config "^26.0.1" + jest-haste-map "^26.0.1" + jest-message-util "^26.0.1" + jest-mock "^26.0.1" + jest-regex-util "^26.0.0" + jest-resolve "^26.0.1" + jest-snapshot "^26.0.1" + jest-util "^26.0.1" + jest-validate "^26.0.1" slash "^3.0.0" strip-bom "^4.0.0" yargs "^15.3.1" @@ -4667,30 +4489,33 @@ jest-serializer@^24.4.0: resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-24.4.0.tgz#f70c5918c8ea9235ccb1276d232e459080588db3" integrity sha512-k//0DtglVstc1fv+GY/VHDIjrtNjdYvYjMlbLUed4kxrE92sIUewOi5Hj3vrpB8CXfkJntRPDRjCrCvUhBdL8Q== -jest-serializer@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-25.2.6.tgz#3bb4cc14fe0d8358489dbbefbb8a4e708ce039b7" - integrity sha512-RMVCfZsezQS2Ww4kB5HJTMaMJ0asmC0BHlnobQC6yEtxiFKIxohFA4QSXSabKwSggaNkqxn6Z2VwdFCjhUWuiQ== +jest-serializer@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.0.0.tgz#f6c521ddb976943b93e662c0d4d79245abec72a3" + integrity sha512-sQGXLdEGWFAE4wIJ2ZaIDb+ikETlUirEOBsLXdoBbeLhTHkZUJwgk3+M8eyFizhM6le43PDCCKPA1hzkSDo4cQ== + dependencies: + graceful-fs "^4.2.4" -jest-snapshot@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-25.4.0.tgz#e0b26375e2101413fd2ccb4278a5711b1922545c" - integrity sha512-J4CJ0X2SaGheYRZdLz9CRHn9jUknVmlks4UBeu270hPAvdsauFXOhx9SQP2JtRzhnR3cvro/9N9KP83/uvFfRg== +jest-snapshot@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-26.0.1.tgz#1baa942bd83d47b837a84af7fcf5fd4a236da399" + integrity sha512-jxd+cF7+LL+a80qh6TAnTLUZHyQoWwEHSUFJjkw35u3Gx+BZUNuXhYvDqHXr62UQPnWo2P6fvQlLjsU93UKyxA== dependencies: "@babel/types" "^7.0.0" - "@jest/types" "^25.4.0" - "@types/prettier" "^1.19.0" - chalk "^3.0.0" - expect "^25.4.0" - jest-diff "^25.4.0" - jest-get-type "^25.2.6" - jest-matcher-utils "^25.4.0" - jest-message-util "^25.4.0" - jest-resolve "^25.4.0" + "@jest/types" "^26.0.1" + "@types/prettier" "^2.0.0" + chalk "^4.0.0" + expect "^26.0.1" + graceful-fs "^4.2.4" + jest-diff "^26.0.1" + jest-get-type "^26.0.0" + jest-matcher-utils "^26.0.1" + jest-message-util "^26.0.1" + jest-resolve "^26.0.1" make-dir "^3.0.0" natural-compare "^1.4.0" - pretty-format "^25.4.0" - semver "^6.3.0" + pretty-format "^26.0.1" + semver "^7.3.2" jest-util@^24.8.0: version "24.8.0" @@ -4710,13 +4535,14 @@ jest-util@^24.8.0: slash "^2.0.0" source-map "^0.6.0" -jest-util@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-25.4.0.tgz#6a093d09d86d2b41ef583e5fe7dd3976346e1acd" - integrity sha512-WSZD59sBtAUjLv1hMeKbNZXmMcrLRWcYqpO8Dz8b4CeCTZpfNQw2q9uwrYAD+BbJoLJlu4ezVPwtAmM/9/SlZA== +jest-util@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.0.1.tgz#72c4c51177b695fdd795ca072a6f94e3d7cef00a" + integrity sha512-byQ3n7ad1BO/WyFkYvlWQHTsomB6GIewBh8tlGtusiylAlaxQ1UpS0XYH0ngOyhZuHVLN79Qvl6/pMiDMSSG1g== dependencies: - "@jest/types" "^25.4.0" - chalk "^3.0.0" + "@jest/types" "^26.0.1" + chalk "^4.0.0" + graceful-fs "^4.2.4" is-ci "^2.0.0" make-dir "^3.0.0" @@ -4744,29 +4570,29 @@ jest-validate@^24.9.0: leven "^3.1.0" pretty-format "^24.9.0" -jest-validate@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-25.4.0.tgz#2e177a93b716a137110eaf2768f3d9095abd3f38" - integrity sha512-hvjmes/EFVJSoeP1yOl8qR8mAtMR3ToBkZeXrD/ZS9VxRyWDqQ/E1C5ucMTeSmEOGLipvdlyipiGbHJ+R1MQ0g== +jest-validate@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-26.0.1.tgz#a62987e1da5b7f724130f904725e22f4e5b2e23c" + integrity sha512-u0xRc+rbmov/VqXnX3DlkxD74rHI/CfS5xaV2VpeaVySjbb1JioNVOyly5b56q2l9ZKe7bVG5qWmjfctkQb0bA== dependencies: - "@jest/types" "^25.4.0" - camelcase "^5.3.1" - chalk "^3.0.0" - jest-get-type "^25.2.6" + "@jest/types" "^26.0.1" + camelcase "^6.0.0" + chalk "^4.0.0" + jest-get-type "^26.0.0" leven "^3.1.0" - pretty-format "^25.4.0" + pretty-format "^26.0.1" -jest-watcher@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-25.4.0.tgz#63ec0cd5c83bb9c9d1ac95be7558dd61c995ff05" - integrity sha512-36IUfOSRELsKLB7k25j/wutx0aVuHFN6wO94gPNjQtQqFPa2rkOymmx9rM5EzbF3XBZZ2oqD9xbRVoYa2w86gw== +jest-watcher@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-26.0.1.tgz#5b5e3ebbdf10c240e22a98af66d645631afda770" + integrity sha512-pdZPydsS8475f89kGswaNsN3rhP6lnC3/QDCppP7bg1L9JQz7oU9Mb/5xPETk1RHDCWeqmVC47M4K5RR7ejxFw== dependencies: - "@jest/test-result" "^25.4.0" - "@jest/types" "^25.4.0" + "@jest/test-result" "^26.0.1" + "@jest/types" "^26.0.1" ansi-escapes "^4.2.1" - chalk "^3.0.0" - jest-util "^25.4.0" - string-length "^3.1.0" + chalk "^4.0.0" + jest-util "^26.0.1" + string-length "^4.0.1" jest-worker@^24.6.0: version "24.6.0" @@ -4776,22 +4602,22 @@ jest-worker@^24.6.0: merge-stream "^1.0.1" supports-color "^6.1.0" -jest-worker@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-25.4.0.tgz#ee0e2ceee5a36ecddf5172d6d7e0ab00df157384" - integrity sha512-ghAs/1FtfYpMmYQ0AHqxV62XPvKdUDIBBApMZfly+E9JEmYh2K45G0R5dWxx986RN12pRCxsViwQVtGl+N4whw== +jest-worker@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.0.0.tgz#4920c7714f0a96c6412464718d0c58a3df3fb066" + integrity sha512-pPaYa2+JnwmiZjK9x7p9BoZht+47ecFCDFA/CJxspHzeDvQcfVBLWzCiWyo+EGrSiQMWZtCFo9iSvMZnAAo8vw== dependencies: merge-stream "^2.0.0" supports-color "^7.0.0" -jest@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/jest/-/jest-25.4.0.tgz#fb96892c5c4e4a6b9bcb12068849cddf4c5f8cc7" - integrity sha512-XWipOheGB4wai5JfCYXd6vwsWNwM/dirjRoZgAa7H2wd8ODWbli2AiKjqG8AYhyx+8+5FBEdpO92VhGlBydzbw== +jest@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-26.0.1.tgz#5c51a2e58dff7525b65f169721767173bf832694" + integrity sha512-29Q54kn5Bm7ZGKIuH2JRmnKl85YRigp0o0asTc6Sb6l2ch1DCXIeZTLLFy9ultJvhkTqbswF5DEx4+RlkmCxWg== dependencies: - "@jest/core" "^25.4.0" + "@jest/core" "^26.0.1" import-local "^3.0.2" - jest-cli "^25.4.0" + jest-cli "^26.0.1" jetifier@^1.6.2: version "1.6.4" @@ -4834,16 +4660,17 @@ jsc-android@^245459.0.0: resolved "https://registry.yarnpkg.com/jsc-android/-/jsc-android-245459.0.0.tgz#e584258dd0b04c9159a27fb104cd5d491fd202c9" integrity sha512-wkjURqwaB1daNkDi2OYYbsLnIdC/lUM2nPXQKRs5pqEU9chDg435bjvo+LSaHotDENygHQDHe+ntUkkw2gwMtg== -jscodeshift@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.7.0.tgz#4eee7506fd4fdacbd80340287d61575af991fdab" - integrity sha512-Kt6rpTa1HVhAWagD6J0y6qxxqRmDgkFvczerLgOsDNSGoUZSmq2CO1vFRcda9OV1BaZKSHCIh+VREPts5tB/Ig== +jscodeshift@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.9.0.tgz#672025658e868a63e24d6a6f4c44af9edb6e55f3" + integrity sha512-SUeXq8dJzj5LR8uy71axgG3bmiHoC0IdHy7n89SqKzkzBWpAds5F9IIGE+lqUSZX9J0ZfEzN8fXWIqQV0dIp2w== dependencies: "@babel/core" "^7.1.6" "@babel/parser" "^7.1.6" "@babel/plugin-proposal-class-properties" "^7.1.0" - "@babel/plugin-proposal-object-rest-spread" "^7.0.0" - "@babel/preset-env" "^7.1.6" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.1.0" + "@babel/plugin-proposal-optional-chaining" "^7.1.0" + "@babel/plugin-transform-modules-commonjs" "^7.1.0" "@babel/preset-flow" "^7.0.0" "@babel/preset-typescript" "^7.1.0" "@babel/register" "^7.0.0" @@ -4858,36 +4685,36 @@ jscodeshift@^0.7.0: temp "^0.8.1" write-file-atomic "^2.3.0" -jsdom@^15.2.1: - version "15.2.1" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-15.2.1.tgz#d2feb1aef7183f86be521b8c6833ff5296d07ec5" - integrity sha512-fAl1W0/7T2G5vURSyxBzrJ1LSdQn6Tr5UX/xD4PXDx/PDgwygedfW6El/KIj3xJ7FU61TTYnc/l/B7P49Eqt6g== - dependencies: - abab "^2.0.0" - acorn "^7.1.0" - acorn-globals "^4.3.2" - array-equal "^1.0.0" - cssom "^0.4.1" - cssstyle "^2.0.0" - data-urls "^1.1.0" - domexception "^1.0.1" - escodegen "^1.11.1" - html-encoding-sniffer "^1.0.2" +jsdom@^16.2.2: + version "16.2.2" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.2.2.tgz#76f2f7541646beb46a938f5dc476b88705bedf2b" + integrity sha512-pDFQbcYtKBHxRaP55zGXCJWgFHkDAYbKcsXEK/3Icu9nKYZkutUXfLBwbD+09XDutkYSHcgfQLZ0qvpAAm9mvg== + dependencies: + abab "^2.0.3" + acorn "^7.1.1" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.2.0" + data-urls "^2.0.0" + decimal.js "^10.2.0" + domexception "^2.0.1" + escodegen "^1.14.1" + html-encoding-sniffer "^2.0.1" + is-potential-custom-element-name "^1.0.0" nwsapi "^2.2.0" - parse5 "5.1.0" - pn "^1.1.0" - request "^2.88.0" - request-promise-native "^1.0.7" - saxes "^3.1.9" - symbol-tree "^3.2.2" + parse5 "5.1.1" + request "^2.88.2" + request-promise-native "^1.0.8" + saxes "^5.0.0" + symbol-tree "^3.2.4" tough-cookie "^3.0.1" - w3c-hr-time "^1.0.1" - w3c-xmlserializer "^1.1.2" - webidl-conversions "^4.0.2" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.0.0" whatwg-encoding "^1.0.5" whatwg-mimetype "^2.3.0" - whatwg-url "^7.0.0" - ws "^7.0.0" + whatwg-url "^8.0.0" + ws "^7.2.3" xml-name-validator "^3.0.0" jsesc@^2.5.1: @@ -5043,13 +4870,6 @@ leven@^3.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== -levenary@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" - integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== - dependencies: - leven "^3.1.0" - levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -5063,14 +4883,6 @@ lines-and-columns@^1.1.6: resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= -locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha1-K1aLJl7slExtnA3pw9u7ygNUzY4= - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -5127,13 +4939,6 @@ logkitty@^0.7.1: dayjs "^1.8.15" yargs "^15.1.0" -lolex@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/lolex/-/lolex-5.1.2.tgz#953694d098ce7c07bc5ed6d0e42bc6c0c6d5a367" - integrity sha512-h4hmjAvHTmd+25JSwrtTIuwbKdwg5NzZVRMLn9saij4SZaepCrTCxPr35H/3bjwfMJtN+t3CX8672UIkglz28A== - dependencies: - "@sinonjs/commons" "^1.7.0" - loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.3.1, loose-envify@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" @@ -5788,16 +5593,17 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" - integrity sha512-SVfQ/wMw+DesunOm5cKqr6yDcvUTDl/yc97ybGHMrteNEY6oekXpNpS3lZwgLlwz0FLgHoiW28ZpmBHUDg37cw== +node-notifier@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-7.0.0.tgz#513bc42f2aa3a49fce1980a7ff375957c71f718a" + integrity sha512-y8ThJESxsHcak81PGpzWwQKxzk+5YtP3IxR8AYdpXQ1IB6FmcVzFdZXrkPin49F/DKUCfeeiziB8ptY9npzGuA== dependencies: growly "^1.3.0" is-wsl "^2.1.1" - semver "^6.3.0" + semver "^7.2.1" shellwords "^0.1.1" - which "^1.3.1" + uuid "^7.0.3" + which "^2.0.2" node-pre-gyp@^0.10.0: version "0.10.3" @@ -5815,11 +5621,6 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.53: - version "1.1.53" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" - integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== - node-stream-zip@^1.9.1: version "1.11.3" resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.11.3.tgz#223892620b4889bce9782b256a76682631c507be" @@ -6096,23 +5897,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= -p-finally@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-2.0.1.tgz#bd6fcaa9c559a096b680806f4d657b3f0f240561" - integrity sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw== - p-is-promise@^1.1.0: version "1.1.0" resolved "http://registry.npmjs.org/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= -p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - p-limit@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.0.0.tgz#e624ed54ee8c460a778b3c9f3670496ff8a57aec" @@ -6127,13 +5916,6 @@ p-limit@^2.2.0: dependencies: p-try "^2.0.0" -p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha1-IKAQOyIqcMj9OcwuWAaA893l7EM= - dependencies: - p-limit "^1.1.0" - p-locate@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" @@ -6148,11 +5930,6 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" -p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M= - p-try@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.0.0.tgz#85080bb87c64688fa47996fe8f7dfbe8211760b1" @@ -6176,10 +5953,10 @@ parse-json@^5.0.0: json-parse-better-errors "^1.0.1" lines-and-columns "^1.1.6" -parse5@5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.0.tgz#c59341c9723f414c452975564c7c00a68d58acd2" - integrity sha512-fxNG2sQjHvlVAYmzBZS9YlDp6PTSSDwa98vkD4QgVDDCAo84z5X1t5XyJQ62ImdLXx5NdIIfihey6xpum9/gRQ== +parse5@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== parseurl@~1.3.2: version "1.3.2" @@ -6281,13 +6058,6 @@ pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - plist@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" @@ -6313,11 +6083,6 @@ pluralize@^7.0.0: resolved "https://registry.yarnpkg.com/pluralize/-/pluralize-7.0.0.tgz#298b89df8b93b0221dbf421ad2b1b1ea23fc6777" integrity sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow== -pn@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" - integrity sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA== - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -6373,12 +6138,12 @@ pretty-format@^25.2.0: ansi-styles "^4.0.0" react-is "^16.12.0" -pretty-format@^25.4.0: - version "25.4.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.4.0.tgz#c58801bb5c4926ff4a677fe43f9b8b99812c7830" - integrity sha512-PI/2dpGjXK5HyXexLPZU/jw5T9Q6S1YVXxxVxco+LIqzUFHXIbKZKdUVt7GcX7QUCr31+3fzhi4gN4/wUYPVxQ== +pretty-format@^26.0.1: + version "26.0.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.0.1.tgz#a4fe54fe428ad2fd3413ca6bbd1ec8c2e277e197" + integrity sha512-SWxz6MbupT3ZSlL0Po4WF/KujhQaVehijR2blyRDCzk9e45EaYMVhMBn49fnRuHxtkSpXTes1GxNpVmH86Bxfw== dependencies: - "@jest/types" "^25.4.0" + "@jest/types" "^26.0.1" ansi-regex "^5.0.0" ansi-styles "^4.0.0" react-is "^16.12.0" @@ -6582,11 +6347,6 @@ readable-stream@^2.0.1, readable-stream@^2.0.6, readable-stream@^2.1.5, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -realpath-native@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-2.0.0.tgz#7377ac429b6e1fd599dc38d08ed942d0d7beb866" - integrity sha512-v1SEYUOXXdbBZK8ZuNgO4TBjamPsiSgcFr0aP+tEKpQZK8vooEUqV6nm6Cv502mX4NF2EfsnVqtNAHG+/6Ur1Q== - recast@^0.18.1: version "0.18.7" resolved "https://registry.yarnpkg.com/recast/-/recast-0.18.7.tgz#56338a6d803c8c3b9113344440dc70d13c8a1ef7" @@ -6700,7 +6460,7 @@ request-promise-core@1.1.3: dependencies: lodash "^4.17.15" -request-promise-native@^1.0.7: +request-promise-native@^1.0.8: version "1.0.8" resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.8.tgz#a455b960b826e44e2bf8999af64dff2bfe58cb36" integrity sha512-dapwLGqkHtwL5AEbfenuzjTYg35Jd6KPytsC2/TLkVMz8rm+tNt72MGUWT1RP/aYawMpN6HqbNGBQaRcBtjQMQ== @@ -6735,7 +6495,7 @@ request@^2.85.0: tunnel-agent "^0.6.0" uuid "^3.3.2" -request@^2.88.0: +request@^2.88.2: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -6806,18 +6566,20 @@ resolve-url@^0.2.1: resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= -resolve@1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" - integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= - -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1, resolve@^1.9.0: version "1.15.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== dependencies: path-parse "^1.0.6" +resolve@^1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== + dependencies: + path-parse "^1.0.6" + restore-cursor@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" @@ -6949,12 +6711,12 @@ sax@^1.2.1, sax@^1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -saxes@^3.1.9: - version "3.1.11" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-3.1.11.tgz#d59d1fd332ec92ad98a2e0b2ee644702384b1c5b" - integrity sha512-Ydydq3zC+WYDJK1+gRxRapLIED9PWeSuuS41wqyoRmzvhhh9nc+QQrVMKJYzJFULazeGhzSV0QleN2wD3boh2g== +saxes@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== dependencies: - xmlchars "^2.1.1" + xmlchars "^2.2.0" scheduler@0.19.1, scheduler@^0.19.1: version "0.19.1" @@ -6969,11 +6731,6 @@ scheduler@0.19.1, scheduler@^0.19.1: resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== -semver@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - semver@^5.1.0, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1: version "5.6.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004" @@ -6984,6 +6741,11 @@ semver@^6.0.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== +semver@^7.2.1, semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" @@ -7298,6 +7060,13 @@ stack-utils@^1.0.1: resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" integrity sha1-1PM6tU6OOHeLDKXP07OvsS22hiA= +stack-utils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.2.tgz#5cf48b4557becb4638d0bc4f21d23f5d19586593" + integrity sha512-0H7QK2ECz3fyZMzQ8rH0j2ykpfbnd20BFtfg/SqVC2+sCTtcw0aDTGB7dk+de4U4uUeuz6nOtJcrkFFLG1B0Rg== + dependencies: + escape-string-regexp "^2.0.0" + stacktrace-parser@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.4.tgz#01397922e5f62ecf30845522c95c4fe1d25e7d4e" @@ -7336,13 +7105,13 @@ stream-buffers@~2.2.0: resolved "https://registry.yarnpkg.com/stream-buffers/-/stream-buffers-2.2.0.tgz#91d5f5130d1cef96dcfa7f726945188741d09ee4" integrity sha1-kdX1Ew0c75bc+n9yaUUYh0HQnuQ= -string-length@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-3.1.0.tgz#107ef8c23456e187a8abd4a61162ff4ac6e25837" - integrity sha512-Ttp5YvkGm5v9Ijagtaz1BnN+k9ObpvS0eIBblPMp2YWL8FBmi9qblQ9fexc2k/CXFgrTIteU3jAw3payCnwSTA== +string-length@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.1.tgz#4a973bf31ef77c4edbceadd6af2611996985f8a1" + integrity sha512-PKyXUd0LK0ePjSOnWn34V2uD6acUWev9uy0Ft05k0E8xRW+SKcA0F7eMr7h5xlzfn+4O3N+55rduYyet3Jk+jw== dependencies: - astral-regex "^1.0.0" - strip-ansi "^5.2.0" + char-regex "^1.0.2" + strip-ansi "^6.0.0" string-width@^1.0.1: version "1.0.2" @@ -7496,10 +7265,10 @@ symbol-observable@1.0.1: resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" integrity sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ= -symbol-tree@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" - integrity sha1-rifbOPZgp64uHDt9G8KQgZuFGeY= +symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== table@^4.0.3: version "4.0.3" @@ -7691,12 +7460,12 @@ tough-cookie@~2.4.3: psl "^1.1.24" punycode "^1.4.1" -tr46@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" - integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= +tr46@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.0.2.tgz#03273586def1595ae08fedb38d7733cee91d2479" + integrity sha512-3n1qG+/5kg+jrbTzwAykB5yRYtQCTqOGKq5U5PE3b0a1/mzo6snDhjGS0zJVJunO0NrT3Dg1MLy5TjWP/UJppg== dependencies: - punycode "^2.1.0" + punycode "^2.1.1" truncate-utf8-bytes@^1.0.0: version "1.0.2" @@ -7877,6 +7646,11 @@ uuid@^3.3.3: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== +uuid@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + v8-to-istanbul@^4.1.3: version "4.1.3" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-4.1.3.tgz#22fe35709a64955f49a08a7c7c959f6520ad6f20" @@ -7918,20 +7692,18 @@ vlq@^1.0.0: resolved "https://registry.yarnpkg.com/vlq/-/vlq-1.0.1.tgz#c003f6e7c0b4c1edd623fd6ee50bbc0d6a1de468" integrity sha512-gQpnTgkubC6hQgdIcRdYGDSDc+SaujOdyesZQMv6JlfQee/9Mp0Qhnys6WxDWvQnL5WZdT7o2Ul187aSt0Rq+w== -w3c-hr-time@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" - integrity sha1-gqwr/2PZUOqeMYmlimViX+3xkEU= +w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== dependencies: - browser-process-hrtime "^0.1.2" + browser-process-hrtime "^1.0.0" -w3c-xmlserializer@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-1.1.2.tgz#30485ca7d70a6fd052420a3d12fd90e6339ce794" - integrity sha512-p10l/ayESzrBMYWRID6xbuCKh2Fp77+sA0doRuGn4tTIMrrZVeqfpKjXHY+oDh3K4nLdPgNwMTVP6Vp4pvqbNg== +w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== dependencies: - domexception "^1.0.1" - webidl-conversions "^4.0.2" xml-name-validator "^3.0.0" walker@^1.0.7, walker@~1.0.5: @@ -7948,12 +7720,17 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" -webidl-conversions@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" - integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== +webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== -whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.5: +webidl-conversions@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + +whatwg-encoding@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== @@ -7965,19 +7742,19 @@ whatwg-fetch@>=0.10.0, whatwg-fetch@^3.0.0: resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== -whatwg-mimetype@^2.2.0, whatwg-mimetype@^2.3.0: +whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== -whatwg-url@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" - integrity sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ== +whatwg-url@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.0.0.tgz#37f256cb746398e19b107bd6ef820b4ae2d15871" + integrity sha512-41ou2Dugpij8/LPO5Pq64K5q++MnRCBpEHvQr26/mArEKTkCV5aoXIqyhuYtE0pkqScXwhf2JP57rkRTYM29lQ== dependencies: lodash.sortby "^4.7.0" - tr46 "^1.0.1" - webidl-conversions "^4.0.2" + tr46 "^2.0.0" + webidl-conversions "^5.0.0" which-module@^2.0.0: version "2.0.0" @@ -8107,10 +7884,10 @@ ws@^7: dependencies: async-limiter "^1.0.0" -ws@^7.0.0: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== +ws@^7.2.3: + version "7.2.5" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.5.tgz#abb1370d4626a5a9cd79d8de404aa18b3465d10d" + integrity sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA== xcode@^2.0.0: version "2.0.0" @@ -8135,7 +7912,7 @@ xmlbuilder@^9.0.7: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-9.0.7.tgz#132ee63d2ec5565c557e20f4c22df9aca686b10d" integrity sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0= -xmlchars@^2.1.1: +xmlchars@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==