mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
125
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6bba507895 | ||
|
|
260a9c720e | ||
|
|
da1d82bcb4 | ||
|
|
1df92c6948 | ||
|
|
124547ef26 | ||
|
|
7b1441730b | ||
|
|
5339e95cb9 | ||
|
|
62364d00ca | ||
|
|
322f721c4a | ||
|
|
471cc514a8 | ||
|
|
ab822c41f1 | ||
|
|
f1c33b9e15 | ||
|
|
205623cbe8 | ||
|
|
62d992019e | ||
|
|
ff991aa15b | ||
|
|
6d8868b2d8 | ||
|
|
2ddef56902 | ||
|
|
d89542e474 | ||
|
|
99c097917b | ||
|
|
34f3794f18 | ||
|
|
ea11efa262 | ||
|
|
e3a5fbe72f | ||
|
|
b177489eb3 | ||
|
|
616fca2fd2 | ||
|
|
279fb52e03 | ||
|
|
b5280bbc93 | ||
|
|
9a469c433d | ||
|
|
fdd8002f19 | ||
|
|
fb653a13bc | ||
|
|
49dd38f133 | ||
|
|
fb0e88beb9 | ||
|
|
c56375994c | ||
|
|
69ce989307 | ||
|
|
02a388f050 | ||
|
|
ef29c9b608 | ||
|
|
9bcc5e0373 | ||
|
|
11473c388e | ||
|
|
3f1c55ba5b | ||
|
|
35fa47b382 | ||
|
|
59407a4d34 | ||
|
|
54e666205b | ||
|
|
f5ebb692ab | ||
|
|
72c940b384 | ||
|
|
93bb2d6fa8 | ||
|
|
866021b58c | ||
|
|
c4b094fd24 | ||
|
|
917e97b996 | ||
|
|
fe8f0fb09f | ||
|
|
37790e4507 | ||
|
|
ebf746b1f9 | ||
|
|
0c2f55d05f | ||
|
|
e2645a59f6 | ||
|
|
b9c297537a | ||
|
|
13a2b117be | ||
|
|
2de4cf03cf | ||
|
|
7b53a244cd | ||
|
|
b03f536279 | ||
|
|
764f584615 | ||
|
|
75d5679701 | ||
|
|
73e55334b0 | ||
|
|
9fd764388a | ||
|
|
a54ba33305 | ||
|
|
e33633644c | ||
|
|
6a8c38eef2 | ||
|
|
eaa32f9f65 | ||
|
|
c401334e04 | ||
|
|
f0ffd2291c | ||
|
|
ad582f5e8a | ||
|
|
ec0049b008 | ||
|
|
047a149279 | ||
|
|
b15199f195 | ||
|
|
2483bc089a | ||
|
|
98e5134a4f | ||
|
|
6d50f7e1f0 | ||
|
|
521c712bfd | ||
|
|
2b3f6de630 | ||
|
|
53da91c4e1 | ||
|
|
5132211228 | ||
|
|
7fc33cc15a | ||
|
|
e044a71f7f | ||
|
|
a168c55ba0 | ||
|
|
a22ceecc84 | ||
|
|
05dcebc211 | ||
|
|
97782c247b | ||
|
|
7a014449d6 | ||
|
|
b640f06e4b | ||
|
|
5367459233 | ||
|
|
0b4b7774e2 | ||
|
|
1aabd099b1 | ||
|
|
1518f838b7 | ||
|
|
6d3b8a2ce8 | ||
|
|
c666fda92c | ||
|
|
04990df7a6 | ||
|
|
33ddb001d8 | ||
|
|
6a87015a10 | ||
|
|
9424d2c85c | ||
|
|
a0ae1fb525 | ||
|
|
d077bdf253 | ||
|
|
120b988229 | ||
|
|
6450bc6166 | ||
|
|
23cc0568a0 | ||
|
|
2176173dcc | ||
|
|
7c7ba1babd | ||
|
|
c3e3a19c9e | ||
|
|
ba69e7dab2 | ||
|
|
91fdd998d3 | ||
|
|
64788cc9fe | ||
|
|
0fd776d889 | ||
|
|
1c146bd420 | ||
|
|
a8bb3d3f20 | ||
|
|
5fc88e95b5 | ||
|
|
70daa6e728 | ||
|
|
e7461eea11 | ||
|
|
bf34be1eca | ||
|
|
b8b3f2f4e8 | ||
|
|
1ab3f58f43 | ||
|
|
d9280e14c3 | ||
|
|
fc06d9c6dd | ||
|
|
d07fae9b23 | ||
|
|
afd76f69c7 | ||
|
|
c40d270fdc | ||
|
|
eb6767813a | ||
|
|
ccde88f4b0 | ||
|
|
c0127265a1 | ||
|
|
8c682ddd59 |
@@ -48,7 +48,7 @@ references:
|
||||
|
||||
cache_keys:
|
||||
buck_cache_key: &buck_cache_key v3-buck-v2019.01.10.01-{{ checksum "scripts/circleci/buck_fetch.sh" }}}
|
||||
checkout_cache_key: &checkout_cache_key v1-checkout
|
||||
checkout_cache_key: &checkout_cache_key v2-checkout
|
||||
gems_cache_key: &gems_cache_key v1-gems-{{ checksum "Gemfile.lock" }}
|
||||
gradle_cache_key: &gradle_cache_key v1-gradle-{{ checksum "gradle/wrapper/gradle-wrapper.properties" }}-{{ checksum "ReactAndroid/gradle.properties" }}
|
||||
hermes_cache_key: &hermes_cache_key v1-hermes-{{ .Environment.CIRCLE_JOB }}-{{ checksum "/tmp/hermes/hermesversion" }}
|
||||
@@ -972,6 +972,7 @@ jobs:
|
||||
mkdir -p /tmp/hermes/osx-bin
|
||||
mkdir -p ~/react-native/sdks/hermes
|
||||
cp -r $HERMES_WS_DIR/hermes/* ~/react-native/sdks/hermes/.
|
||||
cp -r ~/react-native/sdks/hermes-engine/utils/. ~/react-native/sdks/hermes/.
|
||||
- run:
|
||||
name: Install dependencies
|
||||
command: |
|
||||
@@ -1112,7 +1113,7 @@ jobs:
|
||||
- run_yarn
|
||||
- add_ssh_keys:
|
||||
fingerprints:
|
||||
- "1c:98:e0:3a:52:79:95:29:12:cd:b4:87:5b:41:e2:bb"
|
||||
- "1f:c7:61:c4:e2:ff:77:e3:cc:ca:a7:34:c2:79:e3:3c"
|
||||
- run:
|
||||
name: "Set new react-native version and commit changes"
|
||||
command: |
|
||||
@@ -1215,7 +1216,7 @@ jobs:
|
||||
command: |
|
||||
curl -X POST https://api.github.com/repos/react-native-community/rn-diff-purge/dispatches \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-u "$PAT_USERNAME:$PAT_TOKEN" \
|
||||
-H "Authorization: Bearer $REACT_NATIVE_BOT_GITHUB_TOKEN" \
|
||||
-d "{\"event_type\": \"publish\", \"client_payload\": { \"version\": \"${CIRCLE_TAG:1}\" }}"
|
||||
- run:
|
||||
name: Install dependencies
|
||||
|
||||
@@ -97,6 +97,8 @@ package-lock.json
|
||||
# Ruby Gems (Bundler)
|
||||
/vendor
|
||||
/template/vendor
|
||||
.ruby-version
|
||||
/**/.ruby-version
|
||||
|
||||
# iOS / CocoaPods
|
||||
/template/ios/build/
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
2.7.5
|
||||
@@ -1,6 +1,6 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby '2.7.5'
|
||||
ruby '>= 2.6.10'
|
||||
|
||||
gem 'cocoapods', '~> 1.11', '>= 1.11.2'
|
||||
gem 'cocoapods', '>= 1.11.3'
|
||||
|
||||
+22
-24
@@ -1,30 +1,29 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.5)
|
||||
CFPropertyList (3.0.6)
|
||||
rexml
|
||||
activesupport (6.1.5)
|
||||
activesupport (7.0.4.3)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
zeitwerk (~> 2.3)
|
||||
addressable (2.8.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
addressable (2.8.4)
|
||||
public_suffix (>= 2.0.2, < 6.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.11.3)
|
||||
cocoapods (1.12.1)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.11.3)
|
||||
cocoapods-core (= 1.12.1)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 1.4.0, < 2.0)
|
||||
cocoapods-downloader (>= 1.6.0, < 2.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.4.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.6.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
@@ -32,10 +31,10 @@ GEM
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 1.0, < 3.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.21.0, < 2.0)
|
||||
cocoapods-core (1.11.3)
|
||||
activesupport (>= 5.0, < 7)
|
||||
cocoapods-core (1.12.1)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
@@ -45,7 +44,7 @@ GEM
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (1.6.1)
|
||||
cocoapods-downloader (1.6.3)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
@@ -54,47 +53,46 @@ GEM
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.1.10)
|
||||
concurrent-ruby (1.2.2)
|
||||
escape (0.0.4)
|
||||
ethon (0.15.0)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.15.5)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.10.0)
|
||||
i18n (1.12.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.6.1)
|
||||
minitest (5.15.0)
|
||||
json (2.6.3)
|
||||
minitest (5.18.0)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
public_suffix (4.0.6)
|
||||
public_suffix (4.0.7)
|
||||
rexml (3.2.5)
|
||||
ruby-macho (2.5.1)
|
||||
typhoeus (1.4.0)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.4)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.21.0)
|
||||
xcodeproj (1.22.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
zeitwerk (2.5.4)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (~> 1.11, >= 1.11.2)
|
||||
cocoapods (>= 1.11.3)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 2.7.5p203
|
||||
|
||||
BUNDLED WITH
|
||||
2.3.10
|
||||
2.3.11
|
||||
|
||||
@@ -200,18 +200,25 @@ function createAnimatedComponent<Props: {+[string]: mixed, ...}, Instance>(
|
||||
},
|
||||
});
|
||||
|
||||
render() {
|
||||
render(): React.Node {
|
||||
// When rendering in Fabric and an AnimatedValue is used, we keep track of
|
||||
// the initial value of that Value, to avoid additional prop updates when
|
||||
// this component re-renders
|
||||
const initialPropsIfFabric = this._isFabric()
|
||||
? this._initialAnimatedProps
|
||||
: null;
|
||||
|
||||
const animatedProps =
|
||||
this._propsAnimated.__getValue(this._initialAnimatedProps) || {};
|
||||
this._propsAnimated.__getValue(initialPropsIfFabric) || {};
|
||||
if (!this._initialAnimatedProps) {
|
||||
this._initialAnimatedProps = animatedProps;
|
||||
}
|
||||
|
||||
const {style = {}, ...props} = animatedProps;
|
||||
const {style: passthruStyle = {}, ...passthruProps} =
|
||||
this.props.passthroughAnimatedPropExplicitValues || {};
|
||||
const mergedStyle = {...style, ...passthruStyle};
|
||||
|
||||
if (!this._initialAnimatedProps) {
|
||||
this._initialAnimatedProps = animatedProps;
|
||||
}
|
||||
|
||||
// Force `collapsable` to be false so that native view is not flattened.
|
||||
// Flattened views cannot be accurately referenced by a native driver.
|
||||
return (
|
||||
|
||||
@@ -46,9 +46,7 @@ class AnimatedProps extends AnimatedNode {
|
||||
// as they may not be up to date, so we use the initial value to ensure that values of
|
||||
// native animated nodes do not impact rerenders.
|
||||
if (value instanceof AnimatedStyle) {
|
||||
props[key] = value.__getValue(
|
||||
initialProps ? initialProps.style : null,
|
||||
);
|
||||
props[key] = value.__getValue(initialProps?.style);
|
||||
} else if (!initialProps || !value.__isNative) {
|
||||
props[key] = value.__getValue();
|
||||
} else if (initialProps.hasOwnProperty(key)) {
|
||||
|
||||
@@ -105,6 +105,12 @@ class Blob {
|
||||
blobId: this.data.blobId,
|
||||
offset,
|
||||
size,
|
||||
/* Since `blob.slice()` creates a new view onto the same binary
|
||||
* data as the original blob, we should re-use the same collector
|
||||
* object so that the underlying resource gets deallocated when
|
||||
* the last view into the data is released, not the first.
|
||||
*/
|
||||
__collector: this.data.__collector,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @flow strict-local
|
||||
* @format
|
||||
*/
|
||||
|
||||
import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
|
||||
import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
|
||||
import type {ElementRef} from 'react';
|
||||
|
||||
// Events that are only supported on Android.
|
||||
type AccessibilityEventDefinitionsAndroid = {
|
||||
accessibilityServiceChanged: [boolean],
|
||||
};
|
||||
|
||||
// Events that are only supported on iOS.
|
||||
type AccessibilityEventDefinitionsIOS = {
|
||||
announcementFinished: [{announcement: string, success: boolean}],
|
||||
boldTextChanged: [boolean],
|
||||
grayscaleChanged: [boolean],
|
||||
invertColorsChanged: [boolean],
|
||||
reduceTransparencyChanged: [boolean],
|
||||
};
|
||||
|
||||
type AccessibilityEventDefinitions = {
|
||||
...AccessibilityEventDefinitionsAndroid,
|
||||
...AccessibilityEventDefinitionsIOS,
|
||||
change: [boolean], // screenReaderChanged
|
||||
reduceMotionChanged: [boolean],
|
||||
screenReaderChanged: [boolean],
|
||||
};
|
||||
|
||||
type AccessibilityEventTypes = 'click' | 'focus';
|
||||
/**
|
||||
* Sometimes it's useful to know whether or not the device has a screen reader
|
||||
* that is currently active. The `AccessibilityInfo` API is designed for this
|
||||
* purpose. You can use it to query the current state of the screen reader as
|
||||
* well as to register to be notified when the state of the screen reader
|
||||
* changes.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo
|
||||
*/
|
||||
export interface AccessibilityInfo {
|
||||
/**
|
||||
* Query whether bold text is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when bold text is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#isBoldTextEnabled
|
||||
*/
|
||||
isBoldTextEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether grayscale is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when grayscale is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#isGrayscaleEnabled
|
||||
*/
|
||||
isGrayscaleEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether inverted colors are currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when invert color is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#isInvertColorsEnabled
|
||||
*/
|
||||
isInvertColorsEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether reduced motion is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when a reduce motion is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#isReduceMotionEnabled
|
||||
*/
|
||||
isReduceMotionEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#prefersCrossFadeTransitions
|
||||
*/
|
||||
prefersCrossFadeTransitions: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether reduced transparency is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when a reduce transparency is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#isReduceTransparencyEnabled
|
||||
*/
|
||||
isReduceTransparencyEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether a screen reader is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when a screen reader is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#isScreenReaderEnabled
|
||||
*/
|
||||
isScreenReaderEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Query whether Accessibility Service is currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when any service is enabled and `false` otherwise.
|
||||
*
|
||||
* @platform android
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo/#isaccessibilityserviceenabled-android
|
||||
*/
|
||||
isAccessibilityServiceEnabled: () => Promise<boolean>;
|
||||
|
||||
/**
|
||||
* Add an event handler. Supported events:
|
||||
*
|
||||
* - `reduceMotionChanged`: Fires when the state of the reduce motion toggle changes.
|
||||
* The argument to the event handler is a boolean. The boolean is `true` when a reduce
|
||||
* motion is enabled (or when "Transition Animation Scale" in "Developer options" is
|
||||
* "Animation off") and `false` otherwise.
|
||||
* - `screenReaderChanged`: Fires when the state of the screen reader changes. The argument
|
||||
* to the event handler is a boolean. The boolean is `true` when a screen
|
||||
* reader is enabled and `false` otherwise.
|
||||
*
|
||||
* These events are only supported on iOS:
|
||||
*
|
||||
* - `boldTextChanged`: iOS-only event. Fires when the state of the bold text toggle changes.
|
||||
* The argument to the event handler is a boolean. The boolean is `true` when a bold text
|
||||
* is enabled and `false` otherwise.
|
||||
* - `grayscaleChanged`: iOS-only event. Fires when the state of the gray scale toggle changes.
|
||||
* The argument to the event handler is a boolean. The boolean is `true` when a gray scale
|
||||
* is enabled and `false` otherwise.
|
||||
* - `invertColorsChanged`: iOS-only event. Fires when the state of the invert colors toggle
|
||||
* changes. The argument to the event handler is a boolean. The boolean is `true` when a invert
|
||||
* colors is enabled and `false` otherwise.
|
||||
* - `reduceTransparencyChanged`: iOS-only event. Fires when the state of the reduce transparency
|
||||
* toggle changes. The argument to the event handler is a boolean. The boolean is `true`
|
||||
* when a reduce transparency is enabled and `false` otherwise.
|
||||
* - `announcementFinished`: iOS-only event. Fires when the screen reader has
|
||||
* finished making an announcement. The argument to the event handler is a
|
||||
* dictionary with these keys:
|
||||
* - `announcement`: The string announced by the screen reader.
|
||||
* - `success`: A boolean indicating whether the announcement was
|
||||
* successfully made.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#addeventlistener
|
||||
*/
|
||||
addEventListener<K: $Keys<AccessibilityEventDefinitions>>(
|
||||
eventName: K,
|
||||
handler: (...$ElementType<AccessibilityEventDefinitions, K>) => void,
|
||||
): EventSubscription;
|
||||
|
||||
/**
|
||||
* Set accessibility focus to a React component.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#setaccessibilityfocus
|
||||
*/
|
||||
setAccessibilityFocus: (reactTag: number) => void;
|
||||
|
||||
/**
|
||||
* Send a named accessibility event to a HostComponent.
|
||||
*/
|
||||
sendAccessibilityEvent: (
|
||||
handle: ElementRef<HostComponent<mixed>>,
|
||||
eventType: AccessibilityEventTypes,
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Post a string to be announced by the screen reader.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#announceforaccessibility
|
||||
*/
|
||||
announceForAccessibility: (announcement: string) => void;
|
||||
|
||||
/**
|
||||
* Post a string to be announced by the screen reader.
|
||||
* - `announcement`: The string announced by the screen reader.
|
||||
* - `options`: An object that configures the reading options.
|
||||
* - `queue`: The announcement will be queued behind existing announcements. iOS only.
|
||||
*/
|
||||
announceForAccessibilityWithOptions: (
|
||||
announcement: string,
|
||||
options: {queue?: boolean},
|
||||
) => void;
|
||||
|
||||
/**
|
||||
* Get the recommended timeout for changes to the UI needed by this user.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#getrecommendedtimeoutmillis
|
||||
*/
|
||||
getRecommendedTimeoutMillis: (originalTimeout: number) => Promise<number>;
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import NativeAccessibilityInfoAndroid from './NativeAccessibilityInfo';
|
||||
import NativeAccessibilityManagerIOS from './NativeAccessibilityManager';
|
||||
import legacySendAccessibilityEvent from './legacySendAccessibilityEvent';
|
||||
import type {ElementRef} from 'react';
|
||||
import type {AccessibilityInfo as AccessibilityInfoType} from './AccessibilityInfo.flow';
|
||||
|
||||
// Events that are only supported on Android.
|
||||
type AccessibilityEventDefinitionsAndroid = {
|
||||
@@ -73,7 +74,7 @@ const EventNames: Map<
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo
|
||||
*/
|
||||
const AccessibilityInfo = {
|
||||
const AccessibilityInfo: AccessibilityInfoType = {
|
||||
/**
|
||||
* Query whether bold text is currently enabled.
|
||||
*
|
||||
@@ -178,6 +179,34 @@ const AccessibilityInfo = {
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Query whether reduce motion and prefer cross-fade transitions settings are currently enabled.
|
||||
*
|
||||
* Returns a promise which resolves to a boolean.
|
||||
* The result is `true` when prefer cross-fade transitions is enabled and `false` otherwise.
|
||||
*
|
||||
* See https://reactnative.dev/docs/accessibilityinfo#prefersCrossFadeTransitions
|
||||
*/
|
||||
prefersCrossFadeTransitions(): Promise<boolean> {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (Platform.OS === 'android') {
|
||||
return Promise.resolve(false);
|
||||
} else {
|
||||
if (
|
||||
NativeAccessibilityManagerIOS?.getCurrentPrefersCrossFadeTransitionsState !=
|
||||
null
|
||||
) {
|
||||
NativeAccessibilityManagerIOS.getCurrentPrefersCrossFadeTransitionsState(
|
||||
resolve,
|
||||
reject,
|
||||
);
|
||||
} else {
|
||||
reject(null);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Query whether reduced transparency is currently enabled.
|
||||
*
|
||||
@@ -295,6 +324,7 @@ const AccessibilityInfo = {
|
||||
*/
|
||||
addEventListener<K: $Keys<AccessibilityEventDefinitions>>(
|
||||
eventName: K,
|
||||
// $FlowIssue[incompatible-type] - Flow bug with unions and generics (T128099423)
|
||||
handler: (...$ElementType<AccessibilityEventDefinitions, K>) => void,
|
||||
): EventSubscription {
|
||||
const deviceEventName = EventNames.get(eventName);
|
||||
@@ -315,7 +345,7 @@ const AccessibilityInfo = {
|
||||
/**
|
||||
* Send a named accessibility event to a HostComponent.
|
||||
*/
|
||||
sendAccessibilityEvent_unstable(
|
||||
sendAccessibilityEvent(
|
||||
handle: ElementRef<HostComponent<mixed>>,
|
||||
eventType: AccessibilityEventTypes,
|
||||
) {
|
||||
|
||||
@@ -28,6 +28,10 @@ export interface Spec extends TurboModule {
|
||||
onSuccess: (isReduceMotionEnabled: boolean) => void,
|
||||
onError: (error: Object) => void,
|
||||
) => void;
|
||||
+getCurrentPrefersCrossFadeTransitionsState?: (
|
||||
onSuccess: (prefersCrossFadeTransitions: boolean) => void,
|
||||
onError: (error: Object) => void,
|
||||
) => void;
|
||||
+getCurrentReduceTransparencyState: (
|
||||
onSuccess: (isReduceTransparencyEnabled: boolean) => void,
|
||||
onError: (error: Object) => void,
|
||||
|
||||
@@ -24,7 +24,7 @@ export type KeyboardEventEasing =
|
||||
| 'linear'
|
||||
| 'keyboard';
|
||||
|
||||
export type KeyboardEventCoordinates = $ReadOnly<{|
|
||||
export type KeyboardMetrics = $ReadOnly<{|
|
||||
screenX: number,
|
||||
screenY: number,
|
||||
width: number,
|
||||
@@ -36,7 +36,7 @@ export type KeyboardEvent = AndroidKeyboardEvent | IOSKeyboardEvent;
|
||||
type BaseKeyboardEvent = {|
|
||||
duration: number,
|
||||
easing: KeyboardEventEasing,
|
||||
endCoordinates: KeyboardEventCoordinates,
|
||||
endCoordinates: KeyboardMetrics,
|
||||
|};
|
||||
|
||||
export type AndroidKeyboardEvent = $ReadOnly<{|
|
||||
@@ -47,7 +47,7 @@ export type AndroidKeyboardEvent = $ReadOnly<{|
|
||||
|
||||
export type IOSKeyboardEvent = $ReadOnly<{|
|
||||
...BaseKeyboardEvent,
|
||||
startCoordinates: KeyboardEventCoordinates,
|
||||
startCoordinates: KeyboardMetrics,
|
||||
isEventFromThisApp: boolean,
|
||||
|}>;
|
||||
|
||||
@@ -103,6 +103,8 @@ type KeyboardEventDefinitions = {
|
||||
*/
|
||||
|
||||
class Keyboard {
|
||||
_currentlyShowing: ?KeyboardEvent;
|
||||
|
||||
_emitter: NativeEventEmitter<KeyboardEventDefinitions> =
|
||||
new NativeEventEmitter(
|
||||
// T88715063: NativeEventEmitter only used this parameter on iOS. Now it uses it on all platforms, so this code was modified automatically to preserve its behavior
|
||||
@@ -110,6 +112,15 @@ class Keyboard {
|
||||
Platform.OS !== 'ios' ? null : NativeKeyboardObserver,
|
||||
);
|
||||
|
||||
constructor() {
|
||||
this.addListener('keyboardDidShow', ev => {
|
||||
this._currentlyShowing = ev;
|
||||
});
|
||||
this.addListener('keyboardDidHide', _ev => {
|
||||
this._currentlyShowing = null;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The `addListener` function connects a JavaScript function to an identified native
|
||||
* keyboard notification event.
|
||||
@@ -157,6 +168,20 @@ class Keyboard {
|
||||
dismissKeyboard();
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether the keyboard is last known to be visible.
|
||||
*/
|
||||
isVisible(): boolean {
|
||||
return !!this._currentlyShowing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the metrics of the soft-keyboard if visible.
|
||||
*/
|
||||
metrics(): ?KeyboardMetrics {
|
||||
return this._currentlyShowing?.endCoordinates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Useful for syncing TextInput (or other keyboard accessory view) size of
|
||||
* position changes with keyboard movements.
|
||||
|
||||
@@ -22,7 +22,8 @@ import type {
|
||||
ViewLayout,
|
||||
ViewLayoutEvent,
|
||||
} from '../View/ViewPropTypes';
|
||||
import type {KeyboardEvent, KeyboardEventCoordinates} from './Keyboard';
|
||||
import type {KeyboardEvent, KeyboardMetrics} from './Keyboard';
|
||||
import AccessibilityInfo from '../AccessibilityInfo/AccessibilityInfo';
|
||||
|
||||
type Props = $ReadOnly<{|
|
||||
...ViewProps,
|
||||
@@ -71,12 +72,24 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
this.viewRef = React.createRef();
|
||||
}
|
||||
|
||||
_relativeKeyboardHeight(keyboardFrame: KeyboardEventCoordinates): number {
|
||||
async _relativeKeyboardHeight(
|
||||
keyboardFrame: KeyboardMetrics,
|
||||
): Promise<number> {
|
||||
const frame = this._frame;
|
||||
if (!frame || !keyboardFrame) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On iOS when Prefer Cross-Fade Transitions is enabled, the keyboard position
|
||||
// & height is reported differently (0 instead of Y position value matching height of frame)
|
||||
if (
|
||||
Platform.OS === 'ios' &&
|
||||
keyboardFrame.screenY === 0 &&
|
||||
(await AccessibilityInfo.prefersCrossFadeTransitions())
|
||||
) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const keyboardY =
|
||||
keyboardFrame.screenY - (this.props.keyboardVerticalOffset ?? 0);
|
||||
|
||||
@@ -90,7 +103,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
this._updateBottomIfNecessary();
|
||||
};
|
||||
|
||||
_onLayout = (event: ViewLayoutEvent) => {
|
||||
_onLayout = async (event: ViewLayoutEvent) => {
|
||||
const wasFrameNull = this._frame == null;
|
||||
this._frame = event.nativeEvent.layout;
|
||||
if (!this._initialFrameHeight) {
|
||||
@@ -99,7 +112,7 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
if (wasFrameNull) {
|
||||
this._updateBottomIfNecessary();
|
||||
await this._updateBottomIfNecessary();
|
||||
}
|
||||
|
||||
if (this.props.onLayout) {
|
||||
@@ -107,14 +120,14 @@ class KeyboardAvoidingView extends React.Component<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
_updateBottomIfNecessary = () => {
|
||||
_updateBottomIfNecessary = async () => {
|
||||
if (this._keyboardEvent == null) {
|
||||
this.setState({bottom: 0});
|
||||
return;
|
||||
}
|
||||
|
||||
const {duration, easing, endCoordinates} = this._keyboardEvent;
|
||||
const height = this._relativeKeyboardHeight(endCoordinates);
|
||||
const height = await this._relativeKeyboardHeight(endCoordinates);
|
||||
|
||||
if (this.state.bottom === height) {
|
||||
return;
|
||||
|
||||
@@ -42,7 +42,7 @@ import type {HostComponent} from '../../Renderer/shims/ReactNativeTypes';
|
||||
import type {ViewProps} from '../View/ViewPropTypes';
|
||||
import ScrollViewContext, {HORIZONTAL, VERTICAL} from './ScrollViewContext';
|
||||
import type {Props as ScrollViewStickyHeaderProps} from './ScrollViewStickyHeader';
|
||||
import type {KeyboardEvent} from '../Keyboard/Keyboard';
|
||||
import type {KeyboardEvent, KeyboardMetrics} from '../Keyboard/Keyboard';
|
||||
import type {EventSubscription} from '../../vendor/emitter/EventEmitter';
|
||||
|
||||
import Commands from './ScrollViewCommands';
|
||||
@@ -731,7 +731,7 @@ class ScrollView extends React.Component<Props, State> {
|
||||
new Map();
|
||||
_headerLayoutYs: Map<string, number> = new Map();
|
||||
|
||||
_keyboardWillOpenTo: ?KeyboardEvent = null;
|
||||
_keyboardMetrics: ?KeyboardMetrics = null;
|
||||
_additionalScrollOffset: number = 0;
|
||||
_isTouching: boolean = false;
|
||||
_lastMomentumScrollBeginTime: number = 0;
|
||||
@@ -769,7 +769,7 @@ class ScrollView extends React.Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
this._keyboardWillOpenTo = null;
|
||||
this._keyboardMetrics = Keyboard.metrics();
|
||||
this._additionalScrollOffset = 0;
|
||||
|
||||
this._subscriptionKeyboardWillShow = Keyboard.addListener(
|
||||
@@ -1075,8 +1075,8 @@ class ScrollView extends React.Component<Props, State> {
|
||||
let keyboardScreenY = Dimensions.get('window').height;
|
||||
|
||||
const scrollTextInputIntoVisibleRect = () => {
|
||||
if (this._keyboardWillOpenTo != null) {
|
||||
keyboardScreenY = this._keyboardWillOpenTo.endCoordinates.screenY;
|
||||
if (this._keyboardMetrics != null) {
|
||||
keyboardScreenY = this._keyboardMetrics.screenY;
|
||||
}
|
||||
let scrollOffsetY =
|
||||
top - keyboardScreenY + height + this._additionalScrollOffset;
|
||||
@@ -1094,8 +1094,8 @@ class ScrollView extends React.Component<Props, State> {
|
||||
this._preventNegativeScrollOffset = false;
|
||||
};
|
||||
|
||||
if (this._keyboardWillOpenTo == null) {
|
||||
// `_keyboardWillOpenTo` is set inside `scrollResponderKeyboardWillShow` which
|
||||
if (this._keyboardMetrics == null) {
|
||||
// `_keyboardMetrics` is set inside `scrollResponderKeyboardWillShow` which
|
||||
// is not guaranteed to be called before `_inputMeasureAndScrollToKeyboard` but native has already scheduled it.
|
||||
// In case it was not called before `_inputMeasureAndScrollToKeyboard`, we postpone scrolling to
|
||||
// text input.
|
||||
@@ -1243,32 +1243,28 @@ class ScrollView extends React.Component<Props, State> {
|
||||
scrollResponderKeyboardWillShow: (e: KeyboardEvent) => void = (
|
||||
e: KeyboardEvent,
|
||||
) => {
|
||||
this._keyboardWillOpenTo = e;
|
||||
this._keyboardMetrics = e.endCoordinates;
|
||||
this.props.onKeyboardWillShow && this.props.onKeyboardWillShow(e);
|
||||
};
|
||||
|
||||
scrollResponderKeyboardWillHide: (e: KeyboardEvent) => void = (
|
||||
e: KeyboardEvent,
|
||||
) => {
|
||||
this._keyboardWillOpenTo = null;
|
||||
this._keyboardMetrics = null;
|
||||
this.props.onKeyboardWillHide && this.props.onKeyboardWillHide(e);
|
||||
};
|
||||
|
||||
scrollResponderKeyboardDidShow: (e: KeyboardEvent) => void = (
|
||||
e: KeyboardEvent,
|
||||
) => {
|
||||
// TODO(7693961): The event for DidShow is not available on iOS yet.
|
||||
// Use the one from WillShow and do not assign.
|
||||
if (e) {
|
||||
this._keyboardWillOpenTo = e;
|
||||
}
|
||||
this._keyboardMetrics = e.endCoordinates;
|
||||
this.props.onKeyboardDidShow && this.props.onKeyboardDidShow(e);
|
||||
};
|
||||
|
||||
scrollResponderKeyboardDidHide: (e: KeyboardEvent) => void = (
|
||||
e: KeyboardEvent,
|
||||
) => {
|
||||
this._keyboardWillOpenTo = null;
|
||||
this._keyboardMetrics = null;
|
||||
this.props.onKeyboardDidHide && this.props.onKeyboardDidHide(e);
|
||||
};
|
||||
|
||||
@@ -1547,7 +1543,7 @@ class ScrollView extends React.Component<Props, State> {
|
||||
// keyboard, except on Android where setting windowSoftInputMode to
|
||||
// adjustNone leads to missing keyboard events.
|
||||
const softKeyboardMayBeOpen =
|
||||
this._keyboardWillOpenTo != null || Platform.OS === 'android';
|
||||
this._keyboardMetrics != null || Platform.OS === 'android';
|
||||
|
||||
return hasFocusedTextInput && softKeyboardMayBeOpen;
|
||||
};
|
||||
|
||||
@@ -976,8 +976,6 @@ function InternalTextInput(props: Props): React.Node {
|
||||
const text =
|
||||
typeof props.value === 'string'
|
||||
? props.value
|
||||
: typeof lastNativeText === 'string'
|
||||
? lastNativeText
|
||||
: typeof props.defaultValue === 'string'
|
||||
? props.defaultValue
|
||||
: '';
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
/**
|
||||
* @generated by scripts/set-rn-version.js
|
||||
*
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @generated by scripts/set-rn-version.js
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
exports.version = {
|
||||
major: 0,
|
||||
minor: 0,
|
||||
patch: 0,
|
||||
minor: 70,
|
||||
patch: 9,
|
||||
prerelease: null,
|
||||
};
|
||||
|
||||
@@ -39,7 +39,10 @@ if (__DEV__) {
|
||||
// Get hostname from development server (packager)
|
||||
const devServer = getDevServer();
|
||||
const host = devServer.bundleLoadedFromServer
|
||||
? devServer.url.replace(/https?:\/\//, '').split(':')[0]
|
||||
? devServer.url
|
||||
.replace(/https?:\/\//, '')
|
||||
.replace(/\/$/, '')
|
||||
.split(':')[0]
|
||||
: 'localhost';
|
||||
|
||||
// Read the optional global variable for backward compatibility.
|
||||
|
||||
@@ -74,7 +74,8 @@ const PERMISSIONS = Object.freeze({
|
||||
ANSWER_PHONE_CALLS: 'android.permission.ANSWER_PHONE_CALLS',
|
||||
READ_PHONE_NUMBERS: 'android.permission.READ_PHONE_NUMBERS',
|
||||
UWB_RANGING: 'android.permission.UWB_RANGING',
|
||||
POST_NOTIFICATION: 'android.permission.POST_NOTIFICATIONS',
|
||||
POST_NOTIFICATION: 'android.permission.POST_NOTIFICATIONS', // Remove in 0.72
|
||||
POST_NOTIFICATIONS: 'android.permission.POST_NOTIFICATIONS',
|
||||
NEARBY_WIFI_DEVICES: 'android.permission.NEARBY_WIFI_DEVICES',
|
||||
});
|
||||
|
||||
@@ -105,7 +106,8 @@ class PermissionsAndroid {
|
||||
CAMERA: string,
|
||||
GET_ACCOUNTS: string,
|
||||
NEARBY_WIFI_DEVICES: string,
|
||||
POST_NOTIFICATION: string,
|
||||
POST_NOTIFICATION: string, // Remove in 0.72
|
||||
POST_NOTIFICATIONS: string,
|
||||
PROCESS_OUTGOING_CALLS: string,
|
||||
READ_CALENDAR: string,
|
||||
READ_CALL_LOG: string,
|
||||
|
||||
@@ -146,7 +146,7 @@ module.exports = {
|
||||
errorMessageForMethod('setLayoutAnimationEnabledExperimental'),
|
||||
);
|
||||
},
|
||||
// Please use AccessibilityInfo.sendAccessibilityEvent_unstable instead.
|
||||
// Please use AccessibilityInfo.sendAccessibilityEvent instead.
|
||||
// See SetAccessibilityFocusExample in AccessibilityExample.js for a migration example.
|
||||
sendAccessibilityEvent: (reactTag: ?number, eventType: number): void =>
|
||||
console.error(errorMessageForMethod('sendAccessibilityEvent')),
|
||||
|
||||
@@ -347,7 +347,12 @@ module.exports = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (__DEV__ && typeof value.process === 'function') {
|
||||
if (
|
||||
__DEV__ &&
|
||||
typeof value.process === 'function' &&
|
||||
typeof ReactNativeStyleAttributes[property]?.process === 'function' &&
|
||||
value.process !== ReactNativeStyleAttributes[property]?.process
|
||||
) {
|
||||
console.warn(`Overwriting ${property} style attribute preprocessor`);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
*/
|
||||
|
||||
import {setStyleAttributePreprocessor} from '../StyleSheet';
|
||||
|
||||
describe(setStyleAttributePreprocessor, () => {
|
||||
const originalConsoleWarn = console.warn;
|
||||
|
||||
beforeEach(() => {
|
||||
jest.resetModules();
|
||||
console.warn = jest.fn();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
console.warn = originalConsoleWarn;
|
||||
});
|
||||
|
||||
it('should not show warning when set preprocessor first time', () => {
|
||||
const spyConsole = jest.spyOn(global.console, 'warn');
|
||||
setStyleAttributePreprocessor(
|
||||
'fontFamily',
|
||||
(fontFamily: string) => fontFamily,
|
||||
);
|
||||
expect(spyConsole).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should show warning when overwrite the preprocessor', () => {
|
||||
const spyConsole = jest.spyOn(global.console, 'warn');
|
||||
setStyleAttributePreprocessor(
|
||||
'fontFamily',
|
||||
(fontFamily: string) => fontFamily,
|
||||
);
|
||||
setStyleAttributePreprocessor(
|
||||
'fontFamily',
|
||||
(fontFamily: string) => `Scoped-${fontFamily}`,
|
||||
);
|
||||
expect(spyConsole).toHaveBeenCalledWith(
|
||||
'Overwriting fontFamily style attribute preprocessor',
|
||||
);
|
||||
});
|
||||
});
|
||||
+7
-1
@@ -47,7 +47,13 @@ Pod::Spec.new do |s|
|
||||
s.compiler_flags = folly_compiler_flags + ' ' + boost_compiler_flags
|
||||
s.header_dir = "React"
|
||||
s.framework = "JavaScriptCore"
|
||||
s.pod_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"${PODS_ROOT}/Headers/Public/FlipperKit\" \"$(PODS_ROOT)/Headers/Public/ReactCommon\" \"$(PODS_ROOT)/Headers/Public/React-RCTFabric\"", "DEFINES_MODULE" => "YES", "GCC_PREPROCESSOR_DEFINITIONS" => "RCT_METRO_PORT=${RCT_METRO_PORT}", "CLANG_CXX_LANGUAGE_STANDARD" => "c++17" }
|
||||
s.pod_target_xcconfig = {
|
||||
"HEADER_SEARCH_PATHS" => "\"$(PODS_TARGET_SRCROOT)/ReactCommon\" \"$(PODS_ROOT)/boost\" \"$(PODS_ROOT)/DoubleConversion\" \"$(PODS_ROOT)/RCT-Folly\" \"${PODS_ROOT}/Headers/Public/React-hermes\" \"${PODS_ROOT}/Headers/Public/hermes-engine\" \"${PODS_ROOT}/Headers/Public/FlipperKit\" \"$(PODS_ROOT)/Headers/Public/ReactCommon\" \"$(PODS_ROOT)/Headers/Public/React-RCTFabric\"",
|
||||
"FRAMEWORK_SEARCH_PATHS" => "\"${PODS_CONFIGURATION_BUILD_DIR}/React-hermes\"",
|
||||
"DEFINES_MODULE" => "YES",
|
||||
"GCC_PREPROCESSOR_DEFINITIONS" => "RCT_METRO_PORT=${RCT_METRO_PORT}",
|
||||
"CLANG_CXX_LANGUAGE_STANDARD" => "c++17",
|
||||
}
|
||||
s.user_target_xcconfig = { "HEADER_SEARCH_PATHS" => "\"$(PODS_ROOT)/Headers/Private/React-Core\""}
|
||||
s.default_subspec = "Default"
|
||||
|
||||
|
||||
@@ -9,6 +9,8 @@
|
||||
#import <React/RCTBridge.h>
|
||||
#import <React/RCTRootView.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
|
||||
#ifndef RCT_USE_HERMES
|
||||
@@ -28,13 +30,6 @@
|
||||
#import <ReactCommon/RCTTurboModuleManager.h>
|
||||
#endif
|
||||
|
||||
RCT_EXTERN_C_BEGIN
|
||||
|
||||
void RCTAppSetupPrepareApp(UIApplication *application);
|
||||
UIView *RCTAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary *initialProperties);
|
||||
|
||||
RCT_EXTERN_C_END
|
||||
|
||||
#if RCT_NEW_ARCH_ENABLED
|
||||
RCT_EXTERN id<RCTTurboModule> RCTAppSetupDefaultModuleFromClass(Class moduleClass);
|
||||
|
||||
@@ -42,3 +37,12 @@ std::unique_ptr<facebook::react::JSExecutorFactory> RCTAppSetupDefaultJsExecutor
|
||||
RCTBridge *bridge,
|
||||
RCTTurboModuleManager *turboModuleManager);
|
||||
#endif
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
RCT_EXTERN_C_BEGIN
|
||||
|
||||
void RCTAppSetupPrepareApp(UIApplication *application);
|
||||
UIView *RCTAppSetupDefaultRootView(RCTBridge *bridge, NSString *moduleName, NSDictionary *initialProperties);
|
||||
|
||||
RCT_EXTERN_C_END
|
||||
|
||||
@@ -21,11 +21,11 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^(void){
|
||||
__rnVersion = @{
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(0),
|
||||
RCTVersionPatch: @(0),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
};
|
||||
RCTVersionMajor: @(0),
|
||||
RCTVersionMinor: @(70),
|
||||
RCTVersionPatch: @(9),
|
||||
RCTVersionPrerelease: [NSNull null],
|
||||
};
|
||||
});
|
||||
return __rnVersion;
|
||||
}
|
||||
|
||||
@@ -23,6 +23,7 @@ extern NSString *const RCTAccessibilityManagerDidUpdateMultiplierNotification; /
|
||||
@property (nonatomic, assign) BOOL isGrayscaleEnabled;
|
||||
@property (nonatomic, assign) BOOL isInvertColorsEnabled;
|
||||
@property (nonatomic, assign) BOOL isReduceMotionEnabled;
|
||||
@property (nonatomic, assign) BOOL prefersCrossFadeTransitions;
|
||||
@property (nonatomic, assign) BOOL isReduceTransparencyEnabled;
|
||||
@property (nonatomic, assign) BOOL isVoiceOverEnabled;
|
||||
|
||||
|
||||
@@ -358,6 +358,17 @@ RCT_EXPORT_METHOD(getCurrentReduceMotionState
|
||||
onSuccess(@[ @(_isReduceMotionEnabled) ]);
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getCurrentPrefersCrossFadeTransitionsState
|
||||
: (RCTResponseSenderBlock)onSuccess onError
|
||||
: (__unused RCTResponseSenderBlock)onError)
|
||||
{
|
||||
if (@available(iOS 14.0, *)) {
|
||||
onSuccess(@[ @(UIAccessibilityPrefersCrossFadeTransitions()) ]);
|
||||
} else {
|
||||
onSuccess(@[ @(false) ]);
|
||||
}
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(getCurrentReduceTransparencyState
|
||||
: (RCTResponseSenderBlock)onSuccess onError
|
||||
: (__unused RCTResponseSenderBlock)onError)
|
||||
|
||||
@@ -75,13 +75,15 @@ RCT_EXPORT_MODULE()
|
||||
modalHostView.onShow(nil);
|
||||
}
|
||||
};
|
||||
if (_presentationBlock) {
|
||||
_presentationBlock([modalHostView reactViewController], viewController, animated, completionBlock);
|
||||
} else {
|
||||
[[modalHostView reactViewController] presentViewController:viewController
|
||||
animated:animated
|
||||
completion:completionBlock];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self->_presentationBlock) {
|
||||
self->_presentationBlock([modalHostView reactViewController], viewController, animated, completionBlock);
|
||||
} else {
|
||||
[[modalHostView reactViewController] presentViewController:viewController
|
||||
animated:animated
|
||||
completion:completionBlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (void)dismissModalHostView:(RCTModalHostView *)modalHostView
|
||||
@@ -93,11 +95,13 @@ RCT_EXPORT_MODULE()
|
||||
[[self.bridge moduleForClass:[RCTModalManager class]] modalDismissed:modalHostView.identifier];
|
||||
}
|
||||
};
|
||||
if (_dismissalBlock) {
|
||||
_dismissalBlock([modalHostView reactViewController], viewController, animated, completionBlock);
|
||||
} else {
|
||||
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
if (self->_dismissalBlock) {
|
||||
self->_dismissalBlock([modalHostView reactViewController], viewController, animated, completionBlock);
|
||||
} else {
|
||||
[viewController.presentingViewController dismissViewControllerAnimated:animated completion:completionBlock];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
- (RCTShadowView *)shadowView
|
||||
|
||||
@@ -5,10 +5,15 @@
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
buildscript {
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:${rootProject.hasProperty("kotlinVersion") ? rootProject.ext.kotlinVersion : KOTLIN_VERSION}"
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id("com.android.library")
|
||||
id("com.facebook.react")
|
||||
id("org.jetbrains.kotlin.android") version "1.6.10"
|
||||
id("maven-publish")
|
||||
id("de.undercouch.download")
|
||||
}
|
||||
@@ -483,3 +488,5 @@ afterEvaluate {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "org.jetbrains.kotlin.android"
|
||||
|
||||
@@ -18,14 +18,19 @@ set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
include(${REACT_ANDROID_DIR}/cmake-utils/Android-prebuilt.cmake)
|
||||
|
||||
file(GLOB input_SRC CONFIGURE_DEPENDS
|
||||
set(BUILD_DIR ${PROJECT_BUILD_DIR})
|
||||
if(CMAKE_HOST_WIN32)
|
||||
string(REPLACE "\\" "/" BUILD_DIR ${BUILD_DIR})
|
||||
endif()
|
||||
|
||||
file(GLOB input_SRC CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni/*.cpp)
|
||||
${BUILD_DIR}/generated/rncli/src/main/jni/*.cpp)
|
||||
|
||||
add_library(${CMAKE_PROJECT_NAME} SHARED ${input_SRC})
|
||||
|
||||
target_include_directories(${CMAKE_PROJECT_NAME}
|
||||
PUBLIC
|
||||
target_include_directories(${CMAKE_PROJECT_NAME}
|
||||
PUBLIC
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${PROJECT_BUILD_DIR}/generated/rncli/src/main/jni)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
VERSION_NAME=1000.0.0-main
|
||||
VERSION_NAME=0.70.9
|
||||
GROUP=com.facebook.react
|
||||
|
||||
POM_NAME=ReactNative
|
||||
@@ -22,7 +22,7 @@ OKHTTP_VERSION=4.9.2
|
||||
POWERMOCK_VERSION=2.0.2
|
||||
PROGUARD_ANNOTATIONS_VERSION=1.19.0
|
||||
ROBOLECTRIC_VERSION=4.4
|
||||
SO_LOADER_VERSION=0.10.3
|
||||
SO_LOADER_VERSION=0.10.4
|
||||
SWIPEREFRESH_LAYOUT_VERSION=1.0.0
|
||||
|
||||
# Native Dependency Versions
|
||||
@@ -33,5 +33,8 @@ FOLLY_VERSION=2021.07.22.00
|
||||
GLOG_VERSION=0.3.5
|
||||
LIBEVENT_VERSION=2.1.12
|
||||
|
||||
# Plugins Versions
|
||||
KOTLIN_VERSION=1.6.10
|
||||
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
|
||||
@@ -86,7 +86,7 @@ task unzipHermes(dependsOn: downloadHermes, type: Copy) {
|
||||
|
||||
task configureBuildForHermes(type: Exec) {
|
||||
workingDir(hermesDir)
|
||||
commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), "-S", ".", "-B", hermesBuildDir.toString(), "-DJSI_DIR=" + jsiDir.absolutePath))
|
||||
commandLine(windowsAwareCommandLine(findCmakePath(cmakeVersion), Os.isFamily(Os.FAMILY_WINDOWS) ? "-GNMake Makefiles" : "", "-S", ".", "-B", hermesBuildDir.toString(), "-DJSI_DIR=" + jsiDir.absolutePath))
|
||||
}
|
||||
|
||||
task buildHermes(dependsOn: configureBuildForHermes, type: Exec) {
|
||||
|
||||
@@ -33,8 +33,11 @@ public class HermesExecutor extends JavaScriptExecutor {
|
||||
}
|
||||
}
|
||||
|
||||
HermesExecutor(@Nullable RuntimeConfig config) {
|
||||
super(config == null ? initHybridDefaultConfig() : initHybrid(config.heapSizeMB));
|
||||
HermesExecutor(@Nullable RuntimeConfig config, boolean enableDebugger, String debuggerName) {
|
||||
super(
|
||||
config == null
|
||||
? initHybridDefaultConfig(enableDebugger, debuggerName)
|
||||
: initHybrid(enableDebugger, debuggerName, config.heapSizeMB));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,7 +54,9 @@ public class HermesExecutor extends JavaScriptExecutor {
|
||||
*/
|
||||
public static native boolean canLoadFile(String path);
|
||||
|
||||
private static native HybridData initHybridDefaultConfig();
|
||||
private static native HybridData initHybridDefaultConfig(
|
||||
boolean enableDebugger, String debuggerName);
|
||||
|
||||
private static native HybridData initHybrid(long heapSizeMB);
|
||||
private static native HybridData initHybrid(
|
||||
boolean enableDebugger, String debuggerName, long heapSizeMB);
|
||||
}
|
||||
|
||||
+11
-1
@@ -15,6 +15,8 @@ public class HermesExecutorFactory implements JavaScriptExecutorFactory {
|
||||
private static final String TAG = "Hermes";
|
||||
|
||||
private final RuntimeConfig mConfig;
|
||||
private boolean mEnableDebugger = true;
|
||||
private String mDebuggerName = "";
|
||||
|
||||
public HermesExecutorFactory() {
|
||||
this(null);
|
||||
@@ -24,9 +26,17 @@ public class HermesExecutorFactory implements JavaScriptExecutorFactory {
|
||||
mConfig = config;
|
||||
}
|
||||
|
||||
public void setEnableDebugger(boolean enableDebugger) {
|
||||
mEnableDebugger = enableDebugger;
|
||||
}
|
||||
|
||||
public void setDebuggerName(String debuggerName) {
|
||||
mDebuggerName = debuggerName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JavaScriptExecutor create() {
|
||||
return new HermesExecutor(mConfig);
|
||||
return new HermesExecutor(mConfig, mEnableDebugger, mDebuggerName);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,26 +69,39 @@ class HermesExecutorHolder
|
||||
"Lcom/facebook/hermes/reactexecutor/HermesExecutor;";
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybridDefaultConfig(
|
||||
jni::alias_ref<jclass>) {
|
||||
jni::alias_ref<jclass>,
|
||||
bool enableDebugger,
|
||||
std::string debuggerName) {
|
||||
JReactMarker::setLogPerfMarkerIfNeeded();
|
||||
|
||||
std::call_once(flag, []() {
|
||||
facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler);
|
||||
});
|
||||
return makeCxxInstance(
|
||||
std::make_unique<HermesExecutorFactory>(installBindings));
|
||||
auto factory = std::make_unique<HermesExecutorFactory>(installBindings);
|
||||
factory->setEnableDebugger(enableDebugger);
|
||||
if (!debuggerName.empty()) {
|
||||
factory->setDebuggerName(debuggerName);
|
||||
}
|
||||
return makeCxxInstance(std::move(factory));
|
||||
}
|
||||
|
||||
static jni::local_ref<jhybriddata> initHybrid(
|
||||
jni::alias_ref<jclass>,
|
||||
bool enableDebugger,
|
||||
std::string debuggerName,
|
||||
jlong heapSizeMB) {
|
||||
JReactMarker::setLogPerfMarkerIfNeeded();
|
||||
auto runtimeConfig = makeRuntimeConfig(heapSizeMB);
|
||||
std::call_once(flag, []() {
|
||||
facebook::hermes::HermesRuntime::setFatalHandler(hermesFatalHandler);
|
||||
});
|
||||
return makeCxxInstance(std::make_unique<HermesExecutorFactory>(
|
||||
installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig));
|
||||
auto factory = std::make_unique<HermesExecutorFactory>(
|
||||
installBindings, JSIExecutor::defaultTimeoutInvoker, runtimeConfig);
|
||||
factory->setEnableDebugger(enableDebugger);
|
||||
if (!debuggerName.empty()) {
|
||||
factory->setDebuggerName(debuggerName);
|
||||
}
|
||||
return makeCxxInstance(std::move(factory));
|
||||
}
|
||||
|
||||
static bool canLoadFile(jni::alias_ref<jclass>, const std::string &path) {
|
||||
|
||||
@@ -871,7 +871,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
if (ANIMATED_MODULE_DEBUG) {
|
||||
FLog.d(
|
||||
NAME,
|
||||
"queue: disconnectAnimatedNodeFromView: " + animatedNodeTag + " viewTag: " + viewTag);
|
||||
"queue disconnectAnimatedNodeFromView: " + animatedNodeTag + " viewTag: " + viewTag);
|
||||
}
|
||||
|
||||
decrementInFlightAnimationsForViewTag(viewTag);
|
||||
@@ -883,7 +883,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
if (ANIMATED_MODULE_DEBUG) {
|
||||
FLog.d(
|
||||
NAME,
|
||||
"execute: disconnectAnimatedNodeFromView: "
|
||||
"execute disconnectAnimatedNodeFromView: "
|
||||
+ animatedNodeTag
|
||||
+ " viewTag: "
|
||||
+ viewTag);
|
||||
@@ -897,8 +897,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
public void restoreDefaultValues(final double animatedNodeTagDouble) {
|
||||
final int animatedNodeTag = (int) animatedNodeTagDouble;
|
||||
if (ANIMATED_MODULE_DEBUG) {
|
||||
FLog.d(
|
||||
NAME, "queue restoreDefaultValues: disconnectAnimatedNodeFromView: " + animatedNodeTag);
|
||||
FLog.d(NAME, "queue restoreDefaultValues: " + animatedNodeTag);
|
||||
}
|
||||
|
||||
addPreOperation(
|
||||
@@ -906,10 +905,7 @@ public class NativeAnimatedModule extends NativeAnimatedModuleSpec
|
||||
@Override
|
||||
public void execute(NativeAnimatedNodesManager animatedNodesManager) {
|
||||
if (ANIMATED_MODULE_DEBUG) {
|
||||
FLog.d(
|
||||
NAME,
|
||||
"execute restoreDefaultValues: disconnectAnimatedNodeFromView: "
|
||||
+ animatedNodeTag);
|
||||
FLog.d(NAME, "execute restoreDefaultValues: " + animatedNodeTag);
|
||||
}
|
||||
animatedNodesManager.restoreDefaultValues(animatedNodeTag);
|
||||
}
|
||||
|
||||
+2
-2
@@ -69,9 +69,9 @@ public class DevLoadingViewController {
|
||||
return;
|
||||
}
|
||||
|
||||
int port = parsedURL.getPort() != -1 ? parsedURL.getPort() : parsedURL.getDefaultPort();
|
||||
showMessage(
|
||||
context.getString(
|
||||
R.string.catalyst_loading_from_url, parsedURL.getHost() + ":" + parsedURL.getPort()));
|
||||
context.getString(R.string.catalyst_loading_from_url, parsedURL.getHost() + ":" + port));
|
||||
}
|
||||
|
||||
public void showForRemoteJSEnabled() {
|
||||
|
||||
@@ -703,7 +703,7 @@ public abstract class DevSupportManagerBase implements DevSupportManager {
|
||||
URL sourceUrl = new URL(getSourceUrl());
|
||||
String path = sourceUrl.getPath().substring(1); // strip initial slash in path
|
||||
String host = sourceUrl.getHost();
|
||||
int port = sourceUrl.getPort();
|
||||
int port = sourceUrl.getPort() != -1 ? sourceUrl.getPort() : sourceUrl.getDefaultPort();
|
||||
mCurrentContext
|
||||
.getJSModule(HMRClient.class)
|
||||
.setup("android", path, host, port, mDevSettings.isHotModuleReplacementEnabled());
|
||||
|
||||
@@ -44,7 +44,7 @@ target_link_libraries(
|
||||
react_render_uimanager
|
||||
react_utils
|
||||
react_config
|
||||
reactnativeutilsjni
|
||||
reactnativejni
|
||||
rrc_image
|
||||
rrc_modal
|
||||
rrc_progressbar
|
||||
|
||||
+3
-1
@@ -152,7 +152,9 @@ public class ForwardingCookieHandler extends CookieHandler {
|
||||
|| (message != null
|
||||
&& (message.contains("WebView provider")
|
||||
|| message.contains("No WebView installed")
|
||||
|| message.contains("Cannot load WebView")))) {
|
||||
|| message.contains("Cannot load WebView")
|
||||
|| message.contains("disableWebView")
|
||||
|| message.contains("WebView is disabled")))) {
|
||||
return null;
|
||||
} else {
|
||||
throw exception;
|
||||
|
||||
+2
-2
@@ -16,7 +16,7 @@ import java.util.Map;
|
||||
public class ReactNativeVersion {
|
||||
public static final Map<String, Object> VERSION = MapBuilder.<String, Object>of(
|
||||
"major", 0,
|
||||
"minor", 0,
|
||||
"patch", 0,
|
||||
"minor", 70,
|
||||
"patch", 9,
|
||||
"prerelease", null);
|
||||
}
|
||||
|
||||
@@ -287,7 +287,9 @@ public abstract class BaseViewManager<T extends View, C extends LayoutShadowNode
|
||||
view.setSelected(false);
|
||||
}
|
||||
view.setTag(R.id.accessibility_state, accessibilityState);
|
||||
view.setEnabled(true);
|
||||
if (accessibilityState.hasKey("disabled") && !accessibilityState.getBoolean("disabled")) {
|
||||
view.setEnabled(true);
|
||||
}
|
||||
|
||||
// For states which don't have corresponding methods in
|
||||
// AccessibilityNodeInfo, update the view's content description
|
||||
|
||||
@@ -278,14 +278,16 @@ public class ViewProps {
|
||||
}
|
||||
return true;
|
||||
case BORDER_LEFT_COLOR:
|
||||
return !map.isNull(BORDER_LEFT_COLOR) && map.getInt(BORDER_LEFT_COLOR) == Color.TRANSPARENT;
|
||||
return map.getType(BORDER_LEFT_COLOR) == ReadableType.Number
|
||||
&& map.getInt(BORDER_LEFT_COLOR) == Color.TRANSPARENT;
|
||||
case BORDER_RIGHT_COLOR:
|
||||
return !map.isNull(BORDER_RIGHT_COLOR)
|
||||
return map.getType(BORDER_RIGHT_COLOR) == ReadableType.Number
|
||||
&& map.getInt(BORDER_RIGHT_COLOR) == Color.TRANSPARENT;
|
||||
case BORDER_TOP_COLOR:
|
||||
return !map.isNull(BORDER_TOP_COLOR) && map.getInt(BORDER_TOP_COLOR) == Color.TRANSPARENT;
|
||||
return map.getType(BORDER_TOP_COLOR) == ReadableType.Number
|
||||
&& map.getInt(BORDER_TOP_COLOR) == Color.TRANSPARENT;
|
||||
case BORDER_BOTTOM_COLOR:
|
||||
return !map.isNull(BORDER_BOTTOM_COLOR)
|
||||
return map.getType(BORDER_BOTTOM_COLOR) == ReadableType.Number
|
||||
&& map.getInt(BORDER_BOTTOM_COLOR) == Color.TRANSPARENT;
|
||||
case BORDER_WIDTH:
|
||||
return map.isNull(BORDER_WIDTH) || map.getDouble(BORDER_WIDTH) == 0d;
|
||||
|
||||
@@ -37,6 +37,10 @@ public class CustomLetterSpacingSpan extends MetricAffectingSpan implements Reac
|
||||
apply(paint);
|
||||
}
|
||||
|
||||
public float getSpacing() {
|
||||
return mLetterSpacing;
|
||||
}
|
||||
|
||||
private void apply(TextPaint paint) {
|
||||
if (!Float.isNaN(mLetterSpacing)) {
|
||||
paint.setLetterSpacing(mLetterSpacing);
|
||||
|
||||
@@ -71,6 +71,10 @@ public class CustomStyleSpan extends MetricAffectingSpan implements ReactSpan {
|
||||
return mFontFamily;
|
||||
}
|
||||
|
||||
public @Nullable String getFontFeatureSettings() {
|
||||
return mFeatureSettings;
|
||||
}
|
||||
|
||||
private static void apply(
|
||||
Paint paint,
|
||||
int style,
|
||||
|
||||
@@ -31,8 +31,6 @@ public class ReactTextUpdate {
|
||||
private final int mSelectionEnd;
|
||||
private final int mJustificationMode;
|
||||
|
||||
public boolean mContainsMultipleFragments;
|
||||
|
||||
/**
|
||||
* @deprecated Use a non-deprecated constructor for ReactTextUpdate instead. This one remains
|
||||
* because it's being used by a unit test that isn't currently open source.
|
||||
@@ -142,13 +140,11 @@ public class ReactTextUpdate {
|
||||
int jsEventCounter,
|
||||
int textAlign,
|
||||
int textBreakStrategy,
|
||||
int justificationMode,
|
||||
boolean containsMultipleFragments) {
|
||||
int justificationMode) {
|
||||
|
||||
ReactTextUpdate reactTextUpdate =
|
||||
new ReactTextUpdate(
|
||||
text, jsEventCounter, false, textAlign, textBreakStrategy, justificationMode);
|
||||
reactTextUpdate.mContainsMultipleFragments = containsMultipleFragments;
|
||||
return reactTextUpdate;
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,6 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
private boolean mContainsImages;
|
||||
private final int mDefaultGravityHorizontal;
|
||||
private final int mDefaultGravityVertical;
|
||||
private int mTextAlign;
|
||||
private int mNumberOfLines;
|
||||
private TextUtils.TruncateAt mEllipsizeLocation;
|
||||
private boolean mAdjustsFontSizeToFit;
|
||||
@@ -69,8 +68,7 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
super(context);
|
||||
|
||||
// Get these defaults only during the constructor - these should never be set otherwise
|
||||
mDefaultGravityHorizontal =
|
||||
getGravity() & (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
||||
mDefaultGravityHorizontal = getGravityHorizontal();
|
||||
mDefaultGravityVertical = getGravity() & Gravity.VERTICAL_GRAVITY_MASK;
|
||||
|
||||
initView();
|
||||
@@ -89,10 +87,10 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
|
||||
mReactBackgroundManager = new ReactViewBackgroundManager(this);
|
||||
|
||||
mTextAlign = Gravity.NO_GRAVITY;
|
||||
mNumberOfLines = ViewDefaults.NUMBER_OF_LINES;
|
||||
mAdjustsFontSizeToFit = false;
|
||||
mLinkifyMaskType = 0;
|
||||
mNotifyOnInlineViewLayout = false;
|
||||
mTextIsSelectable = false;
|
||||
mEllipsizeLocation = TextUtils.TruncateAt.END;
|
||||
|
||||
@@ -392,10 +390,9 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
}
|
||||
|
||||
int nextTextAlign = update.getTextAlign();
|
||||
if (mTextAlign != nextTextAlign) {
|
||||
mTextAlign = nextTextAlign;
|
||||
if (nextTextAlign != getGravityHorizontal()) {
|
||||
setGravityHorizontal(nextTextAlign);
|
||||
}
|
||||
setGravityHorizontal(mTextAlign);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
if (getBreakStrategy() != update.getTextBreakStrategy()) {
|
||||
setBreakStrategy(update.getTextBreakStrategy());
|
||||
@@ -552,6 +549,11 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie
|
||||
return false;
|
||||
}
|
||||
|
||||
/* package */ int getGravityHorizontal() {
|
||||
return getGravity()
|
||||
& (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
||||
}
|
||||
|
||||
/* package */ void setGravityHorizontal(int gravityHorizontal) {
|
||||
if (gravityHorizontal == 0) {
|
||||
gravityHorizontal = mDefaultGravityHorizontal;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
package com.facebook.react.views.text;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Build;
|
||||
import android.text.Spannable;
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -24,6 +25,7 @@ import com.facebook.react.uimanager.ReactAccessibilityDelegate;
|
||||
import com.facebook.react.uimanager.ReactStylesDiffMap;
|
||||
import com.facebook.react.uimanager.StateWrapper;
|
||||
import com.facebook.react.uimanager.ThemedReactContext;
|
||||
import com.facebook.react.uimanager.ViewProps;
|
||||
import com.facebook.yoga.YogaMeasureMode;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
@@ -152,15 +154,19 @@ public class ReactTextViewManager
|
||||
view.setSpanned(spanned);
|
||||
|
||||
int textBreakStrategy =
|
||||
TextAttributeProps.getTextBreakStrategy(paragraphAttributes.getString("textBreakStrategy"));
|
||||
TextAttributeProps.getTextBreakStrategy(
|
||||
paragraphAttributes.getString(ViewProps.TEXT_BREAK_STRATEGY));
|
||||
int currentJustificationMode =
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
||||
|
||||
return new ReactTextUpdate(
|
||||
spanned,
|
||||
state.hasKey("mostRecentEventCount") ? state.getInt("mostRecentEventCount") : -1,
|
||||
false, // TODO add this into local Data
|
||||
TextAttributeProps.getTextAlignment(props, TextLayoutManager.isRTL(attributedString)),
|
||||
TextAttributeProps.getTextAlignment(
|
||||
props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()),
|
||||
textBreakStrategy,
|
||||
TextAttributeProps.getJustificationMode(props));
|
||||
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
||||
}
|
||||
|
||||
private Object getReactTextUpdate(ReactTextView view, ReactStylesDiffMap props, MapBuffer state) {
|
||||
@@ -175,15 +181,17 @@ public class ReactTextViewManager
|
||||
int textBreakStrategy =
|
||||
TextAttributeProps.getTextBreakStrategy(
|
||||
paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY));
|
||||
int currentJustificationMode =
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
||||
|
||||
return new ReactTextUpdate(
|
||||
spanned,
|
||||
-1, // UNUSED FOR TEXT
|
||||
false, // TODO add this into local Data
|
||||
TextAttributeProps.getTextAlignment(
|
||||
props, TextLayoutManagerMapBuffer.isRTL(attributedString)),
|
||||
props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()),
|
||||
textBreakStrategy,
|
||||
TextAttributeProps.getJustificationMode(props));
|
||||
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -249,35 +249,35 @@ public class TextAttributeProps {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static int getTextAlignment(ReactStylesDiffMap props, boolean isRTL) {
|
||||
@Nullable
|
||||
String textAlignPropValue =
|
||||
props.hasKey(ViewProps.TEXT_ALIGN) ? props.getString(ViewProps.TEXT_ALIGN) : null;
|
||||
int textAlignment;
|
||||
public static int getTextAlignment(ReactStylesDiffMap props, boolean isRTL, int defaultValue) {
|
||||
if (!props.hasKey(ViewProps.TEXT_ALIGN)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
String textAlignPropValue = props.getString(ViewProps.TEXT_ALIGN);
|
||||
if ("justify".equals(textAlignPropValue)) {
|
||||
textAlignment = Gravity.LEFT;
|
||||
return Gravity.LEFT;
|
||||
} else {
|
||||
if (textAlignPropValue == null || "auto".equals(textAlignPropValue)) {
|
||||
textAlignment = Gravity.NO_GRAVITY;
|
||||
return Gravity.NO_GRAVITY;
|
||||
} else if ("left".equals(textAlignPropValue)) {
|
||||
textAlignment = isRTL ? Gravity.RIGHT : Gravity.LEFT;
|
||||
return isRTL ? Gravity.RIGHT : Gravity.LEFT;
|
||||
} else if ("right".equals(textAlignPropValue)) {
|
||||
textAlignment = isRTL ? Gravity.LEFT : Gravity.RIGHT;
|
||||
return isRTL ? Gravity.LEFT : Gravity.RIGHT;
|
||||
} else if ("center".equals(textAlignPropValue)) {
|
||||
textAlignment = Gravity.CENTER_HORIZONTAL;
|
||||
return Gravity.CENTER_HORIZONTAL;
|
||||
} else {
|
||||
throw new JSApplicationIllegalArgumentException("Invalid textAlign: " + textAlignPropValue);
|
||||
}
|
||||
}
|
||||
return textAlignment;
|
||||
}
|
||||
|
||||
public static int getJustificationMode(ReactStylesDiffMap props) {
|
||||
@Nullable
|
||||
String textAlignPropValue =
|
||||
props.hasKey(ViewProps.TEXT_ALIGN) ? props.getString(ViewProps.TEXT_ALIGN) : null;
|
||||
public static int getJustificationMode(ReactStylesDiffMap props, int defaultValue) {
|
||||
if (!props.hasKey(ViewProps.TEXT_ALIGN)) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
String textAlignPropValue = props.getString(ViewProps.TEXT_ALIGN);
|
||||
if ("justify".equals(textAlignPropValue) && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
return Layout.JUSTIFICATION_MODE_INTER_WORD;
|
||||
}
|
||||
|
||||
+5
@@ -106,6 +106,11 @@ public class TextLayoutManagerMapBuffer {
|
||||
|
||||
MapBuffer fragment = fragments.getMapBuffer((short) 0);
|
||||
MapBuffer textAttributes = fragment.getMapBuffer(FR_KEY_TEXT_ATTRIBUTES);
|
||||
|
||||
if (!textAttributes.contains(TextAttributeProps.TA_KEY_LAYOUT_DIRECTION)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return TextAttributeProps.getLayoutDirection(
|
||||
textAttributes.getString(TextAttributeProps.TA_KEY_LAYOUT_DIRECTION))
|
||||
== LayoutDirection.RTL;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "YOGA_TARGET", "react_native_dep", "react_native_target", "rn_android_library")
|
||||
load("//tools/build_defs/oss:rn_defs.bzl", "IS_OSS_BUILD", "YOGA_TARGET", "react_native_android_toplevel_dep", "react_native_dep", "react_native_target", "rn_android_library")
|
||||
|
||||
# TODO(T115916830): Remove when Kotlin files are used in this module
|
||||
KOTLIN_STDLIB_DEPS = [react_native_android_toplevel_dep("third-party/kotlin:kotlin-stdlib")] if IS_OSS_BUILD else []
|
||||
|
||||
rn_android_library(
|
||||
name = "textinput",
|
||||
@@ -9,7 +12,8 @@ rn_android_library(
|
||||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
"supermodule:xplat/default/public.react_native.infra",
|
||||
],
|
||||
language = "JAVA",
|
||||
language = "KOTLIN",
|
||||
pure_kotlin = False,
|
||||
required_for_source_only_abi = True,
|
||||
visibility = [
|
||||
"PUBLIC",
|
||||
@@ -29,8 +33,10 @@ rn_android_library(
|
||||
react_native_target("java/com/facebook/react/views/imagehelper:imagehelper"),
|
||||
react_native_target("java/com/facebook/react/views/scroll:scroll"),
|
||||
react_native_target("java/com/facebook/react/views/text:text"),
|
||||
react_native_target("java/com/facebook/react/common/mapbuffer:mapbuffer"),
|
||||
react_native_target("java/com/facebook/react/views/view:view"),
|
||||
],
|
||||
react_native_target("java/com/facebook/react/config:config"),
|
||||
] + KOTLIN_STDLIB_DEPS,
|
||||
exported_deps = [
|
||||
react_native_dep("third-party/android/androidx:appcompat"),
|
||||
],
|
||||
|
||||
+212
-100
@@ -11,6 +11,8 @@ import static com.facebook.react.uimanager.UIManagerHelper.getReactContext;
|
||||
import static com.facebook.react.views.text.TextAttributeProps.UNSET;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -50,15 +52,19 @@ import com.facebook.react.views.text.CustomLetterSpacingSpan;
|
||||
import com.facebook.react.views.text.CustomLineHeightSpan;
|
||||
import com.facebook.react.views.text.CustomStyleSpan;
|
||||
import com.facebook.react.views.text.ReactAbsoluteSizeSpan;
|
||||
import com.facebook.react.views.text.ReactBackgroundColorSpan;
|
||||
import com.facebook.react.views.text.ReactForegroundColorSpan;
|
||||
import com.facebook.react.views.text.ReactSpan;
|
||||
import com.facebook.react.views.text.ReactStrikethroughSpan;
|
||||
import com.facebook.react.views.text.ReactTextUpdate;
|
||||
import com.facebook.react.views.text.ReactTypefaceUtils;
|
||||
import com.facebook.react.views.text.ReactUnderlineSpan;
|
||||
import com.facebook.react.views.text.TextAttributes;
|
||||
import com.facebook.react.views.text.TextInlineImageSpan;
|
||||
import com.facebook.react.views.text.TextLayoutManager;
|
||||
import com.facebook.react.views.view.ReactViewBackgroundManager;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A wrapper around the EditText that lets us better control what happens when an EditText gets
|
||||
@@ -82,7 +88,6 @@ public class ReactEditText extends AppCompatEditText
|
||||
// *TextChanged events should be triggered. This is less expensive than removing the text
|
||||
// listeners and adding them back again after the text change is completed.
|
||||
protected boolean mIsSettingTextFromJS;
|
||||
protected boolean mIsSettingTextFromCacheUpdate = false;
|
||||
private int mDefaultGravityHorizontal;
|
||||
private int mDefaultGravityVertical;
|
||||
|
||||
@@ -363,7 +368,7 @@ public class ReactEditText extends AppCompatEditText
|
||||
}
|
||||
|
||||
super.onSelectionChanged(selStart, selEnd);
|
||||
if (!mIsSettingTextFromCacheUpdate && mSelectionWatcher != null && hasFocus()) {
|
||||
if (mSelectionWatcher != null && hasFocus()) {
|
||||
mSelectionWatcher.onSelectionChanged(selStart, selEnd);
|
||||
}
|
||||
}
|
||||
@@ -482,6 +487,14 @@ public class ReactEditText extends AppCompatEditText
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setFontFeatureSettings(String fontFeatureSettings) {
|
||||
if (!Objects.equals(fontFeatureSettings, getFontFeatureSettings())) {
|
||||
super.setFontFeatureSettings(fontFeatureSettings);
|
||||
mTypefaceDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
public void maybeUpdateTypeface() {
|
||||
if (!mTypefaceDirty) {
|
||||
return;
|
||||
@@ -493,6 +506,17 @@ public class ReactEditText extends AppCompatEditText
|
||||
ReactTypefaceUtils.applyStyles(
|
||||
getTypeface(), mFontStyle, mFontWeight, mFontFamily, getContext().getAssets());
|
||||
setTypeface(newTypeface);
|
||||
|
||||
// Match behavior of CustomStyleSpan and enable SUBPIXEL_TEXT_FLAG when setting anything
|
||||
// nonstandard
|
||||
if (mFontStyle != UNSET
|
||||
|| mFontWeight != UNSET
|
||||
|| mFontFamily != null
|
||||
|| getFontFeatureSettings() != null) {
|
||||
setPaintFlags(getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG);
|
||||
} else {
|
||||
setPaintFlags(getPaintFlags() & (~Paint.SUBPIXEL_TEXT_FLAG));
|
||||
}
|
||||
}
|
||||
|
||||
// VisibleForTesting from {@link TextInputEventsTestCase}.
|
||||
@@ -554,7 +578,9 @@ public class ReactEditText extends AppCompatEditText
|
||||
SpannableStringBuilder spannableStringBuilder =
|
||||
new SpannableStringBuilder(reactTextUpdate.getText());
|
||||
|
||||
manageSpans(spannableStringBuilder, reactTextUpdate.mContainsMultipleFragments);
|
||||
manageSpans(spannableStringBuilder);
|
||||
stripStyleEquivalentSpans(spannableStringBuilder);
|
||||
|
||||
mContainsImages = reactTextUpdate.containsImages();
|
||||
|
||||
// When we update text, we trigger onChangeText code that will
|
||||
@@ -581,7 +607,7 @@ public class ReactEditText extends AppCompatEditText
|
||||
}
|
||||
|
||||
// Update cached spans (in Fabric only).
|
||||
updateCachedSpannable(false);
|
||||
updateCachedSpannable();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -590,8 +616,7 @@ public class ReactEditText extends AppCompatEditText
|
||||
* will adapt to the new text, hence why {@link SpannableStringBuilder#replace} never removes
|
||||
* them.
|
||||
*/
|
||||
private void manageSpans(
|
||||
SpannableStringBuilder spannableStringBuilder, boolean skipAddSpansForMeasurements) {
|
||||
private void manageSpans(SpannableStringBuilder spannableStringBuilder) {
|
||||
Object[] spans = getText().getSpans(0, length(), Object.class);
|
||||
for (int spanIdx = 0; spanIdx < spans.length; spanIdx++) {
|
||||
Object span = spans[spanIdx];
|
||||
@@ -619,12 +644,170 @@ public class ReactEditText extends AppCompatEditText
|
||||
spannableStringBuilder.setSpan(span, spanStart, spanEnd, spanFlags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// In Fabric only, apply necessary styles to entire span
|
||||
// If the Spannable was constructed from multiple fragments, we don't apply any spans that could
|
||||
// impact the whole Spannable, because that would override "local" styles per-fragment
|
||||
if (!skipAddSpansForMeasurements) {
|
||||
addSpansForMeasurement(getText());
|
||||
// TODO: Replace with Predicate<T> and lambdas once Java 8 builds in OSS
|
||||
interface SpanPredicate<T> {
|
||||
boolean test(T span);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove spans from the SpannableStringBuilder which can be represented by TextAppearance
|
||||
* attributes on the underlying EditText. This works around instability on Samsung devices with
|
||||
* the presence of spans https://github.com/facebook/react-native/issues/35936 (S318090)
|
||||
*/
|
||||
private void stripStyleEquivalentSpans(SpannableStringBuilder sb) {
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
ReactAbsoluteSizeSpan.class,
|
||||
new SpanPredicate<ReactAbsoluteSizeSpan>() {
|
||||
@Override
|
||||
public boolean test(ReactAbsoluteSizeSpan span) {
|
||||
return span.getSize() == mTextAttributes.getEffectiveFontSize();
|
||||
}
|
||||
});
|
||||
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
ReactBackgroundColorSpan.class,
|
||||
new SpanPredicate<ReactBackgroundColorSpan>() {
|
||||
@Override
|
||||
public boolean test(ReactBackgroundColorSpan span) {
|
||||
return span.getBackgroundColor() == mReactBackgroundManager.getBackgroundColor();
|
||||
}
|
||||
});
|
||||
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
ReactForegroundColorSpan.class,
|
||||
new SpanPredicate<ReactForegroundColorSpan>() {
|
||||
@Override
|
||||
public boolean test(ReactForegroundColorSpan span) {
|
||||
return span.getForegroundColor() == getCurrentTextColor();
|
||||
}
|
||||
});
|
||||
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
ReactStrikethroughSpan.class,
|
||||
new SpanPredicate<ReactStrikethroughSpan>() {
|
||||
@Override
|
||||
public boolean test(ReactStrikethroughSpan span) {
|
||||
return (getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0;
|
||||
}
|
||||
});
|
||||
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
ReactUnderlineSpan.class,
|
||||
new SpanPredicate<ReactUnderlineSpan>() {
|
||||
@Override
|
||||
public boolean test(ReactUnderlineSpan span) {
|
||||
return (getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0;
|
||||
}
|
||||
});
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
CustomLetterSpacingSpan.class,
|
||||
new SpanPredicate<CustomLetterSpacingSpan>() {
|
||||
@Override
|
||||
public boolean test(CustomLetterSpacingSpan span) {
|
||||
return span.getSpacing() == mTextAttributes.getEffectiveLetterSpacing();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
stripSpansOfKind(
|
||||
sb,
|
||||
CustomStyleSpan.class,
|
||||
new SpanPredicate<CustomStyleSpan>() {
|
||||
@Override
|
||||
public boolean test(CustomStyleSpan span) {
|
||||
return span.getStyle() == mFontStyle
|
||||
&& Objects.equals(span.getFontFamily(), mFontFamily)
|
||||
&& span.getWeight() == mFontWeight
|
||||
&& Objects.equals(span.getFontFeatureSettings(), getFontFeatureSettings());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private <T> void stripSpansOfKind(
|
||||
SpannableStringBuilder sb, Class<T> clazz, SpanPredicate<T> shouldStrip) {
|
||||
T[] spans = sb.getSpans(0, sb.length(), clazz);
|
||||
|
||||
for (T span : spans) {
|
||||
if (shouldStrip.test(span)) {
|
||||
sb.removeSpan(span);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy styles represented as attributes to the underlying span, for later measurement or other
|
||||
* usage outside the ReactEditText.
|
||||
*/
|
||||
private void addSpansFromStyleAttributes(SpannableStringBuilder workingText) {
|
||||
int spanFlags = Spannable.SPAN_INCLUSIVE_INCLUSIVE;
|
||||
|
||||
// Set all bits for SPAN_PRIORITY so that this span has the highest possible priority
|
||||
// (least precedence). This ensures the span is behind any overlapping spans.
|
||||
spanFlags |= Spannable.SPAN_PRIORITY;
|
||||
|
||||
workingText.setSpan(
|
||||
new ReactAbsoluteSizeSpan(mTextAttributes.getEffectiveFontSize()),
|
||||
0,
|
||||
workingText.length(),
|
||||
spanFlags);
|
||||
|
||||
workingText.setSpan(
|
||||
new ReactForegroundColorSpan(getCurrentTextColor()), 0, workingText.length(), spanFlags);
|
||||
|
||||
int backgroundColor = mReactBackgroundManager.getBackgroundColor();
|
||||
if (backgroundColor != Color.TRANSPARENT) {
|
||||
workingText.setSpan(
|
||||
new ReactBackgroundColorSpan(backgroundColor), 0, workingText.length(), spanFlags);
|
||||
}
|
||||
|
||||
if ((getPaintFlags() & Paint.STRIKE_THRU_TEXT_FLAG) != 0) {
|
||||
workingText.setSpan(new ReactStrikethroughSpan(), 0, workingText.length(), spanFlags);
|
||||
}
|
||||
|
||||
if ((getPaintFlags() & Paint.UNDERLINE_TEXT_FLAG) != 0) {
|
||||
workingText.setSpan(new ReactUnderlineSpan(), 0, workingText.length(), spanFlags);
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
float effectiveLetterSpacing = mTextAttributes.getEffectiveLetterSpacing();
|
||||
if (!Float.isNaN(effectiveLetterSpacing)) {
|
||||
workingText.setSpan(
|
||||
new CustomLetterSpacingSpan(effectiveLetterSpacing),
|
||||
0,
|
||||
workingText.length(),
|
||||
spanFlags);
|
||||
}
|
||||
}
|
||||
|
||||
if (mFontStyle != UNSET
|
||||
|| mFontWeight != UNSET
|
||||
|| mFontFamily != null
|
||||
|| getFontFeatureSettings() != null) {
|
||||
workingText.setSpan(
|
||||
new CustomStyleSpan(
|
||||
mFontStyle,
|
||||
mFontWeight,
|
||||
getFontFeatureSettings(),
|
||||
mFontFamily,
|
||||
getContext().getAssets()),
|
||||
0,
|
||||
workingText.length(),
|
||||
spanFlags);
|
||||
}
|
||||
|
||||
float lineHeight = mTextAttributes.getEffectiveLineHeight();
|
||||
if (!Float.isNaN(lineHeight)) {
|
||||
workingText.setSpan(new CustomLineHeightSpan(lineHeight), 0, workingText.length(), spanFlags);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -644,73 +827,6 @@ public class ReactEditText extends AppCompatEditText
|
||||
return true;
|
||||
}
|
||||
|
||||
// This is hacked in for Fabric. When we delete non-Fabric code, we might be able to simplify or
|
||||
// clean this up a bit.
|
||||
private void addSpansForMeasurement(Spannable spannable) {
|
||||
if (!mFabricViewStateManager.hasStateWrapper()) {
|
||||
return;
|
||||
}
|
||||
|
||||
boolean originalDisableTextDiffing = mDisableTextDiffing;
|
||||
mDisableTextDiffing = true;
|
||||
|
||||
int start = 0;
|
||||
int end = spannable.length();
|
||||
|
||||
// Remove duplicate spans we might add here
|
||||
Object[] spans = spannable.getSpans(0, length(), Object.class);
|
||||
for (Object span : spans) {
|
||||
int spanFlags = spannable.getSpanFlags(span);
|
||||
boolean isInclusive =
|
||||
(spanFlags & Spanned.SPAN_INCLUSIVE_INCLUSIVE) == Spanned.SPAN_INCLUSIVE_INCLUSIVE
|
||||
|| (spanFlags & Spanned.SPAN_INCLUSIVE_EXCLUSIVE) == Spanned.SPAN_INCLUSIVE_EXCLUSIVE;
|
||||
if (isInclusive
|
||||
&& span instanceof ReactSpan
|
||||
&& spannable.getSpanStart(span) == start
|
||||
&& spannable.getSpanEnd(span) == end) {
|
||||
spannable.removeSpan(span);
|
||||
}
|
||||
}
|
||||
|
||||
List<TextLayoutManager.SetSpanOperation> ops = new ArrayList<>();
|
||||
|
||||
if (!Float.isNaN(mTextAttributes.getLetterSpacing())) {
|
||||
ops.add(
|
||||
new TextLayoutManager.SetSpanOperation(
|
||||
start, end, new CustomLetterSpacingSpan(mTextAttributes.getLetterSpacing())));
|
||||
}
|
||||
ops.add(
|
||||
new TextLayoutManager.SetSpanOperation(
|
||||
start, end, new ReactAbsoluteSizeSpan((int) mTextAttributes.getEffectiveFontSize())));
|
||||
if (mFontStyle != UNSET || mFontWeight != UNSET || mFontFamily != null) {
|
||||
ops.add(
|
||||
new TextLayoutManager.SetSpanOperation(
|
||||
start,
|
||||
end,
|
||||
new CustomStyleSpan(
|
||||
mFontStyle,
|
||||
mFontWeight,
|
||||
null, // TODO: do we need to support FontFeatureSettings / fontVariant?
|
||||
mFontFamily,
|
||||
getReactContext(ReactEditText.this).getAssets())));
|
||||
}
|
||||
if (!Float.isNaN(mTextAttributes.getEffectiveLineHeight())) {
|
||||
ops.add(
|
||||
new TextLayoutManager.SetSpanOperation(
|
||||
start, end, new CustomLineHeightSpan(mTextAttributes.getEffectiveLineHeight())));
|
||||
}
|
||||
|
||||
int priority = 0;
|
||||
for (TextLayoutManager.SetSpanOperation op : ops) {
|
||||
// Actual order of calling {@code execute} does NOT matter,
|
||||
// but the {@code priority} DOES matter.
|
||||
op.execute(spannable, priority);
|
||||
priority++;
|
||||
}
|
||||
|
||||
mDisableTextDiffing = originalDisableTextDiffing;
|
||||
}
|
||||
|
||||
protected boolean showSoftKeyboard() {
|
||||
return mInputMethodManager.showSoftInput(this, 0);
|
||||
}
|
||||
@@ -765,6 +881,11 @@ public class ReactEditText extends AppCompatEditText
|
||||
}
|
||||
}
|
||||
|
||||
/* package */ int getGravityHorizontal() {
|
||||
return getGravity()
|
||||
& (Gravity.HORIZONTAL_GRAVITY_MASK | Gravity.RELATIVE_HORIZONTAL_GRAVITY_MASK);
|
||||
}
|
||||
|
||||
/* package */ void setGravityHorizontal(int gravityHorizontal) {
|
||||
if (gravityHorizontal == 0) {
|
||||
gravityHorizontal = mDefaultGravityHorizontal;
|
||||
@@ -975,7 +1096,9 @@ public class ReactEditText extends AppCompatEditText
|
||||
|
||||
float effectiveLetterSpacing = mTextAttributes.getEffectiveLetterSpacing();
|
||||
if (!Float.isNaN(effectiveLetterSpacing)) {
|
||||
setLetterSpacing(effectiveLetterSpacing);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
setLetterSpacing(effectiveLetterSpacing);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -990,7 +1113,7 @@ public class ReactEditText extends AppCompatEditText
|
||||
* TextLayoutManager.java with some very minor modifications. There's some duplication between
|
||||
* here and TextLayoutManager, so there might be an opportunity for refactor.
|
||||
*/
|
||||
private void updateCachedSpannable(boolean resetStyles) {
|
||||
private void updateCachedSpannable() {
|
||||
// Noops in non-Fabric
|
||||
if (mFabricViewStateManager == null || !mFabricViewStateManager.hasStateWrapper()) {
|
||||
return;
|
||||
@@ -1000,12 +1123,6 @@ public class ReactEditText extends AppCompatEditText
|
||||
return;
|
||||
}
|
||||
|
||||
if (resetStyles) {
|
||||
mIsSettingTextFromCacheUpdate = true;
|
||||
addSpansForMeasurement(getText());
|
||||
mIsSettingTextFromCacheUpdate = false;
|
||||
}
|
||||
|
||||
Editable currentText = getText();
|
||||
boolean haveText = currentText != null && currentText.length() > 0;
|
||||
|
||||
@@ -1063,11 +1180,9 @@ public class ReactEditText extends AppCompatEditText
|
||||
// Measure something so we have correct height, even if there's no string.
|
||||
sb.append("I");
|
||||
}
|
||||
|
||||
// Make sure that all text styles are applied when we're measurable the hint or "blank" text
|
||||
addSpansForMeasurement(sb);
|
||||
}
|
||||
|
||||
addSpansFromStyleAttributes(sb);
|
||||
TextLayoutManager.setCachedSpannabledForTag(getId(), sb);
|
||||
}
|
||||
|
||||
@@ -1082,7 +1197,7 @@ public class ReactEditText extends AppCompatEditText
|
||||
private class TextWatcherDelegator implements TextWatcher {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
if (!mIsSettingTextFromCacheUpdate && !mIsSettingTextFromJS && mListeners != null) {
|
||||
if (!mIsSettingTextFromJS && mListeners != null) {
|
||||
for (TextWatcher listener : mListeners) {
|
||||
listener.beforeTextChanged(s, start, count, after);
|
||||
}
|
||||
@@ -1096,23 +1211,20 @@ public class ReactEditText extends AppCompatEditText
|
||||
TAG, "onTextChanged[" + getId() + "]: " + s + " " + start + " " + before + " " + count);
|
||||
}
|
||||
|
||||
if (!mIsSettingTextFromCacheUpdate) {
|
||||
if (!mIsSettingTextFromJS && mListeners != null) {
|
||||
for (TextWatcher listener : mListeners) {
|
||||
listener.onTextChanged(s, start, before, count);
|
||||
}
|
||||
if (!mIsSettingTextFromJS && mListeners != null) {
|
||||
for (TextWatcher listener : mListeners) {
|
||||
listener.onTextChanged(s, start, before, count);
|
||||
}
|
||||
|
||||
updateCachedSpannable(
|
||||
!mIsSettingTextFromJS && !mIsSettingTextFromState && start == 0 && before == 0);
|
||||
}
|
||||
|
||||
updateCachedSpannable();
|
||||
|
||||
onContentSizeChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
if (!mIsSettingTextFromCacheUpdate && !mIsSettingTextFromJS && mListeners != null) {
|
||||
if (!mIsSettingTextFromJS && mListeners != null) {
|
||||
for (TextWatcher listener : mListeners) {
|
||||
listener.afterTextChanged(s);
|
||||
}
|
||||
|
||||
+78
-11
@@ -13,6 +13,7 @@ import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.graphics.BlendMode;
|
||||
import android.graphics.BlendModeColorFilter;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Build;
|
||||
@@ -44,6 +45,8 @@ import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.WritableNativeMap;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.common.mapbuffer.MapBuffer;
|
||||
import com.facebook.react.config.ReactFeatureFlags;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
import com.facebook.react.uimanager.BaseViewManager;
|
||||
import com.facebook.react.uimanager.FabricViewStateManager;
|
||||
@@ -66,9 +69,11 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil;
|
||||
import com.facebook.react.views.text.ReactBaseTextShadowNode;
|
||||
import com.facebook.react.views.text.ReactTextUpdate;
|
||||
import com.facebook.react.views.text.ReactTextViewManagerCallback;
|
||||
import com.facebook.react.views.text.ReactTypefaceUtils;
|
||||
import com.facebook.react.views.text.TextAttributeProps;
|
||||
import com.facebook.react.views.text.TextInlineImageSpan;
|
||||
import com.facebook.react.views.text.TextLayoutManager;
|
||||
import com.facebook.react.views.text.TextLayoutManagerMapBuffer;
|
||||
import com.facebook.react.views.text.TextTransform;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import java.lang.reflect.Field;
|
||||
@@ -83,6 +88,12 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
public static final String TAG = ReactTextInputManager.class.getSimpleName();
|
||||
public static final String REACT_CLASS = "AndroidTextInput";
|
||||
|
||||
// See also ReactTextViewManager
|
||||
private static final short TX_STATE_KEY_ATTRIBUTED_STRING = 0;
|
||||
private static final short TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
|
||||
private static final short TX_STATE_KEY_HASH = 2;
|
||||
private static final short TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
|
||||
|
||||
private static final int[] SPACING_TYPES = {
|
||||
Spacing.ALL, Spacing.LEFT, Spacing.RIGHT, Spacing.TOP, Spacing.BOTTOM,
|
||||
};
|
||||
@@ -396,6 +407,11 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
view.setFontStyle(fontStyle);
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.FONT_VARIANT)
|
||||
public void setFontVariant(ReactEditText view, @Nullable ReadableArray fontVariant) {
|
||||
view.setFontFeatureSettings(ReactTypefaceUtils.parseFontVariant(fontVariant));
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.INCLUDE_FONT_PADDING, defaultBoolean = true)
|
||||
public void setIncludeFontPadding(ReactEditText view, boolean includepad) {
|
||||
view.setIncludeFontPadding(includepad);
|
||||
@@ -912,6 +928,20 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
view.setAutoFocus(autoFocus);
|
||||
}
|
||||
|
||||
@ReactProp(name = ViewProps.TEXT_DECORATION_LINE)
|
||||
public void setTextDecorationLine(ReactEditText view, @Nullable String textDecorationLineString) {
|
||||
view.setPaintFlags(
|
||||
view.getPaintFlags() & ~(Paint.STRIKE_THRU_TEXT_FLAG | Paint.UNDERLINE_TEXT_FLAG));
|
||||
|
||||
for (String token : textDecorationLineString.split(" ")) {
|
||||
if (token.equals("underline")) {
|
||||
view.setPaintFlags(view.getPaintFlags() | Paint.UNDERLINE_TEXT_FLAG);
|
||||
} else if (token.equals("line-through")) {
|
||||
view.setPaintFlags(view.getPaintFlags() | Paint.STRIKE_THRU_TEXT_FLAG);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ReactPropGroup(
|
||||
names = {
|
||||
ViewProps.BORDER_WIDTH,
|
||||
@@ -1284,11 +1314,15 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
|
||||
stateManager.setStateWrapper(stateWrapper);
|
||||
|
||||
ReadableNativeMap state = stateWrapper.getStateData();
|
||||
if (state == null) {
|
||||
return null;
|
||||
if (ReactFeatureFlags.mapBufferSerializationEnabled) {
|
||||
MapBuffer stateMapBuffer = stateWrapper.getStateDataMapBuffer();
|
||||
if (stateMapBuffer != null) {
|
||||
return getReactTextUpdate(view, props, stateMapBuffer);
|
||||
}
|
||||
}
|
||||
if (!state.hasKey("attributedString")) {
|
||||
|
||||
ReadableNativeMap state = stateWrapper.getStateData();
|
||||
if (state == null || !state.hasKey("attributedString")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -1302,18 +1336,51 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
TextLayoutManager.getOrCreateSpannableForText(
|
||||
view.getContext(), attributedString, mReactTextViewManagerCallback);
|
||||
|
||||
boolean containsMultipleFragments =
|
||||
attributedString.getArray("fragments").toArrayList().size() > 1;
|
||||
|
||||
int textBreakStrategy =
|
||||
TextAttributeProps.getTextBreakStrategy(paragraphAttributes.getString("textBreakStrategy"));
|
||||
TextAttributeProps.getTextBreakStrategy(
|
||||
paragraphAttributes.getString(ViewProps.TEXT_BREAK_STRATEGY));
|
||||
int currentJustificationMode =
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
||||
|
||||
return ReactTextUpdate.buildReactTextUpdateFromState(
|
||||
spanned,
|
||||
state.getInt("mostRecentEventCount"),
|
||||
TextAttributeProps.getTextAlignment(props, TextLayoutManager.isRTL(attributedString)),
|
||||
TextAttributeProps.getTextAlignment(
|
||||
props, TextLayoutManager.isRTL(attributedString), view.getGravityHorizontal()),
|
||||
textBreakStrategy,
|
||||
TextAttributeProps.getJustificationMode(props),
|
||||
containsMultipleFragments);
|
||||
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
||||
}
|
||||
|
||||
public Object getReactTextUpdate(ReactEditText view, ReactStylesDiffMap props, MapBuffer state) {
|
||||
// If native wants to update the state wrapper but the state data hasn't actually
|
||||
// changed, the MapBuffer may be empty
|
||||
if (state.getCount() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
MapBuffer attributedString = state.getMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING);
|
||||
MapBuffer paragraphAttributes = state.getMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES);
|
||||
if (attributedString == null || paragraphAttributes == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid TextInput State (MapBuffer) was received as a parameters");
|
||||
}
|
||||
|
||||
Spannable spanned =
|
||||
TextLayoutManagerMapBuffer.getOrCreateSpannableForText(
|
||||
view.getContext(), attributedString, mReactTextViewManagerCallback);
|
||||
|
||||
int textBreakStrategy =
|
||||
TextAttributeProps.getTextBreakStrategy(
|
||||
paragraphAttributes.getString(TextLayoutManagerMapBuffer.PA_KEY_TEXT_BREAK_STRATEGY));
|
||||
int currentJustificationMode =
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.O ? 0 : view.getJustificationMode();
|
||||
|
||||
return ReactTextUpdate.buildReactTextUpdateFromState(
|
||||
spanned,
|
||||
state.getInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT),
|
||||
TextAttributeProps.getTextAlignment(
|
||||
props, TextLayoutManagerMapBuffer.isRTL(attributedString), view.getGravityHorizontal()),
|
||||
textBreakStrategy,
|
||||
TextAttributeProps.getJustificationMode(props, currentJustificationMode));
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -19,6 +19,7 @@ public class ReactViewBackgroundManager {
|
||||
|
||||
private @Nullable ReactViewBackgroundDrawable mReactBackgroundDrawable;
|
||||
private View mView;
|
||||
private int mColor = Color.TRANSPARENT;
|
||||
|
||||
public ReactViewBackgroundManager(View view) {
|
||||
this.mView = view;
|
||||
@@ -56,6 +57,10 @@ public class ReactViewBackgroundManager {
|
||||
}
|
||||
}
|
||||
|
||||
public int getBackgroundColor() {
|
||||
return mColor;
|
||||
}
|
||||
|
||||
public void setBorderWidth(int position, float width) {
|
||||
getOrCreateReactViewBackground().setBorderWidth(position, width);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ static int YGJNILogFunc(
|
||||
if (*jloggerPtr) {
|
||||
JNIEnv* env = getCurrentEnv();
|
||||
|
||||
jclass cl = env->FindClass("Lcom/facebook/yoga/YogaLogLevel;");
|
||||
jclass cl = env->FindClass("com/facebook/yoga/YogaLogLevel");
|
||||
static const jmethodID smethodId =
|
||||
facebook::yoga::vanillajni::getStaticMethodId(
|
||||
env, cl, "fromInt", "(I)Lcom/facebook/yoga/YogaLogLevel;");
|
||||
@@ -386,7 +386,7 @@ static void jni_YGNodeCalculateLayoutJNI(
|
||||
}
|
||||
} catch (const std::logic_error& ex) {
|
||||
env->ExceptionClear();
|
||||
jclass cl = env->FindClass("Ljava/lang/IllegalStateException;");
|
||||
jclass cl = env->FindClass("java/lang/IllegalStateException");
|
||||
static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId(
|
||||
env, cl, "<init>", "(Ljava/lang/String;)V");
|
||||
auto throwable = env->NewObject(cl, methodId, env->NewStringUTF(ex.what()));
|
||||
|
||||
@@ -15,7 +15,7 @@ namespace yoga {
|
||||
namespace vanillajni {
|
||||
|
||||
YogaJniException::YogaJniException() {
|
||||
jclass cl = getCurrentEnv()->FindClass("Ljava/lang/RuntimeException;");
|
||||
jclass cl = getCurrentEnv()->FindClass("java/lang/RuntimeException");
|
||||
static const jmethodID methodId = facebook::yoga::vanillajni::getMethodId(
|
||||
getCurrentEnv(), cl, "<init>", "()V");
|
||||
auto throwable = getCurrentEnv()->NewObject(cl, methodId);
|
||||
|
||||
@@ -6,8 +6,6 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
set(CMAKE_VERBOSE_MAKEFILE on)
|
||||
|
||||
# TODO Those two libraries are building against the same sources
|
||||
# and should probably be merged
|
||||
file(GLOB reactnativejni_SRC CONFIGURE_DEPENDS *.cpp)
|
||||
|
||||
add_compile_options(
|
||||
@@ -17,32 +15,6 @@ add_compile_options(
|
||||
-std=c++17
|
||||
-DWITH_INSPECTOR=1)
|
||||
|
||||
##########################
|
||||
### React Native Utils ###
|
||||
##########################
|
||||
|
||||
add_library(
|
||||
reactnativeutilsjni
|
||||
SHARED
|
||||
${reactnativejni_SRC}
|
||||
)
|
||||
|
||||
# TODO This should not be ../../
|
||||
target_include_directories(reactnativeutilsjni PUBLIC ../../)
|
||||
|
||||
target_link_libraries(reactnativeutilsjni
|
||||
android
|
||||
callinvokerholder
|
||||
fb
|
||||
fbjni
|
||||
folly_runtime
|
||||
glog_init
|
||||
react_render_runtimescheduler
|
||||
reactnative
|
||||
runtimeexecutor
|
||||
yoga
|
||||
)
|
||||
|
||||
######################
|
||||
### reactnativejni ###
|
||||
######################
|
||||
@@ -67,7 +39,6 @@ target_link_libraries(reactnativejni
|
||||
logger
|
||||
react_render_runtimescheduler
|
||||
reactnative
|
||||
reactnativeutilsjni
|
||||
runtimeexecutor
|
||||
yoga
|
||||
)
|
||||
|
||||
@@ -16,8 +16,8 @@ namespace facebook::react {
|
||||
|
||||
constexpr struct {
|
||||
int32_t Major = 0;
|
||||
int32_t Minor = 0;
|
||||
int32_t Patch = 0;
|
||||
int32_t Minor = 70;
|
||||
int32_t Patch = 9;
|
||||
std::string_view Prerelease = "";
|
||||
} ReactNativeVersion;
|
||||
|
||||
|
||||
@@ -155,15 +155,20 @@ class DecoratedRuntime : public jsi::WithRuntimeDecorator<ReentrancyCheck> {
|
||||
DecoratedRuntime(
|
||||
std::unique_ptr<Runtime> runtime,
|
||||
HermesRuntime &hermesRuntime,
|
||||
std::shared_ptr<MessageQueueThread> jsQueue)
|
||||
std::shared_ptr<MessageQueueThread> jsQueue,
|
||||
bool enableDebugger,
|
||||
const std::string &debuggerName)
|
||||
: jsi::WithRuntimeDecorator<ReentrancyCheck>(*runtime, reentrancyCheck_),
|
||||
runtime_(std::move(runtime)),
|
||||
hermesRuntime_(hermesRuntime) {
|
||||
#ifdef HERMES_ENABLE_DEBUGGER
|
||||
auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(
|
||||
runtime_, hermesRuntime_, jsQueue);
|
||||
facebook::hermes::inspector::chrome::enableDebugging(
|
||||
std::move(adapter), "Hermes React Native");
|
||||
enableDebugger_ = enableDebugger;
|
||||
if (enableDebugger_) {
|
||||
auto adapter = std::make_unique<HermesExecutorRuntimeAdapter>(
|
||||
runtime_, hermesRuntime_, jsQueue);
|
||||
facebook::hermes::inspector::chrome::enableDebugging(
|
||||
std::move(adapter), debuggerName);
|
||||
}
|
||||
#else
|
||||
(void)hermesRuntime_;
|
||||
#endif
|
||||
@@ -171,7 +176,9 @@ class DecoratedRuntime : public jsi::WithRuntimeDecorator<ReentrancyCheck> {
|
||||
|
||||
~DecoratedRuntime() {
|
||||
#ifdef HERMES_ENABLE_DEBUGGER
|
||||
facebook::hermes::inspector::chrome::disableDebugging(*runtime_);
|
||||
if (enableDebugger_) {
|
||||
facebook::hermes::inspector::chrome::disableDebugging(*runtime_);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -186,10 +193,21 @@ class DecoratedRuntime : public jsi::WithRuntimeDecorator<ReentrancyCheck> {
|
||||
std::shared_ptr<Runtime> runtime_;
|
||||
ReentrancyCheck reentrancyCheck_;
|
||||
HermesRuntime &hermesRuntime_;
|
||||
#ifdef HERMES_ENABLE_DEBUGGER
|
||||
bool enableDebugger_;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
void HermesExecutorFactory::setEnableDebugger(bool enableDebugger) {
|
||||
enableDebugger_ = enableDebugger;
|
||||
}
|
||||
|
||||
void HermesExecutorFactory::setDebuggerName(const std::string &debuggerName) {
|
||||
debuggerName_ = debuggerName;
|
||||
}
|
||||
|
||||
std::unique_ptr<JSExecutor> HermesExecutorFactory::createJSExecutor(
|
||||
std::shared_ptr<ExecutorDelegate> delegate,
|
||||
std::shared_ptr<MessageQueueThread> jsQueue) {
|
||||
@@ -197,7 +215,11 @@ std::unique_ptr<JSExecutor> HermesExecutorFactory::createJSExecutor(
|
||||
makeHermesRuntimeSystraced(runtimeConfig_);
|
||||
HermesRuntime &hermesRuntimeRef = *hermesRuntime;
|
||||
auto decoratedRuntime = std::make_shared<DecoratedRuntime>(
|
||||
std::move(hermesRuntime), hermesRuntimeRef, jsQueue);
|
||||
std::move(hermesRuntime),
|
||||
hermesRuntimeRef,
|
||||
jsQueue,
|
||||
enableDebugger_,
|
||||
debuggerName_);
|
||||
|
||||
// So what do we have now?
|
||||
// DecoratedRuntime -> HermesRuntime
|
||||
@@ -221,6 +243,12 @@ std::unique_ptr<JSExecutor> HermesExecutorFactory::createJSExecutor(
|
||||
decoratedRuntime, delegate, jsQueue, timeoutInvoker_, runtimeInstaller_);
|
||||
}
|
||||
|
||||
::hermes::vm::RuntimeConfig HermesExecutorFactory::defaultRuntimeConfig() {
|
||||
return ::hermes::vm::RuntimeConfig::Builder()
|
||||
.withEnableSampleProfiling(true)
|
||||
.build();
|
||||
}
|
||||
|
||||
HermesExecutor::HermesExecutor(
|
||||
std::shared_ptr<jsi::Runtime> runtime,
|
||||
std::shared_ptr<ExecutorDelegate> delegate,
|
||||
|
||||
@@ -21,21 +21,29 @@ class HermesExecutorFactory : public JSExecutorFactory {
|
||||
JSIExecutor::RuntimeInstaller runtimeInstaller,
|
||||
const JSIScopedTimeoutInvoker &timeoutInvoker =
|
||||
JSIExecutor::defaultTimeoutInvoker,
|
||||
::hermes::vm::RuntimeConfig runtimeConfig = ::hermes::vm::RuntimeConfig())
|
||||
::hermes::vm::RuntimeConfig runtimeConfig = defaultRuntimeConfig())
|
||||
: runtimeInstaller_(runtimeInstaller),
|
||||
timeoutInvoker_(timeoutInvoker),
|
||||
runtimeConfig_(std::move(runtimeConfig)) {
|
||||
assert(timeoutInvoker_ && "Should not have empty timeoutInvoker");
|
||||
}
|
||||
|
||||
void setEnableDebugger(bool enableDebugger);
|
||||
|
||||
void setDebuggerName(const std::string &debuggerName);
|
||||
|
||||
std::unique_ptr<JSExecutor> createJSExecutor(
|
||||
std::shared_ptr<ExecutorDelegate> delegate,
|
||||
std::shared_ptr<MessageQueueThread> jsQueue) override;
|
||||
|
||||
private:
|
||||
static ::hermes::vm::RuntimeConfig defaultRuntimeConfig();
|
||||
|
||||
JSIExecutor::RuntimeInstaller runtimeInstaller_;
|
||||
JSIScopedTimeoutInvoker timeoutInvoker_;
|
||||
::hermes::vm::RuntimeConfig runtimeConfig_;
|
||||
bool enableDebugger_ = true;
|
||||
std::string debuggerName_ = "Hermes React Native";
|
||||
};
|
||||
|
||||
class HermesExecutor : public JSIExecutor {
|
||||
|
||||
@@ -139,7 +139,7 @@ class Connection::Impl : public inspector::InspectorObserver,
|
||||
|
||||
template <typename C>
|
||||
void runInExecutor(int id, C callback) {
|
||||
folly::via(executor_.get(), [cb = std::move(callback)]() { cb(); });
|
||||
executor_->add([cb = std::move(callback)]() { cb(); });
|
||||
}
|
||||
|
||||
std::shared_ptr<RuntimeAdapter> runtimeAdapter_;
|
||||
@@ -1411,20 +1411,14 @@ Connection::Impl::makePropsFromValue(
|
||||
}
|
||||
|
||||
void Connection::Impl::handle(const m::runtime::GetHeapUsageRequest &req) {
|
||||
auto resp = std::make_shared<m::runtime::GetHeapUsageResponse>();
|
||||
resp->id = req.id;
|
||||
|
||||
inspector_
|
||||
->executeIfEnabled(
|
||||
"Runtime.getHeapUsage",
|
||||
[this, req, resp](const debugger::ProgramState &state) {
|
||||
auto heapInfo = getRuntime().instrumentation().getHeapInfo(false);
|
||||
resp->usedSize = heapInfo["hermes_allocatedBytes"];
|
||||
resp->totalSize = heapInfo["hermes_heapSize"];
|
||||
})
|
||||
.via(executor_.get())
|
||||
.thenValue([this, resp](auto &&) { sendResponseToClient(*resp); })
|
||||
.thenError<std::exception>(sendErrorToClient(req.id));
|
||||
runInExecutor(req.id, [this, req]() {
|
||||
auto heapInfo = getRuntime().instrumentation().getHeapInfo(false);
|
||||
auto resp = std::make_shared<m::runtime::GetHeapUsageResponse>();
|
||||
resp->id = req.id;
|
||||
resp->usedSize = heapInfo["hermes_allocatedBytes"];
|
||||
resp->totalSize = heapInfo["hermes_heapSize"];
|
||||
sendResponseToClient(*resp);
|
||||
});
|
||||
}
|
||||
|
||||
void Connection::Impl::handle(const m::runtime::GetPropertiesRequest &req) {
|
||||
|
||||
@@ -244,8 +244,7 @@ void JSIExecutor::callFunction(
|
||||
// by value.
|
||||
auto errorProducer = [=] {
|
||||
std::stringstream ss;
|
||||
ss << "moduleID: " << moduleId << " methodID: " << methodId
|
||||
<< " arguments: " << folly::toJson(arguments);
|
||||
ss << "moduleID: " << moduleId << " methodID: " << methodId;
|
||||
return ss.str();
|
||||
};
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ target_link_libraries(rrc_progressbar
|
||||
react_render_debug
|
||||
react_render_graphics
|
||||
react_render_uimanager
|
||||
reactnativeutilsjni
|
||||
reactnativejni
|
||||
rrc_view
|
||||
yoga
|
||||
)
|
||||
|
||||
@@ -31,7 +31,7 @@ target_link_libraries(rrc_slider
|
||||
react_render_imagemanager
|
||||
react_render_mapbuffer
|
||||
react_render_uimanager
|
||||
reactnativeutilsjni
|
||||
reactnativejni
|
||||
rrc_image
|
||||
rrc_view
|
||||
yoga
|
||||
|
||||
@@ -28,7 +28,7 @@ target_link_libraries(
|
||||
react_render_debug
|
||||
react_render_graphics
|
||||
react_render_uimanager
|
||||
reactnativeutilsjni
|
||||
reactnativejni
|
||||
rrc_view
|
||||
yoga
|
||||
)
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
#ifdef ANDROID
|
||||
// constants for Text State serialization
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_ATTRIBUTED_STRING = 0;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
|
||||
// Used for TextInput only
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_HASH = 2;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* State for <Paragraph> component.
|
||||
* Represents what to render and how to render.
|
||||
|
||||
@@ -26,21 +26,13 @@ inline folly::dynamic toDynamic(ParagraphState const ¶graphState) {
|
||||
return newState;
|
||||
}
|
||||
|
||||
// constants for Text State serialization
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_ATTRIBUTED_STRING = 0;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_PARAGRAPH_ATTRIBUTES = 1;
|
||||
// Used for TextInput
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_HASH = 2;
|
||||
constexpr static MapBuffer::Key TX_STATE_KEY_MOST_RECENT_EVENT_COUNT = 3;
|
||||
|
||||
inline MapBuffer toMapBuffer(ParagraphState const ¶graphState) {
|
||||
auto builder = MapBufferBuilder();
|
||||
auto attStringMapBuffer = toMapBuffer(paragraphState.attributedString);
|
||||
builder.putMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING, attStringMapBuffer);
|
||||
auto paMapBuffer = toMapBuffer(paragraphState.paragraphAttributes);
|
||||
builder.putMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES, paMapBuffer);
|
||||
// TODO: Used for TextInput
|
||||
builder.putInt(TX_STATE_KEY_HASH, 1234);
|
||||
builder.putInt(TX_STATE_KEY_HASH, attStringMapBuffer.getInt(AS_KEY_HASH));
|
||||
return builder.build();
|
||||
}
|
||||
#endif
|
||||
|
||||
+22
@@ -10,6 +10,11 @@
|
||||
#include <react/renderer/components/text/conversions.h>
|
||||
#include <react/renderer/debug/debugStringConvertibleUtils.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <react/renderer/mapbuffer/MapBuffer.h>
|
||||
#include <react/renderer/mapbuffer/MapBufferBuilder.h>
|
||||
#endif
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace facebook {
|
||||
@@ -89,6 +94,23 @@ folly::dynamic AndroidTextInputState::getDynamic() const {
|
||||
}
|
||||
return newState;
|
||||
}
|
||||
|
||||
MapBuffer AndroidTextInputState::getMapBuffer() const {
|
||||
auto builder = MapBufferBuilder();
|
||||
// See comment in getDynamic block.
|
||||
if (cachedAttributedStringId == 0) {
|
||||
builder.putInt(TX_STATE_KEY_MOST_RECENT_EVENT_COUNT, mostRecentEventCount);
|
||||
|
||||
auto attStringMapBuffer = toMapBuffer(attributedString);
|
||||
builder.putMapBuffer(TX_STATE_KEY_ATTRIBUTED_STRING, attStringMapBuffer);
|
||||
auto paMapBuffer = toMapBuffer(paragraphAttributes);
|
||||
builder.putMapBuffer(TX_STATE_KEY_PARAGRAPH_ATTRIBUTES, paMapBuffer);
|
||||
|
||||
builder.putInt(TX_STATE_KEY_HASH, attStringMapBuffer.getInt(AS_KEY_HASH));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace react
|
||||
|
||||
+1
-3
@@ -94,9 +94,7 @@ class AndroidTextInputState final {
|
||||
AndroidTextInputState const &previousState,
|
||||
folly::dynamic const &data);
|
||||
folly::dynamic getDynamic() const;
|
||||
MapBuffer getMapBuffer() const {
|
||||
return MapBufferBuilder::EMPTY();
|
||||
};
|
||||
MapBuffer getMapBuffer() const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -40,6 +40,6 @@ target_link_libraries(react_render_textlayoutmanager
|
||||
react_render_telemetry
|
||||
react_render_uimanager
|
||||
react_utils
|
||||
reactnativeutilsjni
|
||||
reactnativejni
|
||||
yoga
|
||||
)
|
||||
|
||||
+45
-1
@@ -305,6 +305,50 @@ NSDictionary<NSAttributedStringKey, id> *RCTNSTextAttributesFromTextAttributes(T
|
||||
return [attributes copy];
|
||||
}
|
||||
|
||||
static void RCTApplyBaselineOffset(NSMutableAttributedString *attributedText)
|
||||
{
|
||||
__block CGFloat maximumLineHeight = 0;
|
||||
|
||||
[attributedText enumerateAttribute:NSParagraphStyleAttributeName
|
||||
inRange:NSMakeRange(0, attributedText.length)
|
||||
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
||||
usingBlock:^(NSParagraphStyle *paragraphStyle, __unused NSRange range, __unused BOOL *stop) {
|
||||
if (!paragraphStyle) {
|
||||
return;
|
||||
}
|
||||
|
||||
maximumLineHeight = MAX(paragraphStyle.maximumLineHeight, maximumLineHeight);
|
||||
}];
|
||||
|
||||
if (maximumLineHeight == 0) {
|
||||
// `lineHeight` was not specified, nothing to do.
|
||||
return;
|
||||
}
|
||||
|
||||
__block CGFloat maximumFontLineHeight = 0;
|
||||
|
||||
[attributedText enumerateAttribute:NSFontAttributeName
|
||||
inRange:NSMakeRange(0, attributedText.length)
|
||||
options:NSAttributedStringEnumerationLongestEffectiveRangeNotRequired
|
||||
usingBlock:^(UIFont *font, NSRange range, __unused BOOL *stop) {
|
||||
if (!font) {
|
||||
return;
|
||||
}
|
||||
|
||||
maximumFontLineHeight = MAX(font.lineHeight, maximumFontLineHeight);
|
||||
}];
|
||||
|
||||
if (maximumLineHeight < maximumFontLineHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGFloat baseLineOffset = (maximumLineHeight - maximumFontLineHeight) / 2.0;
|
||||
|
||||
[attributedText addAttribute:NSBaselineOffsetAttributeName
|
||||
value:@(baseLineOffset)
|
||||
range:NSMakeRange(0, attributedText.length)];
|
||||
}
|
||||
|
||||
NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedString &attributedString)
|
||||
{
|
||||
static UIImage *placeholderImage;
|
||||
@@ -357,7 +401,7 @@ NSAttributedString *RCTNSAttributedStringFromAttributedString(const AttributedSt
|
||||
|
||||
[nsAttributedString appendAttributedString:nsAttributedStringFragment];
|
||||
}
|
||||
|
||||
RCTApplyBaselineOffset(nsAttributedString);
|
||||
[nsAttributedString endEditing];
|
||||
|
||||
return nsAttributedString;
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
+2
-1
@@ -128,11 +128,12 @@ jest
|
||||
isGrayscaleEnabled: jest.fn(),
|
||||
isInvertColorsEnabled: jest.fn(),
|
||||
isReduceMotionEnabled: jest.fn(),
|
||||
prefersCrossFadeTransitions: jest.fn(),
|
||||
isReduceTransparencyEnabled: jest.fn(),
|
||||
isScreenReaderEnabled: jest.fn(() => Promise.resolve(false)),
|
||||
removeEventListener: jest.fn(),
|
||||
setAccessibilityFocus: jest.fn(),
|
||||
sendAccessibilityEvent_unstable: jest.fn(),
|
||||
sendAccessibilityEvent: jest.fn(),
|
||||
getRecommendedTimeoutMillis: jest.fn(),
|
||||
},
|
||||
}))
|
||||
|
||||
+51
-17
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "react-native",
|
||||
"private": true,
|
||||
"version": "1000.0.0",
|
||||
"version": "0.70.9",
|
||||
"bin": "./cli.js",
|
||||
"description": "A framework for building native apps using React",
|
||||
"license": "MIT",
|
||||
@@ -94,18 +93,14 @@
|
||||
"test-android-e2e": "yarn run docker-build-android && yarn run test-android-run-e2e",
|
||||
"test-ios": "./scripts/objc-test.sh test"
|
||||
},
|
||||
"workspaces": [
|
||||
"packages/!(eslint-config-react-native-community)",
|
||||
"repo-config"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"react": "18.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@jest/create-cache-key-function": "^27.0.1",
|
||||
"@react-native-community/cli": "^9.0.0-alpha.3",
|
||||
"@react-native-community/cli-platform-android": "^9.0.0-alpha.3",
|
||||
"@react-native-community/cli-platform-ios": "^9.0.0-alpha.3",
|
||||
"@react-native-community/cli": "9.3.2",
|
||||
"@react-native-community/cli-platform-android": "9.3.1",
|
||||
"@react-native-community/cli-platform-ios": "9.3.0",
|
||||
"@react-native/assets": "1.0.0",
|
||||
"@react-native/normalize-color": "2.0.0",
|
||||
"@react-native/polyfills": "2.0.0",
|
||||
@@ -116,15 +111,15 @@
|
||||
"invariant": "^2.2.4",
|
||||
"jsc-android": "^250230.2.1",
|
||||
"memoize-one": "^5.0.0",
|
||||
"metro-react-native-babel-transformer": "0.71.3",
|
||||
"metro-runtime": "0.71.3",
|
||||
"metro-source-map": "0.71.3",
|
||||
"metro-react-native-babel-transformer": "0.72.3",
|
||||
"metro-runtime": "0.72.3",
|
||||
"metro-source-map": "0.72.3",
|
||||
"mkdirp": "^0.5.1",
|
||||
"nullthrows": "^1.1.1",
|
||||
"pretty-format": "^26.5.2",
|
||||
"promise": "^8.0.3",
|
||||
"promise": "^8.3.0",
|
||||
"react-devtools-core": "4.24.0",
|
||||
"react-native-gradle-plugin": "^0.70.0",
|
||||
"react-native-gradle-plugin": "^0.70.3",
|
||||
"react-refresh": "^0.4.0",
|
||||
"react-shallow-renderer": "^16.15.0",
|
||||
"regenerator-runtime": "^0.13.2",
|
||||
@@ -132,13 +127,52 @@
|
||||
"stacktrace-parser": "^0.1.3",
|
||||
"use-sync-external-store": "^1.0.0",
|
||||
"whatwg-fetch": "^3.0.0",
|
||||
"ws": "^6.1.4"
|
||||
"ws": "^6.1.4",
|
||||
"react-native-codegen": "^0.70.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
"flow-bin": "^0.182.0",
|
||||
"hermes-eslint": "0.8.0",
|
||||
"react": "18.1.0",
|
||||
"react-test-renderer": "^18.1.0"
|
||||
"react-test-renderer": "18.1.0",
|
||||
"@babel/core": "^7.14.0",
|
||||
"@babel/eslint-parser": "^7.18.2",
|
||||
"@babel/generator": "^7.14.0",
|
||||
"@babel/plugin-transform-regenerator": "^7.0.0",
|
||||
"@react-native-community/eslint-plugin": "*",
|
||||
"@react-native/eslint-plugin-specs": "^0.70.0",
|
||||
"@reactions/component": "^2.0.2",
|
||||
"async": "^3.2.2",
|
||||
"clang-format": "^1.2.4",
|
||||
"connect": "^3.6.5",
|
||||
"coveralls": "^3.1.1",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-config-fb-strict": "^26.0.0",
|
||||
"eslint-config-fbjs": "^3.1.1",
|
||||
"eslint-config-prettier": "^8.3.0",
|
||||
"eslint-plugin-babel": "^5.3.1",
|
||||
"eslint-plugin-eslint-comments": "^3.2.0",
|
||||
"eslint-plugin-flowtype": "^7.0.0",
|
||||
"eslint-plugin-jest": "^25.2.4",
|
||||
"eslint-plugin-jsx-a11y": "^6.4.1",
|
||||
"eslint-plugin-prettier": "^4.0.0",
|
||||
"eslint-plugin-react": "^7.26.1",
|
||||
"eslint-plugin-react-hooks": "^4.2.0",
|
||||
"eslint-plugin-react-native": "^3.11.0",
|
||||
"eslint-plugin-relay": "^1.8.2",
|
||||
"inquirer": "^7.1.0",
|
||||
"jest": "^26.6.3",
|
||||
"jest-junit": "^10.0.0",
|
||||
"jscodeshift": "^0.13.1",
|
||||
"metro-babel-register": "0.72.3",
|
||||
"metro-memory-fs": "0.72.3",
|
||||
"mock-fs": "^5.1.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"prettier": "^2.4.1",
|
||||
"shelljs": "^0.8.5",
|
||||
"signedsource": "^1.0.0",
|
||||
"ws": "^6.1.4",
|
||||
"yargs": "^15.3.1"
|
||||
},
|
||||
"codegenConfig": {
|
||||
"libraries": [
|
||||
@@ -158,4 +192,4 @@
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@react-native/eslint-plugin-specs",
|
||||
"version": "0.0.4",
|
||||
"version": "0.70.0",
|
||||
"description": "ESLint rules to validate NativeModule and Component Specs",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
@@ -9,7 +9,7 @@
|
||||
"directory": "packages/eslint-plugin-specs"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "node prepublish.js"
|
||||
"prepack": "node prepack.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/core": "^7.14.0",
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@
|
||||
const path = require('path');
|
||||
const withBabelRegister = require('./with-babel-register');
|
||||
|
||||
// We run yarn prepublish before publishing package which will set this value to true
|
||||
// We use the prepack hook before publishing package to set this value to true
|
||||
const PACKAGE_USAGE = false;
|
||||
const ERRORS = {
|
||||
misnamedHasteModule(hasteModuleName) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "react-native-codegen",
|
||||
"version": "0.70.3",
|
||||
"version": "0.70.6",
|
||||
"description": "⚛️ Code generation tools for React Native",
|
||||
"homepage": "https://github.com/facebook/react-native/tree/HEAD/packages/react-native-codegen",
|
||||
"repository": {
|
||||
|
||||
@@ -27,7 +27,9 @@ function filterJSFile(file: string) {
|
||||
// NativeSampleTurboModule is for demo purpose. It should be added manually to the
|
||||
// app for now.
|
||||
!file.endsWith('NativeSampleTurboModule.js') &&
|
||||
!file.includes('__tests')
|
||||
!file.includes('__tests') &&
|
||||
// Ignore TypeScript type declaration files.
|
||||
!file.endsWith('.d.ts')
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -75,7 +75,7 @@ module.exports = {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Object.keys(components)
|
||||
const componentTemplates = Object.keys(components)
|
||||
.filter(componentName => {
|
||||
const component = components[componentName];
|
||||
return !(
|
||||
@@ -91,6 +91,8 @@ module.exports = {
|
||||
|
||||
return replacedTemplate;
|
||||
});
|
||||
|
||||
return componentTemplates.length > 0 ? componentTemplates : null;
|
||||
})
|
||||
.filter(Boolean);
|
||||
})
|
||||
|
||||
+48
@@ -1594,6 +1594,53 @@ const EXCLUDE_ANDROID_IOS: SchemaType = {
|
||||
},
|
||||
};
|
||||
|
||||
const EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES: SchemaType = {
|
||||
modules: {
|
||||
ComponentFile1: {
|
||||
type: 'Component',
|
||||
components: {
|
||||
ExcludedIosComponent: {
|
||||
excludedPlatforms: ['iOS'],
|
||||
extendsProps: [
|
||||
{
|
||||
type: 'ReactNativeBuiltInType',
|
||||
knownTypeName: 'ReactNativeCoreViewProps',
|
||||
},
|
||||
],
|
||||
events: [],
|
||||
props: [],
|
||||
commands: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
ComponentFile2: {
|
||||
type: 'Component',
|
||||
components: {
|
||||
MultiFileIncludedNativeComponent: {
|
||||
extendsProps: [
|
||||
{
|
||||
type: 'ReactNativeBuiltInType',
|
||||
knownTypeName: 'ReactNativeCoreViewProps',
|
||||
},
|
||||
],
|
||||
events: [],
|
||||
props: [
|
||||
{
|
||||
name: 'disabled',
|
||||
optional: true,
|
||||
typeAnnotation: {
|
||||
type: 'BooleanTypeAnnotation',
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
commands: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
NO_PROPS_NO_EVENTS,
|
||||
INTERFACE_ONLY,
|
||||
@@ -1621,4 +1668,5 @@ module.exports = {
|
||||
COMMANDS_AND_PROPS,
|
||||
EXCLUDE_ANDROID,
|
||||
EXCLUDE_ANDROID_IOS,
|
||||
EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES,
|
||||
};
|
||||
|
||||
+29
@@ -336,6 +336,35 @@ using ExcludedAndroidIosComponentComponentDescriptor = ConcreteComponentDescript
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateComponentDescriptorH can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"ComponentDescriptors.h" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateComponentDescriptorH.js
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/components/EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES/ShadowNodes.h>
|
||||
#include <react/renderer/core/ConcreteComponentDescriptor.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
using ExcludedIosComponentComponentDescriptor = ConcreteComponentDescriptor<ExcludedIosComponentShadowNode>;
|
||||
using MultiFileIncludedNativeComponentComponentDescriptor = ConcreteComponentDescriptor<MultiFileIncludedNativeComponentShadowNode>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateComponentDescriptorH can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"ComponentDescriptors.h" => "
|
||||
|
||||
+25
@@ -430,6 +430,31 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
|
||||
|
||||
NS_ASSUME_NONNULL_END",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateComponentHObjCpp can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"RCTComponentViewHelpers.h" => "/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateComponentHObjCpp.js
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <React/RCTDefines.h>
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol RCTMultiFileIncludedNativeComponentViewProtocol <NSObject>
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END",
|
||||
}
|
||||
`;
|
||||
|
||||
+26
@@ -351,6 +351,32 @@ namespace react {
|
||||
|
||||
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateEventEmitterCpp can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"EventEmitters.cpp" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateEventEmitterCpp.js
|
||||
*/
|
||||
|
||||
#include <react/renderer/components/EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES/EventEmitters.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
||||
+27
@@ -390,6 +390,33 @@ namespace react {
|
||||
|
||||
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateEventEmitterH can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"EventEmitters.h" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateEventEmitterH.js
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/components/view/ViewEventEmitter.h>
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
|
||||
+40
@@ -412,6 +412,46 @@ ExcludedAndroidIosComponentProps::ExcludedAndroidIosComponentProps(
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsCpp can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"Props.cpp" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsCpp.js
|
||||
*/
|
||||
|
||||
#include <react/renderer/components/EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES/Props.h>
|
||||
#include <react/renderer/core/PropsParserContext.h>
|
||||
#include <react/renderer/core/propsConversions.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
ExcludedIosComponentProps::ExcludedIosComponentProps(
|
||||
const PropsParserContext &context,
|
||||
const ExcludedIosComponentProps &sourceProps,
|
||||
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps)
|
||||
|
||||
|
||||
{}
|
||||
MultiFileIncludedNativeComponentProps::MultiFileIncludedNativeComponentProps(
|
||||
const PropsParserContext &context,
|
||||
const MultiFileIncludedNativeComponentProps &sourceProps,
|
||||
const RawProps &rawProps): ViewProps(context, sourceProps, rawProps),
|
||||
|
||||
disabled(convertRawProp(context, rawProps, \\"disabled\\", sourceProps.disabled, {true}))
|
||||
{}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsCpp can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"Props.cpp" => "
|
||||
|
||||
+46
@@ -660,6 +660,52 @@ class JSI_EXPORT ExcludedAndroidIosComponentProps final : public ViewProps {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsH can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"Props.h" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsH.js
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <jsi/jsi.h>
|
||||
#include <react/renderer/components/view/ViewProps.h>
|
||||
#include <react/renderer/core/PropsParserContext.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
class JSI_EXPORT ExcludedIosComponentProps final : public ViewProps {
|
||||
public:
|
||||
ExcludedIosComponentProps() = default;
|
||||
ExcludedIosComponentProps(const PropsParserContext& context, const ExcludedIosComponentProps &sourceProps, const RawProps &rawProps);
|
||||
|
||||
#pragma mark - Props
|
||||
|
||||
|
||||
};
|
||||
|
||||
class JSI_EXPORT MultiFileIncludedNativeComponentProps final : public ViewProps {
|
||||
public:
|
||||
MultiFileIncludedNativeComponentProps() = default;
|
||||
MultiFileIncludedNativeComponentProps(const PropsParserContext& context, const MultiFileIncludedNativeComponentProps &sourceProps, const RawProps &rawProps);
|
||||
|
||||
#pragma mark - Props
|
||||
|
||||
bool disabled{true};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsH can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"Props.h" => "
|
||||
|
||||
+63
@@ -436,6 +436,69 @@ exports[`GeneratePropsJavaDelegate can generate fixture EXCLUDE_ANDROID 1`] = `M
|
||||
|
||||
exports[`GeneratePropsJavaDelegate can generate fixture EXCLUDE_ANDROID_IOS 1`] = `Map {}`;
|
||||
|
||||
exports[`GeneratePropsJavaDelegate can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"java/com/facebook/react/viewmanagers/ExcludedIosComponentManagerDelegate.java" => "/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaDelegate.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
||||
import com.facebook.react.uimanager.BaseViewManagerInterface;
|
||||
|
||||
public class ExcludedIosComponentManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & ExcludedIosComponentManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
||||
public ExcludedIosComponentManagerDelegate(U viewManager) {
|
||||
super(viewManager);
|
||||
}
|
||||
@Override
|
||||
public void setProperty(T view, String propName, @Nullable Object value) {
|
||||
super.setProperty(view, propName, value);
|
||||
}
|
||||
}
|
||||
",
|
||||
"java/com/facebook/react/viewmanagers/MultiFileIncludedNativeComponentManagerDelegate.java" => "/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaDelegate.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers;
|
||||
|
||||
import android.view.View;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.react.uimanager.BaseViewManagerDelegate;
|
||||
import com.facebook.react.uimanager.BaseViewManagerInterface;
|
||||
|
||||
public class MultiFileIncludedNativeComponentManagerDelegate<T extends View, U extends BaseViewManagerInterface<T> & MultiFileIncludedNativeComponentManagerInterface<T>> extends BaseViewManagerDelegate<T, U> {
|
||||
public MultiFileIncludedNativeComponentManagerDelegate(U viewManager) {
|
||||
super(viewManager);
|
||||
}
|
||||
@Override
|
||||
public void setProperty(T view, String propName, @Nullable Object value) {
|
||||
switch (propName) {
|
||||
case \\"disabled\\":
|
||||
mViewManager.setDisabled(view, value == null ? true : (boolean) value);
|
||||
break;
|
||||
default:
|
||||
super.setProperty(view, propName, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsJavaDelegate can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"java/com/facebook/react/viewmanagers/FloatPropNativeComponentManagerDelegate.java" => "/**
|
||||
|
||||
+39
@@ -249,6 +249,45 @@ exports[`GeneratePropsJavaInterface can generate fixture EXCLUDE_ANDROID 1`] = `
|
||||
|
||||
exports[`GeneratePropsJavaInterface can generate fixture EXCLUDE_ANDROID_IOS 1`] = `Map {}`;
|
||||
|
||||
exports[`GeneratePropsJavaInterface can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"java/com/facebook/react/viewmanagers/ExcludedIosComponentManagerInterface.java" => "/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaInterface.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface ExcludedIosComponentManagerInterface<T extends View> {
|
||||
// No props
|
||||
}
|
||||
",
|
||||
"java/com/facebook/react/viewmanagers/MultiFileIncludedNativeComponentManagerInterface.java" => "/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaInterface.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers;
|
||||
|
||||
import android.view.View;
|
||||
|
||||
public interface MultiFileIncludedNativeComponentManagerInterface<T extends View> {
|
||||
void setDisabled(T view, boolean value);
|
||||
}
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsJavaInterface can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"java/com/facebook/react/viewmanagers/FloatPropNativeComponentManagerInterface.java" => "/**
|
||||
|
||||
+46
@@ -474,6 +474,52 @@ exports[`GeneratePropsJavaPojo can generate fixture EXCLUDE_ANDROID 1`] = `Map {
|
||||
|
||||
exports[`GeneratePropsJavaPojo can generate fixture EXCLUDE_ANDROID_IOS 1`] = `Map {}`;
|
||||
|
||||
exports[`GeneratePropsJavaPojo can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"java/com/facebook/react/viewmanagers/ComponentFile1/ExcludedIosComponentProps.java" => "/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaPojo.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers.ComponentFile1;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
@DoNotStrip
|
||||
public class ExcludedIosComponentProps {
|
||||
|
||||
|
||||
}
|
||||
",
|
||||
"java/com/facebook/react/viewmanagers/ComponentFile2/MultiFileIncludedNativeComponentProps.java" => "/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @generated by codegen project: GeneratePropsJavaPojo.js
|
||||
*/
|
||||
|
||||
package com.facebook.react.viewmanagers.ComponentFile2;
|
||||
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
|
||||
@DoNotStrip
|
||||
public class MultiFileIncludedNativeComponentProps {
|
||||
private boolean mDisabled;
|
||||
@DoNotStrip
|
||||
public boolean getDisabled() {
|
||||
return mDisabled;
|
||||
}
|
||||
}
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GeneratePropsJavaPojo can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"java/com/facebook/react/viewmanagers/Switch/FloatPropNativeComponentProps.java" => "/**
|
||||
|
||||
+26
@@ -300,6 +300,32 @@ extern const char ExcludedAndroidIosComponentComponentName[] = \\"ExcludedAndroi
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateShadowNodeCpp can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"ShadowNodes.cpp" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateShadowNodeCpp.js
|
||||
*/
|
||||
|
||||
#include <react/renderer/components/EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES/ShadowNodes.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char ExcludedIosComponentComponentName[] = \\"ExcludedIosComponent\\";
|
||||
extern const char MultiFileIncludedNativeComponentComponentName[] = \\"MultiFileIncludedNativeComponent\\";
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateShadowNodeCpp can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"ShadowNodes.cpp" => "
|
||||
|
||||
+45
@@ -429,6 +429,51 @@ using ExcludedAndroidIosComponentShadowNode = ConcreteViewShadowNode<
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateShadowNodeH can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"ShadowNodes.h" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateShadowNodeH.js
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/renderer/components/EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES/Props.h>
|
||||
#include <react/renderer/components/view/ConcreteViewShadowNode.h>
|
||||
#include <jsi/jsi.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
JSI_EXPORT extern const char ExcludedIosComponentComponentName[];
|
||||
|
||||
/*
|
||||
* \`ShadowNode\` for <ExcludedIosComponent> component.
|
||||
*/
|
||||
using ExcludedIosComponentShadowNode = ConcreteViewShadowNode<
|
||||
ExcludedIosComponentComponentName,
|
||||
ExcludedIosComponentProps>;
|
||||
|
||||
JSI_EXPORT extern const char MultiFileIncludedNativeComponentComponentName[];
|
||||
|
||||
/*
|
||||
* \`ShadowNode\` for <MultiFileIncludedNativeComponent> component.
|
||||
*/
|
||||
using MultiFileIncludedNativeComponentShadowNode = ConcreteViewShadowNode<
|
||||
MultiFileIncludedNativeComponentComponentName,
|
||||
MultiFileIncludedNativeComponentProps>;
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateShadowNodeH can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"ShadowNodes.h" => "
|
||||
|
||||
+61
@@ -486,6 +486,67 @@ TEST(ExcludedAndroidIosComponentProps_DoesNotDie, etc) {
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateTests can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"Tests.cpp" => "/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @generated by codegen project: GenerateTests.js
|
||||
* */
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <react/renderer/core/PropsParserContext.h>
|
||||
#include <react/renderer/components/EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES/Props.h>
|
||||
#include <react/renderer/core/RawProps.h>
|
||||
#include <react/renderer/core/RawPropsParser.h>
|
||||
#include <react/renderer/core/propsConversions.h>
|
||||
|
||||
using namespace facebook::react;
|
||||
|
||||
TEST(ExcludedIosComponentProps_DoesNotDie, etc) {
|
||||
auto propParser = RawPropsParser();
|
||||
propParser.prepare<ExcludedIosComponentProps>();
|
||||
auto const &sourceProps = ExcludedIosComponentProps();
|
||||
auto const &rawProps = RawProps(folly::dynamic::object(\\"xx_invalid_xx\\", \\"xx_invalid_xx\\"));
|
||||
|
||||
ContextContainer contextContainer{};
|
||||
PropsParserContext parserContext{-1, contextContainer};
|
||||
|
||||
rawProps.parse(propParser, parserContext);
|
||||
ExcludedIosComponentProps(parserContext, sourceProps, rawProps);
|
||||
}
|
||||
|
||||
TEST(MultiFileIncludedNativeComponentProps_DoesNotDie, etc) {
|
||||
auto propParser = RawPropsParser();
|
||||
propParser.prepare<MultiFileIncludedNativeComponentProps>();
|
||||
auto const &sourceProps = MultiFileIncludedNativeComponentProps();
|
||||
auto const &rawProps = RawProps(folly::dynamic::object(\\"xx_invalid_xx\\", \\"xx_invalid_xx\\"));
|
||||
|
||||
ContextContainer contextContainer{};
|
||||
PropsParserContext parserContext{-1, contextContainer};
|
||||
|
||||
rawProps.parse(propParser, parserContext);
|
||||
MultiFileIncludedNativeComponentProps(parserContext, sourceProps, rawProps);
|
||||
}
|
||||
|
||||
TEST(MultiFileIncludedNativeComponentProps_disabled, etc) {
|
||||
auto propParser = RawPropsParser();
|
||||
propParser.prepare<MultiFileIncludedNativeComponentProps>();
|
||||
auto const &sourceProps = MultiFileIncludedNativeComponentProps();
|
||||
auto const &rawProps = RawProps(folly::dynamic::object(\\"disabled\\", true));
|
||||
|
||||
ContextContainer contextContainer{};
|
||||
PropsParserContext parserContext{-1, contextContainer};
|
||||
|
||||
rawProps.parse(propParser, parserContext);
|
||||
MultiFileIncludedNativeComponentProps(parserContext, sourceProps, rawProps);
|
||||
}",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateTests can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"Tests.cpp" => "/**
|
||||
|
||||
+1
@@ -51,6 +51,7 @@ Class<RCTComponentViewProtocol> CommandNativeComponentCls(void) __attribute__((u
|
||||
Class<RCTComponentViewProtocol> CommandNativeComponentCls(void) __attribute__((used)); // COMMANDS_AND_PROPS
|
||||
Class<RCTComponentViewProtocol> ExcludedAndroidComponentCls(void) __attribute__((used)); // EXCLUDE_ANDROID
|
||||
|
||||
Class<RCTComponentViewProtocol> MultiFileIncludedNativeComponentCls(void) __attribute__((used)); // EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
+2
@@ -74,6 +74,8 @@ Class<RCTComponentViewProtocol> RCTThirdPartyFabricComponentsProvider(const char
|
||||
|
||||
{\\"ExcludedAndroidComponent\\", ExcludedAndroidComponentCls}, // EXCLUDE_ANDROID
|
||||
|
||||
|
||||
{\\"MultiFileIncludedNativeComponent\\", MultiFileIncludedNativeComponentCls}, // EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES
|
||||
};
|
||||
|
||||
auto p = sFabricComponentsClassMap.find(name);
|
||||
|
||||
+44
@@ -509,6 +509,50 @@ export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateViewConfigJs can generate fixture EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILES 1`] = `
|
||||
Map {
|
||||
"EXCLUDE_IOS_TWO_COMPONENTS_DIFFERENT_FILESNativeViewConfig.js" => "
|
||||
/**
|
||||
* This code was generated by [react-native-codegen](https://www.npmjs.com/package/react-native-codegen).
|
||||
*
|
||||
* Do not edit this file as changes may cause incorrect behavior and will be lost
|
||||
* once the code is regenerated.
|
||||
*
|
||||
* @flow
|
||||
*
|
||||
* @generated by codegen project: GenerateViewConfigJs.js
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const NativeComponentRegistry = require('react-native/Libraries/NativeComponent/NativeComponentRegistry');
|
||||
|
||||
let nativeComponentName = 'ExcludedIosComponent';
|
||||
|
||||
|
||||
export const __INTERNAL_VIEW_CONFIG = {
|
||||
uiViewClassName: 'ExcludedIosComponent',
|
||||
validAttributes: {},
|
||||
};
|
||||
|
||||
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
|
||||
|
||||
let nativeComponentName = 'MultiFileIncludedNativeComponent';
|
||||
|
||||
|
||||
export const __INTERNAL_VIEW_CONFIG = {
|
||||
uiViewClassName: 'MultiFileIncludedNativeComponent',
|
||||
|
||||
validAttributes: {
|
||||
disabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
export default NativeComponentRegistry.get(nativeComponentName, () => __INTERNAL_VIEW_CONFIG);
|
||||
",
|
||||
}
|
||||
`;
|
||||
|
||||
exports[`GenerateViewConfigJs can generate fixture FLOAT_PROPS 1`] = `
|
||||
Map {
|
||||
"FLOAT_PROPSNativeViewConfig.js" => "
|
||||
|
||||
Vendored
+22
@@ -0,0 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {compareSnaps, compareTsArraySnaps} = require('../compareSnaps.js');
|
||||
|
||||
const flowFixtures = require('../../flow/components/__test_fixtures__/fixtures.js');
|
||||
const flowSnaps = require('../../../../src/parsers/flow/components/__tests__/__snapshots__/component-parser-test.js.snap');
|
||||
const tsFixtures = require('../../typescript/components/__test_fixtures__/fixtures.js');
|
||||
const tsSnaps = require('../../../../src/parsers/typescript/components/__tests__/__snapshots__/typescript-component-parser-test.js.snap');
|
||||
const tsExtraCases = ['ARRAY2_PROP_TYPES_NO_EVENTS'];
|
||||
|
||||
compareSnaps(flowFixtures, flowSnaps, [], tsFixtures, tsSnaps, tsExtraCases);
|
||||
compareTsArraySnaps(tsSnaps, tsExtraCases);
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const {compareSnaps, compareTsArraySnaps} = require('../compareSnaps.js');
|
||||
|
||||
const flowFixtures = require('../../flow/modules/__test_fixtures__/fixtures.js');
|
||||
const flowSnaps = require('../../../../src/parsers/flow/modules/__tests__/__snapshots__/module-parser-snapshot-test.js.snap');
|
||||
const tsFixtures = require('../../typescript/modules/__test_fixtures__/fixtures.js');
|
||||
const tsSnaps = require('../../../../src/parsers/typescript/modules/__tests__/__snapshots__/typescript-module-parser-snapshot-test.js.snap');
|
||||
const tsExtraCases = [
|
||||
'NATIVE_MODULE_WITH_ARRAY2_WITH_ALIAS',
|
||||
'NATIVE_MODULE_WITH_ARRAY2_WITH_UNION_AND_TOUPLE',
|
||||
'NATIVE_MODULE_WITH_BASIC_ARRAY2',
|
||||
'NATIVE_MODULE_WITH_COMPLEX_ARRAY2',
|
||||
];
|
||||
|
||||
compareSnaps(flowFixtures, flowSnaps, [], tsFixtures, tsSnaps, tsExtraCases);
|
||||
compareTsArraySnaps(tsSnaps, tsExtraCases);
|
||||
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @emails oncall+react_native
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
function compareSnaps(
|
||||
flowFixtures,
|
||||
flowSnaps,
|
||||
flowExtraCases,
|
||||
tsFixtures,
|
||||
tsSnaps,
|
||||
tsExtraCases,
|
||||
) {
|
||||
const flowCases = Object.keys(flowFixtures).sort();
|
||||
const tsCases = Object.keys(tsFixtures).sort();
|
||||
const commonCases = flowCases.filter(name => tsCases.indexOf(name) !== -1);
|
||||
|
||||
describe('RN Codegen Parsers', () => {
|
||||
it('should not unintentionally contains test case for Flow but not for TypeScript', () => {
|
||||
expect(
|
||||
flowCases.filter(name => commonCases.indexOf(name) === -1),
|
||||
).toEqual(flowExtraCases);
|
||||
});
|
||||
|
||||
it('should not unintentionally contains test case for TypeScript but not for Flow', () => {
|
||||
expect(tsCases.filter(name => commonCases.indexOf(name) === -1)).toEqual(
|
||||
tsExtraCases,
|
||||
);
|
||||
});
|
||||
|
||||
for (const commonCase of commonCases) {
|
||||
it(`should generate the same snap from Flow and TypeScript for fixture ${commonCase}`, () => {
|
||||
expect(
|
||||
flowSnaps[
|
||||
`RN Codegen Flow Parser can generate fixture ${commonCase}`
|
||||
],
|
||||
).toEqual(
|
||||
tsSnaps[
|
||||
`RN Codegen TypeScript Parser can generate fixture ${commonCase}`
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function compareTsArraySnaps(tsSnaps, tsExtraCases) {
|
||||
for (const array2Case of tsExtraCases.filter(
|
||||
name => name.indexOf('ARRAY2') !== -1,
|
||||
)) {
|
||||
const arrayCase = array2Case.replace('ARRAY2', 'ARRAY');
|
||||
it(`should generate the same snap from fixture ${arrayCase} and ${array2Case}`, () => {
|
||||
expect(
|
||||
tsSnaps[
|
||||
`RN Codegen TypeScript Parser can generate fixture ${arrayCase}`
|
||||
],
|
||||
).toEqual(
|
||||
tsSnaps[
|
||||
`RN Codegen TypeScript Parser can generate fixture ${array2Case}`
|
||||
],
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
compareSnaps,
|
||||
compareTsArraySnaps,
|
||||
};
|
||||
Vendored
+2
-2
@@ -141,7 +141,7 @@ import type {ViewProps} from 'ViewPropTypes';
|
||||
import type {HostComponent} from 'react-native';
|
||||
|
||||
interface NativeCommands {
|
||||
readonly hotspotUpdate: (viewRef: React.Ref<'RCTView'> | null | void, x: Int32, y: Int32) => void;
|
||||
readonly hotspotUpdate: (viewRef: React.Ref<'RCTView'> | null | undefined, x: Int32, y: Int32) => void;
|
||||
}
|
||||
|
||||
export interface ModuleProps extends ViewProps {
|
||||
@@ -249,7 +249,7 @@ import type {ViewProps} from 'ViewPropTypes';
|
||||
import type {HostComponent} from 'react-native';
|
||||
|
||||
export interface ModuleProps extends ViewProps {
|
||||
nullable_with_default: WithDefault<Float, 1.0> | null | void;
|
||||
nullable_with_default: WithDefault<Float, 1.0> | null | undefined;
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>(
|
||||
|
||||
Vendored
+218
-85
@@ -15,33 +15,33 @@
|
||||
const EVENT_DEFINITION = `
|
||||
boolean_required: boolean;
|
||||
boolean_optional_key?: boolean;
|
||||
boolean_optional_value: boolean | null | void;
|
||||
boolean_optional_both?: boolean | null | void;
|
||||
boolean_optional_value: boolean | null | undefined;
|
||||
boolean_optional_both?: boolean | null | undefined;
|
||||
|
||||
string_required: string;
|
||||
string_optional_key?: string;
|
||||
string_optional_value: string | null | void;
|
||||
string_optional_both?: string | null | void;
|
||||
string_optional_value: string | null | undefined;
|
||||
string_optional_both?: string | null | undefined;
|
||||
|
||||
double_required: Double;
|
||||
double_optional_key?: Double;
|
||||
double_optional_value: Double | null | void;
|
||||
double_optional_both?: Double | null | void;
|
||||
double_optional_value: Double | null | undefined;
|
||||
double_optional_both?: Double | null | undefined;
|
||||
|
||||
float_required: Float;
|
||||
float_optional_key?: Float;
|
||||
float_optional_value: Float | null | void;
|
||||
float_optional_both?: Float | null | void;
|
||||
float_optional_value: Float | null | undefined;
|
||||
float_optional_both?: Float | null | undefined;
|
||||
|
||||
int32_required: Int32;
|
||||
int32_optional_key?: Int32;
|
||||
int32_optional_value: Int32 | null | void;
|
||||
int32_optional_both?: Int32 | null | void;
|
||||
int32_optional_value: Int32 | null | undefined;
|
||||
int32_optional_both?: Int32 | null | undefined;
|
||||
|
||||
enum_required: 'small' | 'large';
|
||||
enum_optional_key?: 'small' | 'large';
|
||||
enum_optional_value: ('small' | 'large') | null | void;
|
||||
enum_optional_both?: ('small' | 'large') | null | void;
|
||||
enum_optional_value: ('small' | 'large') | null | undefined;
|
||||
enum_optional_both?: ('small' | 'large') | null | undefined;
|
||||
|
||||
object_required: {
|
||||
boolean_required: boolean;
|
||||
@@ -52,21 +52,21 @@ const EVENT_DEFINITION = `
|
||||
};
|
||||
|
||||
object_optional_value: {
|
||||
float_optional_value: Float | null | void;
|
||||
} | null | void;
|
||||
float_optional_value: Float | null | undefined;
|
||||
} | null | undefined;
|
||||
|
||||
object_optional_both?: {
|
||||
int32_optional_both?: Int32 | null | void;
|
||||
} | null | void;
|
||||
int32_optional_both?: Int32 | null | undefined;
|
||||
} | null | undefined;
|
||||
|
||||
object_required_nested_2_layers: {
|
||||
object_optional_nested_1_layer?: {
|
||||
boolean_required: Int32;
|
||||
string_optional_key?: string;
|
||||
double_optional_value: Double | null | void;
|
||||
float_optional_value: Float | null | void;
|
||||
int32_optional_both?: Int32 | null | void;
|
||||
} | null | void;
|
||||
double_optional_value: Double | null | undefined;
|
||||
float_optional_value: Float | null | undefined;
|
||||
int32_optional_both?: Int32 | null | undefined;
|
||||
} | null | undefined;
|
||||
};
|
||||
|
||||
object_readonly_required: Readonly<{
|
||||
@@ -78,12 +78,12 @@ const EVENT_DEFINITION = `
|
||||
}>;
|
||||
|
||||
object_readonly_optional_value: Readonly<{
|
||||
float_optional_value: Float | null | void;
|
||||
}> | null | void;
|
||||
float_optional_value: Float | null | undefined;
|
||||
}> | null | undefined;
|
||||
|
||||
object_readonly_optional_both?: Readonly<{
|
||||
int32_optional_both?: Int32 | null | void;
|
||||
}> | null | void;
|
||||
int32_optional_both?: Int32 | null | undefined;
|
||||
}> | null | undefined;
|
||||
`;
|
||||
|
||||
const ONE_OF_EACH_PROP_EVENT_DEFAULT_AND_OPTIONS = `
|
||||
@@ -265,43 +265,43 @@ export interface ModuleProps extends ViewProps {
|
||||
|
||||
// Object props
|
||||
object_optional_key?: Readonly<{prop: string}>;
|
||||
object_optional_both?: Readonly<{prop: string} | null | void>;
|
||||
object_optional_value: Readonly<{prop: string} | null | void>;
|
||||
object_optional_both?: Readonly<{prop: string} | null | undefined>;
|
||||
object_optional_value: Readonly<{prop: string} | null | undefined>;
|
||||
|
||||
// ImageSource props
|
||||
image_required: ImageSource;
|
||||
image_optional_value: ImageSource | null | void;
|
||||
image_optional_both?: ImageSource | null | void;
|
||||
image_optional_value: ImageSource | null | undefined;
|
||||
image_optional_both?: ImageSource | null | undefined;
|
||||
|
||||
// ColorValue props
|
||||
color_required: ColorValue;
|
||||
color_optional_key?: ColorValue;
|
||||
color_optional_value: ColorValue | null | void;
|
||||
color_optional_both?: ColorValue | null | void;
|
||||
color_optional_value: ColorValue | null | undefined;
|
||||
color_optional_both?: ColorValue | null | undefined;
|
||||
|
||||
// ColorArrayValue props
|
||||
color_array_required: ColorArrayValue;
|
||||
color_array_optional_key?: ColorArrayValue;
|
||||
color_array_optional_value: ColorArrayValue | null | void;
|
||||
color_array_optional_both?: ColorArrayValue | null | void;
|
||||
color_array_optional_value: ColorArrayValue | null | undefined;
|
||||
color_array_optional_both?: ColorArrayValue | null | undefined;
|
||||
|
||||
// ProcessedColorValue props
|
||||
processed_color_required: ProcessedColorValue;
|
||||
processed_color_optional_key?: ProcessedColorValue;
|
||||
processed_color_optional_value: ProcessedColorValue | null | void;
|
||||
processed_color_optional_both?: ProcessedColorValue | null | void;
|
||||
processed_color_optional_value: ProcessedColorValue | null | undefined;
|
||||
processed_color_optional_both?: ProcessedColorValue | null | undefined;
|
||||
|
||||
// PointValue props
|
||||
point_required: PointValue;
|
||||
point_optional_key?: PointValue;
|
||||
point_optional_value: PointValue | null | void;
|
||||
point_optional_both?: PointValue | null | void;
|
||||
point_optional_value: PointValue | null | undefined;
|
||||
point_optional_both?: PointValue | null | undefined;
|
||||
|
||||
// EdgeInsets props
|
||||
insets_required: EdgeInsetsValue;
|
||||
insets_optional_key?: EdgeInsetsValue;
|
||||
insets_optional_value: EdgeInsetsValue | null | void;
|
||||
insets_optional_both?: EdgeInsetsValue | null | void;
|
||||
insets_optional_value: EdgeInsetsValue | null | undefined;
|
||||
insets_optional_both?: EdgeInsetsValue | null | undefined;
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>(
|
||||
@@ -342,32 +342,32 @@ export interface ModuleProps extends ViewProps {
|
||||
// Boolean props
|
||||
array_boolean_required: ReadonlyArray<boolean>;
|
||||
array_boolean_optional_key?: ReadonlyArray<boolean>;
|
||||
array_boolean_optional_value: ReadonlyArray<boolean> | null | void;
|
||||
array_boolean_optional_both?: ReadonlyArray<boolean> | null | void;
|
||||
array_boolean_optional_value: ReadonlyArray<boolean> | null | undefined;
|
||||
array_boolean_optional_both?: ReadonlyArray<boolean> | null | undefined;
|
||||
|
||||
// String props
|
||||
array_string_required: ReadonlyArray<string>;
|
||||
array_string_optional_key?: ReadonlyArray<string>;
|
||||
array_string_optional_value: ReadonlyArray<string> | null | void;
|
||||
array_string_optional_both?: ReadonlyArray<string> | null | void;
|
||||
array_string_optional_value: ReadonlyArray<string> | null | undefined;
|
||||
array_string_optional_both?: ReadonlyArray<string> | null | undefined;
|
||||
|
||||
// Double props
|
||||
array_double_required: ReadonlyArray<Double>;
|
||||
array_double_optional_key?: ReadonlyArray<Double>;
|
||||
array_double_optional_value: ReadonlyArray<Double> | null | void;
|
||||
array_double_optional_both?: ReadonlyArray<Double> | null | void;
|
||||
array_double_optional_value: ReadonlyArray<Double> | null | undefined;
|
||||
array_double_optional_both?: ReadonlyArray<Double> | null | undefined;
|
||||
|
||||
// Float props
|
||||
array_float_required: ReadonlyArray<Float>;
|
||||
array_float_optional_key?: ReadonlyArray<Float>;
|
||||
array_float_optional_value: ReadonlyArray<Float> | null | void;
|
||||
array_float_optional_both?: ReadonlyArray<Float> | null | void;
|
||||
array_float_optional_value: ReadonlyArray<Float> | null | undefined;
|
||||
array_float_optional_both?: ReadonlyArray<Float> | null | undefined;
|
||||
|
||||
// Int32 props
|
||||
array_int32_required: ReadonlyArray<Int32>;
|
||||
array_int32_optional_key?: ReadonlyArray<Int32>;
|
||||
array_int32_optional_value: ReadonlyArray<Int32> | null | void;
|
||||
array_int32_optional_both?: ReadonlyArray<Int32> | null | void;
|
||||
array_int32_optional_value: ReadonlyArray<Int32> | null | undefined;
|
||||
array_int32_optional_both?: ReadonlyArray<Int32> | null | undefined;
|
||||
|
||||
// String enum props
|
||||
array_enum_optional_key?: WithDefault<
|
||||
@@ -382,32 +382,32 @@ export interface ModuleProps extends ViewProps {
|
||||
// ImageSource props
|
||||
array_image_required: ReadonlyArray<ImageSource>;
|
||||
array_image_optional_key?: ReadonlyArray<ImageSource>;
|
||||
array_image_optional_value: ReadonlyArray<ImageSource> | null | void;
|
||||
array_image_optional_both?: ReadonlyArray<ImageSource> | null | void;
|
||||
array_image_optional_value: ReadonlyArray<ImageSource> | null | undefined;
|
||||
array_image_optional_both?: ReadonlyArray<ImageSource> | null | undefined;
|
||||
|
||||
// ColorValue props
|
||||
array_color_required: ReadonlyArray<ColorValue>;
|
||||
array_color_optional_key?: ReadonlyArray<ColorValue>;
|
||||
array_color_optional_value: ReadonlyArray<ColorValue> | null | void;
|
||||
array_color_optional_both?: ReadonlyArray<ColorValue> | null | void;
|
||||
array_color_optional_value: ReadonlyArray<ColorValue> | null | undefined;
|
||||
array_color_optional_both?: ReadonlyArray<ColorValue> | null | undefined;
|
||||
|
||||
// PointValue props
|
||||
array_point_required: ReadonlyArray<PointValue>;
|
||||
array_point_optional_key?: ReadonlyArray<PointValue>;
|
||||
array_point_optional_value: ReadonlyArray<PointValue> | null | void;
|
||||
array_point_optional_both?: ReadonlyArray<PointValue> | null | void;
|
||||
array_point_optional_value: ReadonlyArray<PointValue> | null | undefined;
|
||||
array_point_optional_both?: ReadonlyArray<PointValue> | null | undefined;
|
||||
|
||||
// EdgeInsetsValue props
|
||||
array_insets_required: ReadonlyArray<EdgeInsetsValue>;
|
||||
array_insets_optional_key?: ReadonlyArray<EdgeInsetsValue>;
|
||||
array_insets_optional_value: ReadonlyArray<EdgeInsetsValue> | null | void;
|
||||
array_insets_optional_both?: ReadonlyArray<EdgeInsetsValue> | null | void;
|
||||
array_insets_optional_value: ReadonlyArray<EdgeInsetsValue> | null | undefined;
|
||||
array_insets_optional_both?: ReadonlyArray<EdgeInsetsValue> | null | undefined;
|
||||
|
||||
// Object props
|
||||
array_object_required: ReadonlyArray<Readonly<{prop: string}>>;
|
||||
array_object_optional_key?: ReadonlyArray<Readonly<{prop: string}>>;
|
||||
array_object_optional_value: ArrayObjectType | null | void;
|
||||
array_object_optional_both?: ReadonlyArray<ObjectType> | null | void;
|
||||
array_object_optional_value: ArrayObjectType | null | undefined;
|
||||
array_object_optional_both?: ReadonlyArray<ObjectType> | null | undefined;
|
||||
|
||||
// Nested array object types
|
||||
array_of_array_object_required: ReadonlyArray<
|
||||
@@ -426,18 +426,18 @@ export interface ModuleProps extends ViewProps {
|
||||
Readonly<{
|
||||
// This needs to be the same name as the top level array above
|
||||
array_object_optional_value: ReadonlyArray<
|
||||
Readonly<{prop: string | null | void}>
|
||||
Readonly<{prop: string | null | undefined}>
|
||||
>;
|
||||
}>
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
array_of_array_object_optional_both?: ReadonlyArray<
|
||||
Readonly<{
|
||||
// This needs to be the same name as the top level array above
|
||||
array_object_optional_both: ReadonlyArray<
|
||||
Readonly<{prop?: string | null | void}>
|
||||
Readonly<{prop?: string | null | undefined}>
|
||||
>;
|
||||
}>
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
// Nested array of array of object types
|
||||
array_of_array_of_object_required: ReadonlyArray<
|
||||
@@ -459,6 +459,138 @@ export default codegenNativeComponent<ModuleProps>(
|
||||
) as HostComponent<ModuleProps>;
|
||||
`;
|
||||
|
||||
const ARRAY2_PROP_TYPES_NO_EVENTS = `
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const codegenNativeComponent = require('codegenNativeComponent');
|
||||
|
||||
import type {Int32, Double, Float, WithDefault} from 'CodegenTypes';
|
||||
import type {ImageSource} from 'ImageSource';
|
||||
import type {
|
||||
ColorValue,
|
||||
ColorArrayValue,
|
||||
PointValue,
|
||||
EdgeInsetsValue,
|
||||
} from 'StyleSheetTypes';
|
||||
import type {ViewProps} from 'ViewPropTypes';
|
||||
import type {HostComponent} from 'react-native';
|
||||
|
||||
type ObjectType = Readonly<{prop: string}>;
|
||||
type ArrayObjectType = readonly Readonly<{prop: string}>[];
|
||||
|
||||
export interface ModuleProps extends ViewProps {
|
||||
// Props
|
||||
// Boolean props
|
||||
array_boolean_required: readonly boolean[];
|
||||
array_boolean_optional_key?: readonly boolean[];
|
||||
array_boolean_optional_value: readonly boolean[] | null | undefined;
|
||||
array_boolean_optional_both?: readonly boolean[] | null | undefined;
|
||||
|
||||
// String props
|
||||
array_string_required: readonly string[];
|
||||
array_string_optional_key?: readonly string[];
|
||||
array_string_optional_value: readonly string[] | null | undefined;
|
||||
array_string_optional_both?: readonly string[] | null | undefined;
|
||||
|
||||
// Double props
|
||||
array_double_required: readonly Double[];
|
||||
array_double_optional_key?: readonly Double[];
|
||||
array_double_optional_value: readonly Double[] | null | undefined;
|
||||
array_double_optional_both?: readonly Double[] | null | undefined;
|
||||
|
||||
// Float props
|
||||
array_float_required: readonly Float[];
|
||||
array_float_optional_key?: readonly Float[];
|
||||
array_float_optional_value: readonly Float[] | null | undefined;
|
||||
array_float_optional_both?: readonly Float[] | null | undefined;
|
||||
|
||||
// Int32 props
|
||||
array_int32_required: readonly Int32[];
|
||||
array_int32_optional_key?: readonly Int32[];
|
||||
array_int32_optional_value: readonly Int32[] | null | undefined;
|
||||
array_int32_optional_both?: readonly Int32[] | null | undefined;
|
||||
|
||||
// String enum props
|
||||
array_enum_optional_key?: WithDefault<
|
||||
readonly ('small' | 'large')[],
|
||||
'small'
|
||||
>;
|
||||
array_enum_optional_both?: WithDefault<
|
||||
readonly ('small' | 'large')[],
|
||||
'small'
|
||||
>;
|
||||
|
||||
// ImageSource props
|
||||
array_image_required: readonly ImageSource[];
|
||||
array_image_optional_key?: readonly ImageSource[];
|
||||
array_image_optional_value: readonly ImageSource[] | null | undefined;
|
||||
array_image_optional_both?: readonly ImageSource[] | null | undefined;
|
||||
|
||||
// ColorValue props
|
||||
array_color_required: readonly ColorValue[];
|
||||
array_color_optional_key?: readonly ColorValue[];
|
||||
array_color_optional_value: readonly ColorValue[] | null | undefined;
|
||||
array_color_optional_both?: readonly ColorValue[] | null | undefined;
|
||||
|
||||
// PointValue props
|
||||
array_point_required: readonly PointValue[];
|
||||
array_point_optional_key?: readonly PointValue[];
|
||||
array_point_optional_value: readonly PointValue[] | null | undefined;
|
||||
array_point_optional_both?: readonly PointValue[] | null | undefined;
|
||||
|
||||
// EdgeInsetsValue props
|
||||
array_insets_required: readonly EdgeInsetsValue[];
|
||||
array_insets_optional_key?: readonly EdgeInsetsValue[];
|
||||
array_insets_optional_value: readonly EdgeInsetsValue[] | null | undefined;
|
||||
array_insets_optional_both?: readonly EdgeInsetsValue[] | null | undefined;
|
||||
|
||||
// Object props
|
||||
array_object_required: readonly Readonly<{prop: string}>[];
|
||||
array_object_optional_key?: readonly Readonly<{prop: string}>[];
|
||||
array_object_optional_value: ArrayObjectType | null | undefined;
|
||||
array_object_optional_both?: readonly ObjectType[] | null | undefined;
|
||||
|
||||
// Nested array object types
|
||||
array_of_array_object_required: readonly Readonly<{
|
||||
// This needs to be the same name as the top level array above
|
||||
array_object_required: readonly Readonly<{prop: string}>[];
|
||||
}>[];
|
||||
array_of_array_object_optional_key?: readonly Readonly<{
|
||||
// This needs to be the same name as the top level array above
|
||||
array_object_optional_key: readonly Readonly<{prop?: string}>[];
|
||||
}>[];
|
||||
array_of_array_object_optional_value: readonly Readonly<{
|
||||
// This needs to be the same name as the top level array above
|
||||
array_object_optional_value: readonly Readonly<{prop: string | null | undefined}>[];
|
||||
}>[] | null | undefined;
|
||||
array_of_array_object_optional_both?: readonly Readonly<{
|
||||
// This needs to be the same name as the top level array above
|
||||
array_object_optional_both: readonly Readonly<{prop?: string | null | undefined}>[];
|
||||
}>[] | null | undefined;
|
||||
|
||||
// Nested array of array of object types
|
||||
array_of_array_of_object_required: readonly Readonly<{
|
||||
prop: string;
|
||||
}>[][];
|
||||
|
||||
// Nested array of array of object types (in file)
|
||||
array_of_array_of_object_required_in_file: readonly ObjectType[][];
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>(
|
||||
'Module',
|
||||
) as HostComponent<ModuleProps>;
|
||||
`;
|
||||
|
||||
const OBJECT_PROP_TYPES_NO_EVENTS = `
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
@@ -514,46 +646,46 @@ export interface ModuleProps extends ViewProps {
|
||||
// ImageSource props
|
||||
image_required: Readonly<{prop: ImageSource}>;
|
||||
image_optional_key: Readonly<{prop?: ImageSource}>;
|
||||
image_optional_value: Readonly<{prop: ImageSource | null | void}>;
|
||||
image_optional_both: Readonly<{prop?: ImageSource | null | void}>;
|
||||
image_optional_value: Readonly<{prop: ImageSource | null | undefined}>;
|
||||
image_optional_both: Readonly<{prop?: ImageSource | null | undefined}>;
|
||||
|
||||
// ColorValue props
|
||||
color_required: Readonly<{prop: ColorValue}>;
|
||||
color_optional_key: Readonly<{prop?: ColorValue}>;
|
||||
color_optional_value: Readonly<{prop: ColorValue | null | void}>;
|
||||
color_optional_both: Readonly<{prop?: ColorValue | null | void}>;
|
||||
color_optional_value: Readonly<{prop: ColorValue | null | undefined}>;
|
||||
color_optional_both: Readonly<{prop?: ColorValue | null | undefined}>;
|
||||
|
||||
// ProcessedColorValue props
|
||||
processed_color_required: Readonly<{prop: ProcessedColorValue}>;
|
||||
processed_color_optional_key: Readonly<{prop?: ProcessedColorValue}>;
|
||||
processed_color_optional_value: Readonly<{
|
||||
prop: ProcessedColorValue | null | void;
|
||||
prop: ProcessedColorValue | null | undefined;
|
||||
}>;
|
||||
processed_color_optional_both: Readonly<{
|
||||
prop?: ProcessedColorValue | null | void;
|
||||
prop?: ProcessedColorValue | null | undefined;
|
||||
}>;
|
||||
|
||||
// PointValue props
|
||||
point_required: Readonly<{prop: PointValue}>;
|
||||
point_optional_key: Readonly<{prop?: PointValue}>;
|
||||
point_optional_value: Readonly<{prop: PointValue | null | void}>;
|
||||
point_optional_both: Readonly<{prop?: PointValue | null | void}>;
|
||||
point_optional_value: Readonly<{prop: PointValue | null | undefined}>;
|
||||
point_optional_both: Readonly<{prop?: PointValue | null | undefined}>;
|
||||
|
||||
// EdgeInsetsValue props
|
||||
insets_required: Readonly<{prop: EdgeInsetsValue}>;
|
||||
insets_optional_key: Readonly<{prop?: EdgeInsetsValue}>;
|
||||
insets_optional_value: Readonly<{prop: EdgeInsetsValue | null | void}>;
|
||||
insets_optional_both: Readonly<{prop?: EdgeInsetsValue | null | void}>;
|
||||
insets_optional_value: Readonly<{prop: EdgeInsetsValue | null | undefined}>;
|
||||
insets_optional_both: Readonly<{prop?: EdgeInsetsValue | null | undefined}>;
|
||||
|
||||
// Nested object props
|
||||
object_required: Readonly<{prop: Readonly<{nestedProp: string}>}>;
|
||||
object_optional_key?: Readonly<{prop: Readonly<{nestedProp: string}>}>;
|
||||
object_optional_value: Readonly<{
|
||||
prop: Readonly<{nestedProp: string}>;
|
||||
}> | null | void;
|
||||
}> | null | undefined;
|
||||
object_optional_both?: Readonly<{
|
||||
prop: Readonly<{nestedProp: string}>;
|
||||
}> | null | void;
|
||||
}> | null | undefined;
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>(
|
||||
@@ -642,20 +774,20 @@ export interface ModuleProps extends ViewProps {
|
||||
Readonly<{
|
||||
${EVENT_DEFINITION}
|
||||
}>
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
onDirectEventDefinedInlineOptionalBoth?: DirectEventHandler<
|
||||
Readonly<{
|
||||
${EVENT_DEFINITION}
|
||||
}>
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
onDirectEventDefinedInlineWithPaperName?: DirectEventHandler<
|
||||
Readonly<{
|
||||
${EVENT_DEFINITION}
|
||||
}>,
|
||||
'paperDirectEventDefinedInlineWithPaperName'
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
onBubblingEventDefinedInline: BubblingEventHandler<
|
||||
Readonly<{
|
||||
@@ -673,20 +805,20 @@ export interface ModuleProps extends ViewProps {
|
||||
Readonly<{
|
||||
${EVENT_DEFINITION}
|
||||
}>
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
onBubblingEventDefinedInlineOptionalBoth?: BubblingEventHandler<
|
||||
Readonly<{
|
||||
${EVENT_DEFINITION}
|
||||
}>
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
onBubblingEventDefinedInlineWithPaperName?: BubblingEventHandler<
|
||||
Readonly<{
|
||||
${EVENT_DEFINITION}
|
||||
}>,
|
||||
'paperBubblingEventDefinedInlineWithPaperName'
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>(
|
||||
@@ -718,21 +850,21 @@ export interface ModuleProps extends ViewProps {
|
||||
// Events defined inline
|
||||
onDirectEventDefinedInlineNull: DirectEventHandler<null>;
|
||||
onDirectEventDefinedInlineNullOptionalKey?: DirectEventHandler<null>;
|
||||
onDirectEventDefinedInlineNullOptionalValue: DirectEventHandler<null> | null | void;
|
||||
onDirectEventDefinedInlineNullOptionalValue: DirectEventHandler<null> | null | undefined;
|
||||
onDirectEventDefinedInlineNullOptionalBoth?: DirectEventHandler<null>;
|
||||
onDirectEventDefinedInlineNullWithPaperName?: DirectEventHandler<
|
||||
null,
|
||||
'paperDirectEventDefinedInlineNullWithPaperName'
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
|
||||
onBubblingEventDefinedInlineNull: BubblingEventHandler<null>;
|
||||
onBubblingEventDefinedInlineNullOptionalKey?: BubblingEventHandler<null>;
|
||||
onBubblingEventDefinedInlineNullOptionalValue: BubblingEventHandler<null> | null | void;
|
||||
onBubblingEventDefinedInlineNullOptionalBoth?: BubblingEventHandler<null> | null | void;
|
||||
onBubblingEventDefinedInlineNullOptionalValue: BubblingEventHandler<null> | null | undefined;
|
||||
onBubblingEventDefinedInlineNullOptionalBoth?: BubblingEventHandler<null> | null | undefined;
|
||||
onBubblingEventDefinedInlineNullWithPaperName?: BubblingEventHandler<
|
||||
null,
|
||||
'paperBubblingEventDefinedInlineNullWithPaperName'
|
||||
> | null | void;
|
||||
> | null | undefined;
|
||||
}
|
||||
|
||||
export default codegenNativeComponent<ModuleProps>(
|
||||
@@ -959,6 +1091,7 @@ export default codegenNativeComponent<ModuleProps>(
|
||||
module.exports = {
|
||||
ALL_PROP_TYPES_NO_EVENTS,
|
||||
ARRAY_PROP_TYPES_NO_EVENTS,
|
||||
ARRAY2_PROP_TYPES_NO_EVENTS,
|
||||
OBJECT_PROP_TYPES_NO_EVENTS,
|
||||
PROPS_ALIASED_LOCALLY,
|
||||
ONE_OF_EACH_PROP_EVENT_DEFAULT_AND_OPTIONS,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user