mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
feat(android): allow passing filter function for prop folly::dynamic conversion (#48202)
Summary: ### Motivation - We need to exclude certain prop keys from conversion to `folly::dynamic` on android for our custom use case where we pass down `jsi::object`s with NativeState attached down the props Otherwise we run into crashes such as:  ### Changes - `dynamicFromValue` was marked as `noexcept` although it can throw, I removed the `noexcept` for correctness - Made it so you can pass down a filter function to exclude certain props from conversion (using the existing mechanism for that) - I think there is no way to pass a filter function and retain it in `RawProps` as that is constructed very early on in `UIManagerBinding` ## Changelog: <!-- Help reviewers and the release process by writing your own changelog entry. Pick one each for the category and type tags: [ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message For more details, see: https://reactnative.dev/contributing/changelogs-in-pull-requests --> [INTERNAL] [ADDED] - Allow passing a filter function to `BaseViewProps` to exclude certain props on android from being dynamically casted Pull Request resolved: https://github.com/facebook/react-native/pull/48202 Test Plan: You can try modifying for example `ScrollViewProps.cpp` and pass a fourth argument to `ViewProps` to confirm that the filtering is working: ```cpp ScrollViewProps::ScrollViewProps( const PropsParserContext& context, const ScrollViewProps& sourceProps, const RawProps& rawProps) : ViewProps(context, sourceProps, rawProps, [&](const std::string& keyName){ return true; }), ``` Reviewed By: NickGerleman Differential Revision: D67088540 Pulled By: javache fbshipit-source-id: ed8cf5d773d357dfc54553f5ccf7adf27c781d56
This commit is contained in:
committed by
Facebook GitHub Bot
parent
1763321c89
commit
feff4a7556
@@ -53,8 +53,9 @@ std::array<float, 3> getTranslateForTransformOrigin(
|
||||
BaseViewProps::BaseViewProps(
|
||||
const PropsParserContext& context,
|
||||
const BaseViewProps& sourceProps,
|
||||
const RawProps& rawProps)
|
||||
: YogaStylableProps(context, sourceProps, rawProps),
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys)
|
||||
: YogaStylableProps(context, sourceProps, rawProps, filterObjectKeys),
|
||||
AccessibilityProps(context, sourceProps, rawProps),
|
||||
opacity(
|
||||
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
||||
|
||||
@@ -31,7 +31,9 @@ class BaseViewProps : public YogaStylableProps, public AccessibilityProps {
|
||||
BaseViewProps(
|
||||
const PropsParserContext& context,
|
||||
const BaseViewProps& sourceProps,
|
||||
const RawProps& rawProps);
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys =
|
||||
nullptr);
|
||||
|
||||
void setProp(
|
||||
const PropsParserContext& context,
|
||||
|
||||
+3
-2
@@ -18,9 +18,10 @@ namespace facebook::react {
|
||||
YogaStylableProps::YogaStylableProps(
|
||||
const PropsParserContext& context,
|
||||
const YogaStylableProps& sourceProps,
|
||||
const RawProps& rawProps)
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys)
|
||||
: Props() {
|
||||
initialize(context, sourceProps, rawProps);
|
||||
initialize(context, sourceProps, rawProps, filterObjectKeys);
|
||||
|
||||
yogaStyle.setDirection(convertRawProp(
|
||||
context,
|
||||
|
||||
+3
-1
@@ -21,7 +21,9 @@ class YogaStylableProps : public Props {
|
||||
YogaStylableProps(
|
||||
const PropsParserContext& context,
|
||||
const YogaStylableProps& sourceProps,
|
||||
const RawProps& rawProps);
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys =
|
||||
nullptr);
|
||||
|
||||
void setProp(
|
||||
const PropsParserContext& context,
|
||||
|
||||
+3
-2
@@ -20,8 +20,9 @@ namespace facebook::react {
|
||||
HostPlatformViewProps::HostPlatformViewProps(
|
||||
const PropsParserContext& context,
|
||||
const HostPlatformViewProps& sourceProps,
|
||||
const RawProps& rawProps)
|
||||
: BaseViewProps(context, sourceProps, rawProps),
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys)
|
||||
: BaseViewProps(context, sourceProps, rawProps, filterObjectKeys),
|
||||
elevation(
|
||||
ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
||||
? sourceProps.elevation
|
||||
|
||||
+3
-1
@@ -26,7 +26,9 @@ class HostPlatformViewProps : public BaseViewProps {
|
||||
HostPlatformViewProps(
|
||||
const PropsParserContext& context,
|
||||
const HostPlatformViewProps& sourceProps,
|
||||
const RawProps& rawProps);
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys =
|
||||
nullptr);
|
||||
|
||||
void setProp(
|
||||
const PropsParserContext& context,
|
||||
|
||||
@@ -17,19 +17,22 @@ namespace facebook::react {
|
||||
Props::Props(
|
||||
const PropsParserContext& context,
|
||||
const Props& sourceProps,
|
||||
const RawProps& rawProps) {
|
||||
initialize(context, sourceProps, rawProps);
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys) {
|
||||
initialize(context, sourceProps, rawProps, filterObjectKeys);
|
||||
}
|
||||
|
||||
void Props::initialize(
|
||||
const PropsParserContext& context,
|
||||
const Props& sourceProps,
|
||||
const RawProps& rawProps) {
|
||||
const RawProps& rawProps,
|
||||
[[maybe_unused]] const std::function<bool(const std::string&)>&
|
||||
filterObjectKeys) {
|
||||
nativeId = ReactNativeFeatureFlags::enableCppPropsIteratorSetter()
|
||||
? sourceProps.nativeId
|
||||
: convertRawProp(context, rawProps, "nativeID", sourceProps.nativeId, {});
|
||||
#ifdef ANDROID
|
||||
this->rawProps = (folly::dynamic)rawProps;
|
||||
this->rawProps = rawProps.toDynamic(filterObjectKeys);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -33,7 +33,9 @@ class Props : public virtual Sealable, public virtual DebugStringConvertible {
|
||||
Props(
|
||||
const PropsParserContext& context,
|
||||
const Props& sourceProps,
|
||||
const RawProps& rawProps);
|
||||
const RawProps& rawProps,
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys =
|
||||
nullptr);
|
||||
virtual ~Props() = default;
|
||||
|
||||
Props(const Props& other) = delete;
|
||||
@@ -71,7 +73,13 @@ class Props : public virtual Sealable, public virtual DebugStringConvertible {
|
||||
void initialize(
|
||||
const PropsParserContext& context,
|
||||
const Props& sourceProps,
|
||||
const RawProps& rawProps);
|
||||
const RawProps& rawProps,
|
||||
/**
|
||||
* Filter object keys to be excluded when converting the RawProps to
|
||||
* folly::dynamic (android only)
|
||||
*/
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys =
|
||||
nullptr);
|
||||
};
|
||||
|
||||
} // namespace facebook::react
|
||||
|
||||
@@ -172,13 +172,38 @@ void RawProps::parse(const RawPropsParser& parser) noexcept {
|
||||
* The support for explicit conversion to `folly::dynamic` is deprecated and
|
||||
* will be removed as soon Android implementation does not need it.
|
||||
*/
|
||||
RawProps::operator folly::dynamic() const noexcept {
|
||||
RawProps::operator folly::dynamic() const {
|
||||
return toDynamic();
|
||||
}
|
||||
|
||||
/*
|
||||
* Deprecated. Do not use.
|
||||
* The support for explicit conversion to `folly::dynamic` is deprecated and
|
||||
* will be removed as soon Android implementation does not need it.
|
||||
*/
|
||||
folly::dynamic RawProps::toDynamic(
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys) const {
|
||||
switch (mode_) {
|
||||
case Mode::Empty:
|
||||
return folly::dynamic::object();
|
||||
case Mode::JSI:
|
||||
return jsi::dynamicFromValue(
|
||||
*runtime_, value_, ignoreYogaStyleProps_ ? isYogaStyleProp : nullptr);
|
||||
case Mode::JSI: {
|
||||
if (ignoreYogaStyleProps_ || filterObjectKeys != nullptr) {
|
||||
// We need to filter props
|
||||
return jsi::dynamicFromValue(
|
||||
*runtime_, value_, [&](const std::string& key) {
|
||||
if (ignoreYogaStyleProps_ && isYogaStyleProp(key)) {
|
||||
return true;
|
||||
}
|
||||
if (filterObjectKeys) {
|
||||
return filterObjectKeys(key);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
} else {
|
||||
// We don't need to filter, just include all props by default
|
||||
return jsi::dynamicFromValue(*runtime_, value_, nullptr);
|
||||
}
|
||||
}
|
||||
case Mode::Dynamic:
|
||||
return dynamic_;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,16 @@ class RawProps final {
|
||||
* The support for explicit conversion to `folly::dynamic` is deprecated and
|
||||
* will be removed as soon Android implementation does not need it.
|
||||
*/
|
||||
explicit operator folly::dynamic() const noexcept;
|
||||
explicit operator folly::dynamic() const;
|
||||
|
||||
/*
|
||||
* Deprecated. Do not use.
|
||||
* The support for explicit conversion to `folly::dynamic` is deprecated and
|
||||
* will be removed as soon Android implementation does not need it.
|
||||
*/
|
||||
folly::dynamic toDynamic(
|
||||
const std::function<bool(const std::string&)>& filterObjectKeys =
|
||||
nullptr) const;
|
||||
|
||||
/*
|
||||
* Once called, Yoga style props will be filtered out during conversion to
|
||||
|
||||
Reference in New Issue
Block a user