yeet
This commit is contained in:
185
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputComponentDescriptor.h
generated
vendored
Normal file
185
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputComponentDescriptor.h
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/core/ConcreteComponentDescriptor.h>
|
||||
#include "AndroidTextInputShadowNode.h"
|
||||
|
||||
#include <yoga/CompactValue.h>
|
||||
#include <yoga/YGEnums.h>
|
||||
#include <yoga/YGValue.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Descriptor for <AndroidTextInput> component.
|
||||
*/
|
||||
class AndroidTextInputComponentDescriptor final
|
||||
: public ConcreteComponentDescriptor<AndroidTextInputShadowNode> {
|
||||
public:
|
||||
AndroidTextInputComponentDescriptor(
|
||||
ComponentDescriptorParameters const ¶meters)
|
||||
: ConcreteComponentDescriptor<AndroidTextInputShadowNode>(parameters) {
|
||||
// Every single `AndroidTextInputShadowNode` will have a reference to
|
||||
// a shared `TextLayoutManager`.
|
||||
textLayoutManager_ = std::make_shared<TextLayoutManager>(contextContainer_);
|
||||
}
|
||||
|
||||
virtual State::Shared createInitialState(
|
||||
ShadowNodeFragment const &fragment,
|
||||
ShadowNodeFamily::Shared const &family) const override {
|
||||
int surfaceId = family->getSurfaceId();
|
||||
|
||||
float defaultThemePaddingStart = NAN;
|
||||
float defaultThemePaddingEnd = NAN;
|
||||
float defaultThemePaddingTop = NAN;
|
||||
float defaultThemePaddingBottom = NAN;
|
||||
|
||||
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
|
||||
surfaceIdToThemePaddingMap_.end()) {
|
||||
YGStyle::Edges theme = surfaceIdToThemePaddingMap_[surfaceId];
|
||||
defaultThemePaddingStart = ((YGValue)theme[YGEdgeStart]).value;
|
||||
defaultThemePaddingEnd = ((YGValue)theme[YGEdgeEnd]).value;
|
||||
defaultThemePaddingTop = ((YGValue)theme[YGEdgeTop]).value;
|
||||
defaultThemePaddingBottom = ((YGValue)theme[YGEdgeBottom]).value;
|
||||
}
|
||||
|
||||
return std::make_shared<AndroidTextInputShadowNode::ConcreteState>(
|
||||
std::make_shared<AndroidTextInputState const>(AndroidTextInputState(
|
||||
0,
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
{},
|
||||
textLayoutManager_,
|
||||
defaultThemePaddingStart,
|
||||
defaultThemePaddingEnd,
|
||||
defaultThemePaddingTop,
|
||||
defaultThemePaddingBottom)),
|
||||
family);
|
||||
}
|
||||
|
||||
protected:
|
||||
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||
assert(std::dynamic_pointer_cast<AndroidTextInputShadowNode>(shadowNode));
|
||||
auto textInputShadowNode =
|
||||
std::static_pointer_cast<AndroidTextInputShadowNode>(shadowNode);
|
||||
|
||||
// `ParagraphShadowNode` uses `TextLayoutManager` to measure text content
|
||||
// and communicate text rendering metrics to mounting layer.
|
||||
textInputShadowNode->setTextLayoutManager(textLayoutManager_);
|
||||
|
||||
textInputShadowNode->setContextContainer(
|
||||
const_cast<ContextContainer *>(getContextContainer().get()));
|
||||
|
||||
// Get theme padding from cache, or set it from State.
|
||||
// In theory, the Java ViewManager for TextInput should need to set state
|
||||
// *exactly once* per surface to communicate the correct default padding,
|
||||
// which will be cached here in C++.
|
||||
// TODO T63008435: can this feature be removed entirely?
|
||||
// TODO: figure out RTL/start/end/left/right stuff here
|
||||
int surfaceId = textInputShadowNode->getSurfaceId();
|
||||
const AndroidTextInputState &state = textInputShadowNode->getStateData();
|
||||
if (surfaceIdToThemePaddingMap_.find(surfaceId) ==
|
||||
surfaceIdToThemePaddingMap_.end() &&
|
||||
!isnan(state.defaultThemePaddingStart)) {
|
||||
YGStyle::Edges result;
|
||||
result[YGEdgeStart] =
|
||||
(YGValue){state.defaultThemePaddingStart, YGUnitPoint};
|
||||
result[YGEdgeEnd] = (YGValue){state.defaultThemePaddingEnd, YGUnitPoint};
|
||||
result[YGEdgeTop] = (YGValue){state.defaultThemePaddingTop, YGUnitPoint};
|
||||
result[YGEdgeBottom] =
|
||||
(YGValue){state.defaultThemePaddingBottom, YGUnitPoint};
|
||||
surfaceIdToThemePaddingMap_.emplace(std::make_pair(surfaceId, result));
|
||||
}
|
||||
|
||||
if (surfaceIdToThemePaddingMap_.find(surfaceId) !=
|
||||
surfaceIdToThemePaddingMap_.end()) {
|
||||
YGStyle::Edges theme = surfaceIdToThemePaddingMap_[surfaceId];
|
||||
|
||||
// Override padding
|
||||
// Node is still unsealed during adoption, before layout is complete
|
||||
// TODO: T62959168 account for RTL and paddingLeft when setting default
|
||||
// paddingStart, and vice-versa with paddingRight/paddingEnd.
|
||||
// For now this assumes no RTL.
|
||||
YGStyle::Edges result =
|
||||
textInputShadowNode->getConcreteProps().yogaStyle.padding();
|
||||
bool changedPadding = false;
|
||||
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingStart &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingLeft &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingHorizontal) {
|
||||
changedPadding = true;
|
||||
result[YGEdgeStart] = theme[YGEdgeStart];
|
||||
}
|
||||
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingEnd &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingRight &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingHorizontal) {
|
||||
changedPadding = true;
|
||||
result[YGEdgeEnd] = theme[YGEdgeEnd];
|
||||
}
|
||||
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingTop &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingVertical) {
|
||||
changedPadding = true;
|
||||
result[YGEdgeTop] = theme[YGEdgeTop];
|
||||
}
|
||||
if (!textInputShadowNode->getConcreteProps().hasPadding &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingBottom &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingVertical) {
|
||||
changedPadding = true;
|
||||
result[YGEdgeBottom] = theme[YGEdgeBottom];
|
||||
}
|
||||
|
||||
// If the TextInput initially does not have paddingLeft or paddingStart, a
|
||||
// paddingStart may be set from the theme. If that happens, when there's a
|
||||
// paddingLeft update, we must explicitly unset paddingStart... (same with
|
||||
// paddingEnd)
|
||||
// TODO: support RTL
|
||||
if ((textInputShadowNode->getConcreteProps().hasPadding ||
|
||||
textInputShadowNode->getConcreteProps().hasPaddingLeft ||
|
||||
textInputShadowNode->getConcreteProps().hasPaddingHorizontal) &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingStart) {
|
||||
result[YGEdgeStart] = YGValueUndefined;
|
||||
}
|
||||
if ((textInputShadowNode->getConcreteProps().hasPadding ||
|
||||
textInputShadowNode->getConcreteProps().hasPaddingRight ||
|
||||
textInputShadowNode->getConcreteProps().hasPaddingHorizontal) &&
|
||||
!textInputShadowNode->getConcreteProps().hasPaddingEnd) {
|
||||
result[YGEdgeEnd] = YGValueUndefined;
|
||||
}
|
||||
|
||||
// Note that this is expensive: on every adopt, we need to set the Yoga
|
||||
// props again, which normally only happens during prop parsing. Every
|
||||
// commit, state update, etc, will incur this cost.
|
||||
if (changedPadding) {
|
||||
// Set new props on node
|
||||
const_cast<AndroidTextInputProps &>(
|
||||
textInputShadowNode->getConcreteProps())
|
||||
.yogaStyle.padding() = result;
|
||||
// Communicate new props to Yoga part of the node
|
||||
textInputShadowNode->updateYogaProps();
|
||||
}
|
||||
}
|
||||
|
||||
textInputShadowNode->dirtyLayout();
|
||||
textInputShadowNode->enableMeasurement();
|
||||
|
||||
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||
}
|
||||
|
||||
private:
|
||||
SharedTextLayoutManager textLayoutManager_;
|
||||
mutable better::map<int, YGStyle::Edges> surfaceIdToThemePaddingMap_;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
179
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputEventEmitter.cpp
generated
vendored
Normal file
179
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputEventEmitter.cpp
generated
vendored
Normal file
@ -0,0 +1,179 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "AndroidTextInputEventEmitter.h"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
void AndroidTextInputEventEmitter::onBlur(
|
||||
AndroidTextInputOnBlurStruct event) const {
|
||||
dispatchEvent("blur", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onFocus(
|
||||
AndroidTextInputOnFocusStruct event) const {
|
||||
dispatchEvent("focus", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onChange(
|
||||
AndroidTextInputOnChangeStruct event) const {
|
||||
dispatchEvent("change", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(runtime, "eventCount", event.eventCount);
|
||||
payload.setProperty(runtime, "text", event.text);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onChangeText(
|
||||
AndroidTextInputOnChangeTextStruct event) const {
|
||||
dispatchEvent(
|
||||
"changeText", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(runtime, "eventCount", event.eventCount);
|
||||
payload.setProperty(runtime, "text", event.text);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onContentSizeChange(
|
||||
AndroidTextInputOnContentSizeChangeStruct event) const {
|
||||
dispatchEvent(
|
||||
"contentSizeChange", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
{
|
||||
auto contentSize = jsi::Object(runtime);
|
||||
contentSize.setProperty(runtime, "width", event.contentSize.width);
|
||||
contentSize.setProperty(runtime, "height", event.contentSize.height);
|
||||
|
||||
payload.setProperty(runtime, "contentSize", contentSize);
|
||||
}
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onTextInput(
|
||||
AndroidTextInputOnTextInputStruct event) const {
|
||||
dispatchEvent("textInput", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(runtime, "text", event.text);
|
||||
payload.setProperty(runtime, "previousText", event.previousText);
|
||||
{
|
||||
auto range = jsi::Object(runtime);
|
||||
range.setProperty(runtime, "start", event.range.start);
|
||||
range.setProperty(runtime, "end", event.range.end);
|
||||
|
||||
payload.setProperty(runtime, "range", range);
|
||||
}
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onEndEditing(
|
||||
AndroidTextInputOnEndEditingStruct event) const {
|
||||
dispatchEvent(
|
||||
"endEditing", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(runtime, "text", event.text);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onSelectionChange(
|
||||
AndroidTextInputOnSelectionChangeStruct event) const {
|
||||
dispatchEvent(
|
||||
"selectionChange", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
{
|
||||
auto selection = jsi::Object(runtime);
|
||||
selection.setProperty(runtime, "start", event.selection.start);
|
||||
selection.setProperty(runtime, "end", event.selection.end);
|
||||
|
||||
payload.setProperty(runtime, "selection", selection);
|
||||
}
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onSubmitEditing(
|
||||
AndroidTextInputOnSubmitEditingStruct event) const {
|
||||
dispatchEvent(
|
||||
"submitEditing", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(runtime, "text", event.text);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onKeyPress(
|
||||
AndroidTextInputOnKeyPressStruct event) const {
|
||||
dispatchEvent("keyPress", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(runtime, "key", event.key);
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
void AndroidTextInputEventEmitter::onScroll(
|
||||
AndroidTextInputOnScrollStruct event) const {
|
||||
dispatchEvent("scroll", [event = std::move(event)](jsi::Runtime &runtime) {
|
||||
auto payload = jsi::Object(runtime);
|
||||
payload.setProperty(runtime, "target", event.target);
|
||||
payload.setProperty(
|
||||
runtime, "responderIgnoreScroll", event.responderIgnoreScroll);
|
||||
{
|
||||
auto contentInset = jsi::Object(runtime);
|
||||
contentInset.setProperty(runtime, "top", event.contentInset.top);
|
||||
contentInset.setProperty(runtime, "bottom", event.contentInset.bottom);
|
||||
contentInset.setProperty(runtime, "left", event.contentInset.left);
|
||||
contentInset.setProperty(runtime, "right", event.contentInset.right);
|
||||
|
||||
payload.setProperty(runtime, "contentInset", contentInset);
|
||||
}
|
||||
{
|
||||
auto contentOffset = jsi::Object(runtime);
|
||||
contentOffset.setProperty(runtime, "x", event.contentOffset.x);
|
||||
contentOffset.setProperty(runtime, "y", event.contentOffset.y);
|
||||
|
||||
payload.setProperty(runtime, "contentOffset", contentOffset);
|
||||
}
|
||||
{
|
||||
auto contentSize = jsi::Object(runtime);
|
||||
contentSize.setProperty(runtime, "width", event.contentSize.width);
|
||||
contentSize.setProperty(runtime, "height", event.contentSize.height);
|
||||
|
||||
payload.setProperty(runtime, "contentSize", contentSize);
|
||||
}
|
||||
{
|
||||
auto layoutMeasurement = jsi::Object(runtime);
|
||||
layoutMeasurement.setProperty(
|
||||
runtime, "width", event.layoutMeasurement.width);
|
||||
layoutMeasurement.setProperty(
|
||||
runtime, "height", event.layoutMeasurement.height);
|
||||
|
||||
payload.setProperty(runtime, "layoutMeasurement", layoutMeasurement);
|
||||
}
|
||||
{
|
||||
auto velocity = jsi::Object(runtime);
|
||||
velocity.setProperty(runtime, "x", event.velocity.x);
|
||||
velocity.setProperty(runtime, "y", event.velocity.y);
|
||||
|
||||
payload.setProperty(runtime, "velocity", velocity);
|
||||
}
|
||||
return payload;
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
148
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputEventEmitter.h
generated
vendored
Normal file
148
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputEventEmitter.h
generated
vendored
Normal file
@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/components/view/ViewEventEmitter.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct AndroidTextInputOnBlurStruct {
|
||||
int target;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnFocusStruct {
|
||||
int target;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnChangeStruct {
|
||||
int target;
|
||||
int eventCount;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnChangeTextStruct {
|
||||
int target;
|
||||
int eventCount;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnContentSizeChangeContentSizeStruct {
|
||||
double width;
|
||||
double height;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnContentSizeChangeStruct {
|
||||
int target;
|
||||
AndroidTextInputOnContentSizeChangeContentSizeStruct contentSize;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnTextInputRangeStruct {
|
||||
double start;
|
||||
double end;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnTextInputStruct {
|
||||
int target;
|
||||
std::string text;
|
||||
std::string previousText;
|
||||
AndroidTextInputOnTextInputRangeStruct range;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnEndEditingStruct {
|
||||
int target;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnSelectionChangeSelectionStruct {
|
||||
double start;
|
||||
double end;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnSelectionChangeStruct {
|
||||
int target;
|
||||
AndroidTextInputOnSelectionChangeSelectionStruct selection;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnSubmitEditingStruct {
|
||||
int target;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnKeyPressStruct {
|
||||
int target;
|
||||
std::string key;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnScrollContentInsetStruct {
|
||||
double top;
|
||||
double bottom;
|
||||
double left;
|
||||
double right;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnScrollContentOffsetStruct {
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnScrollContentSizeStruct {
|
||||
double width;
|
||||
double height;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnScrollLayoutMeasurementStruct {
|
||||
double width;
|
||||
double height;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnScrollVelocityStruct {
|
||||
double x;
|
||||
double y;
|
||||
};
|
||||
|
||||
struct AndroidTextInputOnScrollStruct {
|
||||
int target;
|
||||
bool responderIgnoreScroll;
|
||||
AndroidTextInputOnScrollContentInsetStruct contentInset;
|
||||
AndroidTextInputOnScrollContentOffsetStruct contentOffset;
|
||||
AndroidTextInputOnScrollContentSizeStruct contentSize;
|
||||
AndroidTextInputOnScrollLayoutMeasurementStruct layoutMeasurement;
|
||||
AndroidTextInputOnScrollVelocityStruct velocity;
|
||||
};
|
||||
|
||||
class AndroidTextInputEventEmitter : public ViewEventEmitter {
|
||||
public:
|
||||
using ViewEventEmitter::ViewEventEmitter;
|
||||
|
||||
void onBlur(AndroidTextInputOnBlurStruct value) const;
|
||||
|
||||
void onFocus(AndroidTextInputOnFocusStruct value) const;
|
||||
|
||||
void onChange(AndroidTextInputOnChangeStruct value) const;
|
||||
|
||||
void onChangeText(AndroidTextInputOnChangeTextStruct value) const;
|
||||
|
||||
void onContentSizeChange(
|
||||
AndroidTextInputOnContentSizeChangeStruct value) const;
|
||||
|
||||
void onTextInput(AndroidTextInputOnTextInputStruct value) const;
|
||||
|
||||
void onEndEditing(AndroidTextInputOnEndEditingStruct value) const;
|
||||
|
||||
void onSelectionChange(AndroidTextInputOnSelectionChangeStruct value) const;
|
||||
|
||||
void onSubmitEditing(AndroidTextInputOnSubmitEditingStruct value) const;
|
||||
|
||||
void onKeyPress(AndroidTextInputOnKeyPressStruct value) const;
|
||||
|
||||
void onScroll(AndroidTextInputOnScrollStruct value) const;
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
370
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputProps.cpp
generated
vendored
Normal file
370
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputProps.cpp
generated
vendored
Normal file
@ -0,0 +1,370 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "AndroidTextInputProps.h"
|
||||
#include <react/components/image/conversions.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
#include <react/graphics/conversions.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
static bool hasValue(
|
||||
const RawProps &rawProps,
|
||||
bool defaultValue,
|
||||
const char *name,
|
||||
const char *prefix,
|
||||
const char *suffix) {
|
||||
auto rawValue = rawProps.at(name, prefix, suffix);
|
||||
|
||||
// No change to prop - use default
|
||||
if (rawValue == nullptr) {
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
// Value passed from JS
|
||||
if (rawValue->hasValue()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Null/undefined passed in, indicating that we should use the default
|
||||
// platform value - thereby resetting this
|
||||
return false;
|
||||
}
|
||||
|
||||
AndroidTextInputProps::AndroidTextInputProps(
|
||||
const AndroidTextInputProps &sourceProps,
|
||||
const RawProps &rawProps)
|
||||
: ViewProps(sourceProps, rawProps),
|
||||
BaseTextProps(sourceProps, rawProps),
|
||||
autoCompleteType(convertRawProp(
|
||||
rawProps,
|
||||
"autoCompleteType",
|
||||
sourceProps.autoCompleteType,
|
||||
{})),
|
||||
returnKeyLabel(convertRawProp(
|
||||
rawProps,
|
||||
"returnKeyLabel",
|
||||
sourceProps.returnKeyLabel,
|
||||
{})),
|
||||
numberOfLines(convertRawProp(
|
||||
rawProps,
|
||||
"numberOfLines",
|
||||
sourceProps.numberOfLines,
|
||||
{0})),
|
||||
disableFullscreenUI(convertRawProp(
|
||||
rawProps,
|
||||
"disableFullscreenUI",
|
||||
sourceProps.disableFullscreenUI,
|
||||
{false})),
|
||||
textBreakStrategy(convertRawProp(
|
||||
rawProps,
|
||||
"textBreakStrategy",
|
||||
sourceProps.textBreakStrategy,
|
||||
{})),
|
||||
underlineColorAndroid(convertRawProp(
|
||||
rawProps,
|
||||
"underlineColorAndroid",
|
||||
sourceProps.underlineColorAndroid,
|
||||
{})),
|
||||
inlineImageLeft(convertRawProp(
|
||||
rawProps,
|
||||
"inlineImageLeft",
|
||||
sourceProps.inlineImageLeft,
|
||||
{})),
|
||||
inlineImagePadding(convertRawProp(
|
||||
rawProps,
|
||||
"inlineImagePadding",
|
||||
sourceProps.inlineImagePadding,
|
||||
{0})),
|
||||
importantForAutofill(convertRawProp(
|
||||
rawProps,
|
||||
"importantForAutofill",
|
||||
sourceProps.importantForAutofill,
|
||||
{})),
|
||||
showSoftInputOnFocus(convertRawProp(
|
||||
rawProps,
|
||||
"showSoftInputOnFocus",
|
||||
sourceProps.showSoftInputOnFocus,
|
||||
{false})),
|
||||
autoCapitalize(convertRawProp(
|
||||
rawProps,
|
||||
"autoCapitalize",
|
||||
sourceProps.autoCapitalize,
|
||||
{})),
|
||||
autoCorrect(convertRawProp(
|
||||
rawProps,
|
||||
"autoCorrect",
|
||||
sourceProps.autoCorrect,
|
||||
{false})),
|
||||
autoFocus(convertRawProp(
|
||||
rawProps,
|
||||
"autoFocus",
|
||||
sourceProps.autoFocus,
|
||||
{false})),
|
||||
allowFontScaling(convertRawProp(
|
||||
rawProps,
|
||||
"allowFontScaling",
|
||||
sourceProps.allowFontScaling,
|
||||
{false})),
|
||||
maxFontSizeMultiplier(convertRawProp(
|
||||
rawProps,
|
||||
"maxFontSizeMultiplier",
|
||||
sourceProps.maxFontSizeMultiplier,
|
||||
{0.0})),
|
||||
editable(
|
||||
convertRawProp(rawProps, "editable", sourceProps.editable, {false})),
|
||||
keyboardType(convertRawProp(
|
||||
rawProps,
|
||||
"keyboardType",
|
||||
sourceProps.keyboardType,
|
||||
{})),
|
||||
returnKeyType(convertRawProp(
|
||||
rawProps,
|
||||
"returnKeyType",
|
||||
sourceProps.returnKeyType,
|
||||
{})),
|
||||
maxLength(
|
||||
convertRawProp(rawProps, "maxLength", sourceProps.maxLength, {0})),
|
||||
multiline(convertRawProp(
|
||||
rawProps,
|
||||
"multiline",
|
||||
sourceProps.multiline,
|
||||
{false})),
|
||||
placeholder(
|
||||
convertRawProp(rawProps, "placeholder", sourceProps.placeholder, {})),
|
||||
placeholderTextColor(convertRawProp(
|
||||
rawProps,
|
||||
"placeholderTextColor",
|
||||
sourceProps.placeholderTextColor,
|
||||
{})),
|
||||
secureTextEntry(convertRawProp(
|
||||
rawProps,
|
||||
"secureTextEntry",
|
||||
sourceProps.secureTextEntry,
|
||||
{false})),
|
||||
selectionColor(convertRawProp(
|
||||
rawProps,
|
||||
"selectionColor",
|
||||
sourceProps.selectionColor,
|
||||
{})),
|
||||
selection(
|
||||
convertRawProp(rawProps, "selection", sourceProps.selection, {})),
|
||||
value(convertRawProp(rawProps, "value", sourceProps.value, {})),
|
||||
defaultValue(convertRawProp(
|
||||
rawProps,
|
||||
"defaultValue",
|
||||
sourceProps.defaultValue,
|
||||
{})),
|
||||
selectTextOnFocus(convertRawProp(
|
||||
rawProps,
|
||||
"selectTextOnFocus",
|
||||
sourceProps.selectTextOnFocus,
|
||||
{false})),
|
||||
blurOnSubmit(convertRawProp(
|
||||
rawProps,
|
||||
"blurOnSubmit",
|
||||
sourceProps.blurOnSubmit,
|
||||
{false})),
|
||||
caretHidden(convertRawProp(
|
||||
rawProps,
|
||||
"caretHidden",
|
||||
sourceProps.caretHidden,
|
||||
{false})),
|
||||
contextMenuHidden(convertRawProp(
|
||||
rawProps,
|
||||
"contextMenuHidden",
|
||||
sourceProps.contextMenuHidden,
|
||||
{false})),
|
||||
textShadowColor(convertRawProp(
|
||||
rawProps,
|
||||
"textShadowColor",
|
||||
sourceProps.textShadowColor,
|
||||
{})),
|
||||
textShadowRadius(convertRawProp(
|
||||
rawProps,
|
||||
"textShadowRadius",
|
||||
sourceProps.textShadowRadius,
|
||||
{0.0})),
|
||||
textDecorationLine(convertRawProp(
|
||||
rawProps,
|
||||
"textDecorationLine",
|
||||
sourceProps.textDecorationLine,
|
||||
{})),
|
||||
fontStyle(
|
||||
convertRawProp(rawProps, "fontStyle", sourceProps.fontStyle, {})),
|
||||
textShadowOffset(convertRawProp(
|
||||
rawProps,
|
||||
"textShadowOffset",
|
||||
sourceProps.textShadowOffset,
|
||||
{})),
|
||||
lineHeight(convertRawProp(
|
||||
rawProps,
|
||||
"lineHeight",
|
||||
sourceProps.lineHeight,
|
||||
{0.0})),
|
||||
textTransform(convertRawProp(
|
||||
rawProps,
|
||||
"textTransform",
|
||||
sourceProps.textTransform,
|
||||
{})),
|
||||
color(convertRawProp(rawProps, "color", sourceProps.color, {0})),
|
||||
letterSpacing(convertRawProp(
|
||||
rawProps,
|
||||
"letterSpacing",
|
||||
sourceProps.letterSpacing,
|
||||
{0.0})),
|
||||
fontSize(
|
||||
convertRawProp(rawProps, "fontSize", sourceProps.fontSize, {0.0})),
|
||||
textAlign(
|
||||
convertRawProp(rawProps, "textAlign", sourceProps.textAlign, {})),
|
||||
includeFontPadding(convertRawProp(
|
||||
rawProps,
|
||||
"includeFontPadding",
|
||||
sourceProps.includeFontPadding,
|
||||
{false})),
|
||||
fontWeight(
|
||||
convertRawProp(rawProps, "fontWeight", sourceProps.fontWeight, {})),
|
||||
fontFamily(
|
||||
convertRawProp(rawProps, "fontFamily", sourceProps.fontFamily, {})),
|
||||
textAlignVertical(convertRawProp(
|
||||
rawProps,
|
||||
"textAlignVertical",
|
||||
sourceProps.textAlignVertical,
|
||||
{})),
|
||||
cursorColor(
|
||||
convertRawProp(rawProps, "cursorColor", sourceProps.cursorColor, {})),
|
||||
mostRecentEventCount(convertRawProp(
|
||||
rawProps,
|
||||
"mostRecentEventCount",
|
||||
sourceProps.mostRecentEventCount,
|
||||
{0})),
|
||||
text(convertRawProp(rawProps, "text", sourceProps.text, {})),
|
||||
paragraphAttributes(
|
||||
convertRawProp(rawProps, sourceProps.paragraphAttributes, {})),
|
||||
// See AndroidTextInputComponentDescriptor for usage
|
||||
// TODO T63008435: can these, and this feature, be removed entirely?
|
||||
hasPadding(hasValue(rawProps, sourceProps.hasPadding, "", "padding", "")),
|
||||
hasPaddingHorizontal(hasValue(
|
||||
rawProps,
|
||||
sourceProps.hasPaddingHorizontal,
|
||||
"Horizontal",
|
||||
"padding",
|
||||
"")),
|
||||
hasPaddingVertical(hasValue(
|
||||
rawProps,
|
||||
sourceProps.hasPaddingVertical,
|
||||
"Vertical",
|
||||
"padding",
|
||||
"")),
|
||||
hasPaddingLeft(hasValue(
|
||||
rawProps,
|
||||
sourceProps.hasPaddingLeft,
|
||||
"Left",
|
||||
"padding",
|
||||
"")),
|
||||
hasPaddingTop(
|
||||
hasValue(rawProps, sourceProps.hasPaddingTop, "Top", "padding", "")),
|
||||
hasPaddingRight(hasValue(
|
||||
rawProps,
|
||||
sourceProps.hasPaddingRight,
|
||||
"Right",
|
||||
"padding",
|
||||
"")),
|
||||
hasPaddingBottom(hasValue(
|
||||
rawProps,
|
||||
sourceProps.hasPaddingBottom,
|
||||
"Bottom",
|
||||
"padding",
|
||||
"")),
|
||||
hasPaddingStart(hasValue(
|
||||
rawProps,
|
||||
sourceProps.hasPaddingStart,
|
||||
"Start",
|
||||
"padding",
|
||||
"")),
|
||||
hasPaddingEnd(
|
||||
hasValue(rawProps, sourceProps.hasPaddingEnd, "End", "padding", "")) {
|
||||
}
|
||||
|
||||
// TODO T53300085: support this in codegen; this was hand-written
|
||||
folly::dynamic AndroidTextInputProps::getDynamic() const {
|
||||
folly::dynamic props = folly::dynamic::object();
|
||||
props["autoCompleteType"] = autoCompleteType;
|
||||
props["returnKeyLabel"] = returnKeyLabel;
|
||||
props["numberOfLines"] = numberOfLines;
|
||||
props["disableFullscreenUI"] = disableFullscreenUI;
|
||||
props["textBreakStrategy"] = textBreakStrategy;
|
||||
props["underlineColorAndroid"] = toDynamic(underlineColorAndroid);
|
||||
props["inlineImageLeft"] = inlineImageLeft;
|
||||
props["inlineImagePadding"] = inlineImagePadding;
|
||||
props["importantForAutofill"] = importantForAutofill;
|
||||
props["showSoftInputOnFocus"] = showSoftInputOnFocus;
|
||||
props["autoCapitalize"] = autoCapitalize;
|
||||
props["autoCorrect"] = autoCorrect;
|
||||
props["autoFocus"] = autoFocus;
|
||||
props["allowFontScaling"] = allowFontScaling;
|
||||
props["maxFontSizeMultiplier"] = maxFontSizeMultiplier;
|
||||
props["editable"] = editable;
|
||||
props["keyboardType"] = keyboardType;
|
||||
props["returnKeyType"] = returnKeyType;
|
||||
props["maxLength"] = maxLength;
|
||||
props["multiline"] = multiline;
|
||||
props["placeholder"] = placeholder;
|
||||
props["placeholderTextColor"] = toDynamic(placeholderTextColor);
|
||||
props["secureTextEntry"] = secureTextEntry;
|
||||
props["selectionColor"] = toDynamic(selectionColor);
|
||||
props["selection"] = toDynamic(selection);
|
||||
props["value"] = value;
|
||||
props["defaultValue"] = defaultValue;
|
||||
props["selectTextOnFocus"] = selectTextOnFocus;
|
||||
props["blurOnSubmit"] = blurOnSubmit;
|
||||
props["caretHidden"] = caretHidden;
|
||||
props["contextMenuHidden"] = contextMenuHidden;
|
||||
props["textShadowColor"] = toDynamic(textShadowColor);
|
||||
props["textShadowRadius"] = textShadowRadius;
|
||||
props["textDecorationLine"] = textDecorationLine;
|
||||
props["fontStyle"] = fontStyle;
|
||||
props["textShadowOffset"] = toDynamic(textShadowOffset);
|
||||
props["lineHeight"] = lineHeight;
|
||||
props["textTransform"] = textTransform;
|
||||
props["color"] = color;
|
||||
props["letterSpacing"] = letterSpacing;
|
||||
props["fontSize"] = fontSize;
|
||||
props["textAlign"] = textAlign;
|
||||
props["includeFontPadding"] = includeFontPadding;
|
||||
props["fontWeight"] = fontWeight;
|
||||
props["fontFamily"] = fontFamily;
|
||||
props["textAlignVertical"] = textAlignVertical;
|
||||
props["cursorColor"] = toDynamic(cursorColor);
|
||||
props["mostRecentEventCount"] = mostRecentEventCount;
|
||||
props["text"] = text;
|
||||
|
||||
props["hasPadding"] = hasPadding;
|
||||
props["hasPaddingHorizontal"] = hasPaddingHorizontal;
|
||||
props["hasPaddingVertical"] = hasPaddingVertical;
|
||||
props["hasPaddingStart"] = hasPaddingStart;
|
||||
props["hasPaddingEnd"] = hasPaddingEnd;
|
||||
props["hasPaddingLeft"] = hasPaddingLeft;
|
||||
props["hasPaddingRight"] = hasPaddingRight;
|
||||
props["hasPaddingTop"] = hasPaddingTop;
|
||||
props["hasPaddingBottom"] = hasPaddingBottom;
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
#pragma mark - DebugStringConvertible
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
// TODO: codegen these
|
||||
SharedDebugStringConvertibleList AndroidTextInputProps::getDebugProps() const {
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
183
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputProps.h
generated
vendored
Normal file
183
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputProps.h
generated
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
// #include <react/components/text/BaseTextProps.h>
|
||||
#include <react/core/Props.h>
|
||||
#include <react/graphics/Color.h>
|
||||
#include <react/graphics/Geometry.h>
|
||||
|
||||
#include <react/attributedstring/TextAttributes.h>
|
||||
#include <react/attributedstring/conversions.h>
|
||||
#include <react/components/text/BaseTextProps.h>
|
||||
#include <react/components/view/ViewProps.h>
|
||||
#include <react/core/propsConversions.h>
|
||||
#include <react/graphics/Color.h>
|
||||
#include <react/imagemanager/primitives.h>
|
||||
#include <cinttypes>
|
||||
#include <vector>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
struct AndroidTextInputSelectionStruct {
|
||||
int start;
|
||||
int end;
|
||||
};
|
||||
|
||||
static inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
AndroidTextInputSelectionStruct &result) {
|
||||
auto map = (better::map<std::string, RawValue>)value;
|
||||
|
||||
auto start = map.find("start");
|
||||
if (start != map.end()) {
|
||||
fromRawValue(start->second, result.start);
|
||||
}
|
||||
auto end = map.find("end");
|
||||
if (end != map.end()) {
|
||||
fromRawValue(end->second, result.end);
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string toString(
|
||||
const AndroidTextInputSelectionStruct &value) {
|
||||
return "[Object AndroidTextInputSelectionStruct]";
|
||||
}
|
||||
|
||||
struct AndroidTextInputTextShadowOffsetStruct {
|
||||
double width;
|
||||
double height;
|
||||
};
|
||||
|
||||
static inline void fromRawValue(
|
||||
const RawValue &value,
|
||||
AndroidTextInputTextShadowOffsetStruct &result) {
|
||||
auto map = (better::map<std::string, RawValue>)value;
|
||||
|
||||
auto width = map.find("width");
|
||||
if (width != map.end()) {
|
||||
fromRawValue(width->second, result.width);
|
||||
}
|
||||
auto height = map.find("height");
|
||||
if (height != map.end()) {
|
||||
fromRawValue(height->second, result.height);
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string toString(
|
||||
const AndroidTextInputTextShadowOffsetStruct &value) {
|
||||
return "[Object AndroidTextInputTextShadowOffsetStruct]";
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
inline folly::dynamic toDynamic(
|
||||
const AndroidTextInputTextShadowOffsetStruct &value) {
|
||||
folly::dynamic dynamicValue = folly::dynamic::object();
|
||||
dynamicValue["width"] = value.width;
|
||||
dynamicValue["height"] = value.height;
|
||||
return dynamicValue;
|
||||
}
|
||||
|
||||
inline folly::dynamic toDynamic(const AndroidTextInputSelectionStruct &value) {
|
||||
folly::dynamic dynamicValue = folly::dynamic::object();
|
||||
dynamicValue["start"] = value.start;
|
||||
dynamicValue["end"] = value.end;
|
||||
return dynamicValue;
|
||||
}
|
||||
#endif
|
||||
|
||||
class AndroidTextInputProps final : public ViewProps, public BaseTextProps {
|
||||
public:
|
||||
AndroidTextInputProps() = default;
|
||||
AndroidTextInputProps(
|
||||
const AndroidTextInputProps &sourceProps,
|
||||
const RawProps &rawProps);
|
||||
|
||||
folly::dynamic getDynamic() const;
|
||||
|
||||
#pragma mark - Props
|
||||
|
||||
const std::string autoCompleteType{};
|
||||
const std::string returnKeyLabel{};
|
||||
const int numberOfLines{0};
|
||||
const bool disableFullscreenUI{false};
|
||||
const std::string textBreakStrategy{};
|
||||
const SharedColor underlineColorAndroid{};
|
||||
const std::string inlineImageLeft{};
|
||||
const int inlineImagePadding{0};
|
||||
const std::string importantForAutofill{};
|
||||
const bool showSoftInputOnFocus{false};
|
||||
const std::string autoCapitalize{};
|
||||
const bool autoCorrect{false};
|
||||
const bool autoFocus{false};
|
||||
const bool allowFontScaling{false};
|
||||
const Float maxFontSizeMultiplier{0.0};
|
||||
const bool editable{false};
|
||||
const std::string keyboardType{};
|
||||
const std::string returnKeyType{};
|
||||
const int maxLength{0};
|
||||
const bool multiline{false};
|
||||
const std::string placeholder{};
|
||||
const SharedColor placeholderTextColor{};
|
||||
const bool secureTextEntry{false};
|
||||
const SharedColor selectionColor{};
|
||||
const AndroidTextInputSelectionStruct selection{};
|
||||
const std::string value{};
|
||||
const std::string defaultValue{};
|
||||
const bool selectTextOnFocus{false};
|
||||
const bool blurOnSubmit{false};
|
||||
const bool caretHidden{false};
|
||||
const bool contextMenuHidden{false};
|
||||
const SharedColor textShadowColor{};
|
||||
const Float textShadowRadius{0.0};
|
||||
const std::string textDecorationLine{};
|
||||
const std::string fontStyle{};
|
||||
const AndroidTextInputTextShadowOffsetStruct textShadowOffset{};
|
||||
const Float lineHeight{0.0};
|
||||
const std::string textTransform{};
|
||||
const int color{0};
|
||||
const Float letterSpacing{0.0};
|
||||
const Float fontSize{0.0};
|
||||
const std::string textAlign{};
|
||||
const bool includeFontPadding{false};
|
||||
const std::string fontWeight{};
|
||||
const std::string fontFamily{};
|
||||
const std::string textAlignVertical{};
|
||||
const SharedColor cursorColor{};
|
||||
const int mostRecentEventCount{0};
|
||||
const std::string text{};
|
||||
|
||||
/*
|
||||
* Contains all prop values that affect visual representation of the
|
||||
* paragraph.
|
||||
*/
|
||||
ParagraphAttributes const paragraphAttributes{};
|
||||
|
||||
/**
|
||||
* Auxiliary information to detect if these props are set or not.
|
||||
* See AndroidTextInputComponentDescriptor for usage.
|
||||
* TODO T63008435: can these, and this feature, be removed entirely?
|
||||
*/
|
||||
const bool hasPadding{};
|
||||
const bool hasPaddingHorizontal{};
|
||||
const bool hasPaddingVertical{};
|
||||
const bool hasPaddingLeft{};
|
||||
const bool hasPaddingTop{};
|
||||
const bool hasPaddingRight{};
|
||||
const bool hasPaddingBottom{};
|
||||
const bool hasPaddingStart{};
|
||||
const bool hasPaddingEnd{};
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
SharedDebugStringConvertibleList getDebugProps() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
197
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.cpp
generated
vendored
Normal file
197
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.cpp
generated
vendored
Normal file
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "AndroidTextInputShadowNode.h"
|
||||
|
||||
#include <fbjni/fbjni.h>
|
||||
#include <react/attributedstring/AttributedStringBox.h>
|
||||
#include <react/attributedstring/TextAttributes.h>
|
||||
#include <react/components/text/BaseTextShadowNode.h>
|
||||
#include <react/core/LayoutConstraints.h>
|
||||
#include <react/core/LayoutContext.h>
|
||||
#include <react/core/conversions.h>
|
||||
#include <react/jni/ReadableNativeMap.h>
|
||||
|
||||
using namespace facebook::jni;
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char AndroidTextInputComponentName[] = "AndroidTextInput";
|
||||
|
||||
void AndroidTextInputShadowNode::setContextContainer(
|
||||
ContextContainer *contextContainer) {
|
||||
ensureUnsealed();
|
||||
contextContainer_ = contextContainer;
|
||||
}
|
||||
|
||||
AttributedString AndroidTextInputShadowNode::getAttributedString() const {
|
||||
// Use BaseTextShadowNode to get attributed string from children
|
||||
auto childTextAttributes = TextAttributes::defaultTextAttributes();
|
||||
childTextAttributes.apply(getConcreteProps().textAttributes);
|
||||
|
||||
auto attributedString = AttributedString{};
|
||||
auto attachments = BaseTextShadowNode::Attachments{};
|
||||
BaseTextShadowNode::buildAttributedString(
|
||||
childTextAttributes, *this, attributedString, attachments);
|
||||
|
||||
// BaseTextShadowNode only gets children. We must detect and prepend text
|
||||
// value attributes manually.
|
||||
if (!getConcreteProps().text.empty()) {
|
||||
auto textAttributes = TextAttributes::defaultTextAttributes();
|
||||
textAttributes.apply(getConcreteProps().textAttributes);
|
||||
auto fragment = AttributedString::Fragment{};
|
||||
fragment.string = getConcreteProps().text;
|
||||
fragment.textAttributes = textAttributes;
|
||||
// If the TextInput opacity is 0 < n < 1, the opacity of the TextInput and
|
||||
// text value's background will stack. This is a hack/workaround to prevent
|
||||
// that effect.
|
||||
fragment.textAttributes.backgroundColor = clearColor();
|
||||
fragment.parentShadowView = ShadowView(*this);
|
||||
attributedString.prependFragment(fragment);
|
||||
}
|
||||
|
||||
return attributedString;
|
||||
}
|
||||
|
||||
// For measurement purposes, we want to make sure that there's at least a
|
||||
// single character in the string so that the measured height is greater
|
||||
// than zero. Otherwise, empty TextInputs with no placeholder don't
|
||||
// display at all.
|
||||
AttributedString AndroidTextInputShadowNode::getPlaceholderAttributedString()
|
||||
const {
|
||||
// Return placeholder text, since text and children are empty.
|
||||
auto textAttributedString = AttributedString{};
|
||||
auto fragment = AttributedString::Fragment{};
|
||||
fragment.string = getConcreteProps().placeholder;
|
||||
|
||||
if (fragment.string.empty()) {
|
||||
fragment.string = " ";
|
||||
}
|
||||
|
||||
auto textAttributes = TextAttributes::defaultTextAttributes();
|
||||
textAttributes.apply(getConcreteProps().textAttributes);
|
||||
|
||||
// If there's no text, it's possible that this Fragment isn't actually
|
||||
// appended to the AttributedString (see implementation of appendFragment)
|
||||
fragment.textAttributes = textAttributes;
|
||||
fragment.parentShadowView = ShadowView(*this);
|
||||
textAttributedString.appendFragment(fragment);
|
||||
|
||||
return textAttributedString;
|
||||
}
|
||||
|
||||
void AndroidTextInputShadowNode::setTextLayoutManager(
|
||||
SharedTextLayoutManager textLayoutManager) {
|
||||
ensureUnsealed();
|
||||
textLayoutManager_ = textLayoutManager;
|
||||
}
|
||||
|
||||
AttributedString AndroidTextInputShadowNode::getMostRecentAttributedString()
|
||||
const {
|
||||
auto const &state = getStateData();
|
||||
|
||||
auto reactTreeAttributedString = getAttributedString();
|
||||
|
||||
// Sometimes the treeAttributedString will only differ from the state
|
||||
// not by inherent properties (string or prop attributes), but by the frame of
|
||||
// the parent which has changed Thus, we can't directly compare the entire
|
||||
// AttributedString
|
||||
bool treeAttributedStringChanged =
|
||||
!state.reactTreeAttributedString.compareTextAttributesWithoutFrame(
|
||||
reactTreeAttributedString);
|
||||
|
||||
return (
|
||||
!treeAttributedStringChanged ? state.attributedString
|
||||
: reactTreeAttributedString);
|
||||
}
|
||||
|
||||
void AndroidTextInputShadowNode::updateStateIfNeeded() {
|
||||
ensureUnsealed();
|
||||
|
||||
auto reactTreeAttributedString = getAttributedString();
|
||||
auto const &state = getStateData();
|
||||
|
||||
assert(textLayoutManager_);
|
||||
assert(
|
||||
(!state.layoutManager || state.layoutManager == textLayoutManager_) &&
|
||||
"`StateData` refers to a different `TextLayoutManager`");
|
||||
|
||||
// Tree is often out of sync with the value of the TextInput.
|
||||
// This is by design - don't change the value of the TextInput in the State,
|
||||
// and therefore in Java, unless the tree itself changes.
|
||||
if (state.reactTreeAttributedString == reactTreeAttributedString &&
|
||||
state.layoutManager == textLayoutManager_) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Store default TextAttributes in state.
|
||||
// In the case where the TextInput is completely empty (no value, no
|
||||
// defaultValue, no placeholder, no children) there are therefore no fragments
|
||||
// in the AttributedString, and when State is updated, it needs some way to
|
||||
// reconstruct a Fragment with default TextAttributes.
|
||||
auto defaultTextAttributes = TextAttributes::defaultTextAttributes();
|
||||
defaultTextAttributes.apply(getConcreteProps().textAttributes);
|
||||
|
||||
auto newEventCount =
|
||||
(state.reactTreeAttributedString == reactTreeAttributedString
|
||||
? 0
|
||||
: getConcreteProps().mostRecentEventCount);
|
||||
auto newAttributedString = getMostRecentAttributedString();
|
||||
|
||||
// Even if we're here and updating state, it may be only to update the layout
|
||||
// manager If that is the case, make sure we don't update text: pass in the
|
||||
// current attributedString unchanged, and pass in zero for the "event count"
|
||||
// so no changes are applied There's no way to prevent a state update from
|
||||
// flowing to Java, so we just ensure it's a noop in those cases.
|
||||
setStateData(AndroidTextInputState{newEventCount,
|
||||
newAttributedString,
|
||||
reactTreeAttributedString,
|
||||
getConcreteProps().paragraphAttributes,
|
||||
defaultTextAttributes,
|
||||
ShadowView(*this),
|
||||
textLayoutManager_,
|
||||
state.defaultThemePaddingStart,
|
||||
state.defaultThemePaddingEnd,
|
||||
state.defaultThemePaddingTop,
|
||||
state.defaultThemePaddingBottom});
|
||||
}
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
Size AndroidTextInputShadowNode::measure(
|
||||
LayoutConstraints layoutConstraints) const {
|
||||
// Layout is called right after measure.
|
||||
// Measure is marked as `const`, and `layout` is not; so State can be updated
|
||||
// during layout, but not during `measure`. If State is out-of-date in layout,
|
||||
// it's too late: measure will have already operated on old State. Thus, we
|
||||
// use the same value here that we *will* use in layout to update the state.
|
||||
AttributedString attributedString = getMostRecentAttributedString();
|
||||
|
||||
if (attributedString.isEmpty()) {
|
||||
attributedString = getPlaceholderAttributedString();
|
||||
}
|
||||
|
||||
if (attributedString.isEmpty()) {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
return textLayoutManager_
|
||||
->measure(
|
||||
AttributedStringBox{attributedString},
|
||||
getConcreteProps().paragraphAttributes,
|
||||
layoutConstraints)
|
||||
.size;
|
||||
}
|
||||
|
||||
void AndroidTextInputShadowNode::layout(LayoutContext layoutContext) {
|
||||
updateStateIfNeeded();
|
||||
ConcreteViewShadowNode::layout(layoutContext);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
79
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h
generated
vendored
Normal file
79
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputShadowNode.h
generated
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AndroidTextInputEventEmitter.h"
|
||||
#include "AndroidTextInputProps.h"
|
||||
#include "AndroidTextInputState.h"
|
||||
|
||||
#include <react/components/view/ConcreteViewShadowNode.h>
|
||||
#include <react/utils/ContextContainer.h>
|
||||
|
||||
#include <react/attributedstring/AttributedString.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
extern const char AndroidTextInputComponentName[];
|
||||
|
||||
/*
|
||||
* `ShadowNode` for <AndroidTextInput> component.
|
||||
*/
|
||||
class AndroidTextInputShadowNode : public ConcreteViewShadowNode<
|
||||
AndroidTextInputComponentName,
|
||||
AndroidTextInputProps,
|
||||
AndroidTextInputEventEmitter,
|
||||
AndroidTextInputState> {
|
||||
public:
|
||||
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
||||
|
||||
void setContextContainer(ContextContainer *contextContainer);
|
||||
|
||||
/*
|
||||
* Returns a `AttributedString` which represents text content of the node.
|
||||
*/
|
||||
AttributedString getAttributedString() const;
|
||||
AttributedString getPlaceholderAttributedString() const;
|
||||
|
||||
/*
|
||||
* Associates a shared TextLayoutManager with the node.
|
||||
* `ParagraphShadowNode` uses the manager to measure text content
|
||||
* and construct `ParagraphState` objects.
|
||||
*/
|
||||
void setTextLayoutManager(SharedTextLayoutManager textLayoutManager);
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
Size measure(LayoutConstraints layoutConstraints) const override;
|
||||
void layout(LayoutContext layoutContext) override;
|
||||
|
||||
private:
|
||||
ContextContainer *contextContainer_{};
|
||||
|
||||
/**
|
||||
* Get the most up-to-date attributed string for measurement and State.
|
||||
*/
|
||||
AttributedString getMostRecentAttributedString() const;
|
||||
|
||||
/*
|
||||
* Creates a `State` object (with `AttributedText` and
|
||||
* `TextLayoutManager`) if needed.
|
||||
*/
|
||||
void updateStateIfNeeded();
|
||||
|
||||
SharedTextLayoutManager textLayoutManager_;
|
||||
|
||||
/*
|
||||
* Cached attributed string that represents the content of the subtree started
|
||||
* from the node.
|
||||
*/
|
||||
mutable folly::Optional<AttributedString> cachedAttributedString_{};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
30
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputState.cpp
generated
vendored
Normal file
30
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputState.cpp
generated
vendored
Normal file
@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#include "AndroidTextInputState.h"
|
||||
|
||||
#include <react/components/text/conversions.h>
|
||||
#include <react/debug/debugStringConvertibleUtils.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
#ifdef ANDROID
|
||||
folly::dynamic AndroidTextInputState::getDynamic() const {
|
||||
// Java doesn't need all fields, so we don't pass them along.
|
||||
folly::dynamic newState = folly::dynamic::object();
|
||||
newState["mostRecentEventCount"] = mostRecentEventCount;
|
||||
newState["attributedString"] = toDynamic(attributedString);
|
||||
newState["paragraphAttributes"] = toDynamic(paragraphAttributes);
|
||||
newState["hash"] = newState["attributedString"]["hash"];
|
||||
newState["hasThemeData"] = !isnan(defaultThemePaddingStart);
|
||||
return newState;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
185
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputState.h
generated
vendored
Normal file
185
node_modules/react-native/ReactCommon/fabric/components/textinput/androidtextinput/AndroidTextInputState.h
generated
vendored
Normal file
@ -0,0 +1,185 @@
|
||||
/*
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <react/attributedstring/AttributedString.h>
|
||||
#include <react/attributedstring/ParagraphAttributes.h>
|
||||
#include <react/textlayoutmanager/TextLayoutManager.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <folly/dynamic.h>
|
||||
#endif
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* State for <Paragraph> component.
|
||||
* Represents what to render and how to render.
|
||||
*/
|
||||
class AndroidTextInputState final {
|
||||
public:
|
||||
int64_t mostRecentEventCount{0};
|
||||
|
||||
/*
|
||||
* All content of <TextInput> component represented as an `AttributedString`.
|
||||
*/
|
||||
AttributedString attributedString{};
|
||||
|
||||
/*
|
||||
* All content of <TextInput> component represented as an `AttributedString`.
|
||||
* This stores the previous computed *from the React tree*. This usually
|
||||
* doesn't change as the TextInput contents are being updated. If it does
|
||||
* change, we need to wipe out current contents of the TextInput and replace
|
||||
* with the new value from the tree.
|
||||
*/
|
||||
AttributedString reactTreeAttributedString{};
|
||||
|
||||
/*
|
||||
* Represents all visual attributes of a paragraph of text represented as
|
||||
* a ParagraphAttributes.
|
||||
*/
|
||||
ParagraphAttributes paragraphAttributes{};
|
||||
|
||||
/**
|
||||
* Default TextAttributes used if we need to construct a new Fragment.
|
||||
* Only used if text is inserted into an AttributedString with no existing
|
||||
* Fragments.
|
||||
*/
|
||||
TextAttributes defaultTextAttributes;
|
||||
|
||||
/**
|
||||
* Default parent ShadowView used if we need to construct a new Fragment.
|
||||
* Only used if text is inserted into an AttributedString with no existing
|
||||
* Fragments.
|
||||
*/
|
||||
ShadowView defaultParentShadowView;
|
||||
|
||||
/*
|
||||
* `TextLayoutManager` provides a connection to platform-specific
|
||||
* text rendering infrastructure which is capable to render the
|
||||
* `AttributedString`.
|
||||
*/
|
||||
SharedTextLayoutManager layoutManager{};
|
||||
|
||||
/**
|
||||
* Communicates Android theme padding back to the ShadowNode / Component
|
||||
* Descriptor for layout.
|
||||
*/
|
||||
float defaultThemePaddingStart{NAN};
|
||||
float defaultThemePaddingEnd{NAN};
|
||||
float defaultThemePaddingTop{NAN};
|
||||
float defaultThemePaddingBottom{NAN};
|
||||
|
||||
#ifdef ANDROID
|
||||
AttributedString updateAttributedString(
|
||||
TextAttributes const &defaultTextAttributes,
|
||||
ShadowView const &defaultParentShadowView,
|
||||
AttributedString const &original,
|
||||
folly::dynamic const &data) {
|
||||
if (data["textChanged"].empty()) {
|
||||
return original;
|
||||
}
|
||||
|
||||
// TODO: parse other attributes besides just string?
|
||||
// on the other hand, not much should be driven from Java
|
||||
// TODO: it'd be really nice to treat these as operational transforms
|
||||
// instead of having to pass the whole string across.
|
||||
// Unfortunately we don't have a good way of communicating from Java to C++
|
||||
// *which* version of the State changes should be applied to; and if there's
|
||||
// a conflict, we don't have any recourse of any way to bail out of a
|
||||
// commit.
|
||||
|
||||
auto str = AttributedString{};
|
||||
|
||||
int i = 0;
|
||||
folly::dynamic fragments = data["textChanged"]["fragments"];
|
||||
for (auto const &fragment : original.getFragments()) {
|
||||
str.appendFragment(AttributedString::Fragment{
|
||||
fragments.size() > i ? fragments[i]["string"].getString() : "",
|
||||
fragment.textAttributes,
|
||||
fragment.parentShadowView});
|
||||
i++;
|
||||
}
|
||||
|
||||
if (fragments.size() > original.getFragments().size()) {
|
||||
for (; i < fragments.size(); i++) {
|
||||
str.appendFragment(
|
||||
AttributedString::Fragment{fragments[i]["string"].getString(),
|
||||
defaultTextAttributes,
|
||||
defaultParentShadowView});
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
AndroidTextInputState(
|
||||
int64_t mostRecentEventCount,
|
||||
AttributedString const &attributedString,
|
||||
AttributedString const &reactTreeAttributedString,
|
||||
ParagraphAttributes const ¶graphAttributes,
|
||||
TextAttributes const &defaultTextAttributes,
|
||||
ShadowView const &defaultParentShadowView,
|
||||
SharedTextLayoutManager const &layoutManager,
|
||||
float defaultThemePaddingStart,
|
||||
float defaultThemePaddingEnd,
|
||||
float defaultThemePaddingTop,
|
||||
float defaultThemePaddingBottom)
|
||||
: mostRecentEventCount(mostRecentEventCount),
|
||||
attributedString(attributedString),
|
||||
reactTreeAttributedString(reactTreeAttributedString),
|
||||
paragraphAttributes(paragraphAttributes),
|
||||
defaultTextAttributes(defaultTextAttributes),
|
||||
defaultParentShadowView(defaultParentShadowView),
|
||||
layoutManager(layoutManager),
|
||||
defaultThemePaddingStart(defaultThemePaddingStart),
|
||||
defaultThemePaddingEnd(defaultThemePaddingEnd),
|
||||
defaultThemePaddingTop(defaultThemePaddingTop),
|
||||
defaultThemePaddingBottom(defaultThemePaddingBottom) {}
|
||||
AndroidTextInputState() = default;
|
||||
AndroidTextInputState(
|
||||
AndroidTextInputState const &previousState,
|
||||
folly::dynamic const &data)
|
||||
: mostRecentEventCount(data.getDefault(
|
||||
"mostRecentEventCount",
|
||||
previousState.mostRecentEventCount)
|
||||
.getInt()),
|
||||
attributedString(updateAttributedString(
|
||||
previousState.defaultTextAttributes,
|
||||
previousState.defaultParentShadowView,
|
||||
previousState.attributedString,
|
||||
data)),
|
||||
reactTreeAttributedString(previousState.reactTreeAttributedString),
|
||||
paragraphAttributes(previousState.paragraphAttributes),
|
||||
defaultTextAttributes(previousState.defaultTextAttributes),
|
||||
defaultParentShadowView(previousState.defaultParentShadowView),
|
||||
layoutManager(previousState.layoutManager),
|
||||
defaultThemePaddingStart(data.getDefault(
|
||||
"themePaddingStart",
|
||||
previousState.defaultThemePaddingStart)
|
||||
.getDouble()),
|
||||
defaultThemePaddingEnd(data.getDefault(
|
||||
"themePaddingEnd",
|
||||
previousState.defaultThemePaddingEnd)
|
||||
.getDouble()),
|
||||
defaultThemePaddingTop(data.getDefault(
|
||||
"themePaddingTop",
|
||||
previousState.defaultThemePaddingTop)
|
||||
.getDouble()),
|
||||
defaultThemePaddingBottom(
|
||||
data.getDefault(
|
||||
"themePaddingBottom",
|
||||
previousState.defaultThemePaddingBottom)
|
||||
.getDouble()){};
|
||||
folly::dynamic getDynamic() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
Reference in New Issue
Block a user