mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Add C++ AndroidTextInput component for backwards-compatible Fabric support of TextInput on Android
Summary: Support existing, backwards-compatible AndroidTextInput component for minimal support of TextInput on Android. Reviewed By: shergin, mdvacca Differential Revision: D17086758 fbshipit-source-id: 25726f22229e0d5dfe96eb36b386a5317601283d
This commit is contained in:
committed by
Facebook Github Bot
parent
898124541c
commit
5abe5843e2
+21
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
package com.facebook.react.views.textinput;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.Typeface;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -20,6 +21,7 @@ import android.view.Gravity;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
@@ -29,6 +31,7 @@ import com.facebook.react.bridge.Dynamic;
|
||||
import com.facebook.react.bridge.JSApplicationIllegalArgumentException;
|
||||
import com.facebook.react.bridge.ReactContext;
|
||||
import com.facebook.react.bridge.ReadableArray;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.ReadableType;
|
||||
import com.facebook.react.common.MapBuilder;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
@@ -50,7 +53,9 @@ import com.facebook.react.views.text.DefaultStyleValuesUtil;
|
||||
import com.facebook.react.views.text.ReactFontManager;
|
||||
import com.facebook.react.views.text.ReactTextUpdate;
|
||||
import com.facebook.react.views.text.TextInlineImageSpan;
|
||||
import com.facebook.react.views.text.TextLayoutManager;
|
||||
import com.facebook.yoga.YogaConstants;
|
||||
import com.facebook.yoga.YogaMeasureMode;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Map;
|
||||
@@ -91,6 +96,8 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
private static final InputFilter[] EMPTY_FILTERS = new InputFilter[0];
|
||||
private static final int UNSET = -1;
|
||||
|
||||
@Nullable private static EditText mDummyEditText = null;
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return REACT_CLASS;
|
||||
@@ -1075,4 +1082,18 @@ public class ReactTextInputManager extends BaseViewManager<ReactEditText, Layout
|
||||
"sentences",
|
||||
InputType.TYPE_TEXT_FLAG_CAP_SENTENCES));
|
||||
}
|
||||
/** Measure function for Fabric. */
|
||||
@Override
|
||||
public long measure(
|
||||
Context context,
|
||||
ReadableMap localData,
|
||||
ReadableMap props,
|
||||
ReadableMap state,
|
||||
float width,
|
||||
YogaMeasureMode widthMode,
|
||||
float height,
|
||||
YogaMeasureMode heightMode) {
|
||||
return TextLayoutManager.measureText(
|
||||
context, localData, props, width, widthMode, height, heightMode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,8 @@
|
||||
*/
|
||||
|
||||
#include "SliderShadowNode.h"
|
||||
#include "SliderLocalData.h"
|
||||
|
||||
#include <react/components/slider/SliderLocalData.h>
|
||||
#include <react/components/slider/SliderShadowNode.h>
|
||||
#include <react/core/LayoutContext.h>
|
||||
|
||||
namespace facebook {
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace react {
|
||||
|
||||
AttributedString BaseTextShadowNode::getAttributedString(
|
||||
const TextAttributes &textAttributes,
|
||||
const SharedShadowNode &parentNode) const {
|
||||
const SharedShadowNode &parentNode) {
|
||||
auto attributedString = AttributedString{};
|
||||
|
||||
for (const auto &childNode : parentNode->getChildren()) {
|
||||
|
||||
@@ -21,10 +21,14 @@ class BaseTextShadowNode {
|
||||
public:
|
||||
/*
|
||||
* Returns a `AttributedString` which represents text content of the node.
|
||||
* This is static so that both Paragraph (which subclasses BaseText) and
|
||||
* TextInput (which does not) can use this.
|
||||
* TODO T53299884: decide if this should be moved out and made a static
|
||||
* function, or if TextInput should inherit from BaseTextShadowNode.
|
||||
*/
|
||||
AttributedString getAttributedString(
|
||||
static AttributedString getAttributedString(
|
||||
const TextAttributes &baseTextAttributes,
|
||||
const SharedShadowNode &parentNode) const;
|
||||
const SharedShadowNode &parentNode);
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
load("@fbsource//tools/build_defs/apple:flag_defs.bzl", "get_debug_preprocessor_flags")
|
||||
load(
|
||||
"//tools/build_defs/oss:rn_defs.bzl",
|
||||
"ANDROID",
|
||||
"APPLE",
|
||||
"CXX",
|
||||
"YOGA_CXX_TARGET",
|
||||
"fb_xplat_cxx_test",
|
||||
"get_apple_compiler_flags",
|
||||
"get_apple_inspector_flags",
|
||||
"react_native_xplat_target",
|
||||
"rn_xplat_cxx_library",
|
||||
"subdir_glob",
|
||||
)
|
||||
|
||||
APPLE_COMPILER_FLAGS = get_apple_compiler_flags()
|
||||
|
||||
rn_xplat_cxx_library(
|
||||
name = "androidtextinput",
|
||||
srcs = glob(
|
||||
["**/*.cpp"],
|
||||
exclude = glob(["tests/**/*.cpp"]),
|
||||
),
|
||||
headers = glob(
|
||||
["**/*.h"],
|
||||
exclude = glob(["tests/**/*.h"]),
|
||||
),
|
||||
header_namespace = "",
|
||||
exported_headers = subdir_glob(
|
||||
[
|
||||
("", "*.h"),
|
||||
("androidtextinput", "*.h"),
|
||||
],
|
||||
prefix = "react/components/androidtextinput",
|
||||
),
|
||||
compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
"-std=c++14",
|
||||
"-Wall",
|
||||
],
|
||||
cxx_tests = [":tests"],
|
||||
fbobjc_compiler_flags = APPLE_COMPILER_FLAGS,
|
||||
fbobjc_preprocessor_flags = get_debug_preprocessor_flags() + get_apple_inspector_flags(),
|
||||
force_static = True,
|
||||
platforms = (ANDROID, APPLE, CXX),
|
||||
preprocessor_flags = [
|
||||
"-DLOG_TAG=\"ReactNative\"",
|
||||
"-DWITH_FBSYSTRACE=1",
|
||||
],
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
"fbsource//xplat/fbsystrace:fbsystrace",
|
||||
"fbsource//xplat/folly:evicting_cache_map",
|
||||
"fbsource//xplat/folly:headers_only",
|
||||
"fbsource//xplat/folly:memory",
|
||||
"fbsource//xplat/folly:molly",
|
||||
"fbsource//xplat/third-party/glog:glog",
|
||||
YOGA_CXX_TARGET,
|
||||
react_native_xplat_target("utils:utils"),
|
||||
react_native_xplat_target("fabric/attributedstring:attributedstring"),
|
||||
react_native_xplat_target("fabric/core:core"),
|
||||
react_native_xplat_target("fabric/debug:debug"),
|
||||
react_native_xplat_target("fabric/graphics:graphics"),
|
||||
react_native_xplat_target("fabric/textlayoutmanager:textlayoutmanager"),
|
||||
react_native_xplat_target("fabric/components/text:text"),
|
||||
react_native_xplat_target("fabric/components/view:view"),
|
||||
react_native_xplat_target("fabric/components/image:image"),
|
||||
react_native_xplat_target("fabric/uimanager:uimanager"),
|
||||
react_native_xplat_target("fabric/imagemanager:imagemanager"),
|
||||
],
|
||||
)
|
||||
|
||||
fb_xplat_cxx_test(
|
||||
name = "tests",
|
||||
srcs = glob(["tests/**/*.cpp"]),
|
||||
headers = glob(["tests/**/*.h"]),
|
||||
compiler_flags = [
|
||||
"-fexceptions",
|
||||
"-frtti",
|
||||
"-std=c++14",
|
||||
"-Wall",
|
||||
],
|
||||
contacts = ["oncall+react_native@xmail.facebook.com"],
|
||||
platforms = (
|
||||
# `Apple` and `Android` flavors are disabled because the module depends on `textlayoutmanager` which requires real an Emulator/Simulator to run.
|
||||
# At the same time, the code of tests does not rely on the simulator capabilities and it would be wasteful to add `fbandroid_use_instrumentation_test = True`.
|
||||
# (Beware of this option though.)
|
||||
# ANDROID,
|
||||
# APPLE,
|
||||
CXX
|
||||
),
|
||||
deps = [
|
||||
"fbsource//xplat/folly:molly",
|
||||
"fbsource//xplat/third-party/gmock:gtest",
|
||||
":androidtextinput",
|
||||
],
|
||||
)
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
* 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"
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
/*
|
||||
* Descriptor for <AndroidTextInput> component.
|
||||
*/
|
||||
class AndroidTextInputComponentDescriptor final
|
||||
: public ConcreteComponentDescriptor<AndroidTextInputShadowNode> {
|
||||
public:
|
||||
AndroidTextInputComponentDescriptor(
|
||||
EventDispatcher::Shared eventDispatcher,
|
||||
const ContextContainer::Shared &contextContainer)
|
||||
: ConcreteComponentDescriptor<AndroidTextInputShadowNode>(
|
||||
eventDispatcher,
|
||||
contextContainer) {}
|
||||
|
||||
protected:
|
||||
void adopt(UnsharedShadowNode shadowNode) const override {
|
||||
assert(std::dynamic_pointer_cast<AndroidTextInputShadowNode>(shadowNode));
|
||||
auto concreteShadowNode =
|
||||
std::static_pointer_cast<AndroidTextInputShadowNode>(shadowNode);
|
||||
|
||||
concreteShadowNode->setContextContainer(
|
||||
const_cast<ContextContainer *>(getContextContainer().get()));
|
||||
|
||||
concreteShadowNode->dirtyLayout();
|
||||
concreteShadowNode->enableMeasurement();
|
||||
|
||||
ConcreteComponentDescriptor::adopt(shadowNode);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
+179
@@ -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
@@ -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
|
||||
@@ -0,0 +1,383 @@
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
/**
|
||||
* This was cribbed from BaseTextProps. Maybe we can unify someday.
|
||||
* TODO: we should probably just move this to BaseTextProps / subclass it
|
||||
*
|
||||
* @param rawProps
|
||||
* @param defaultTextAttributes
|
||||
* @return
|
||||
*/
|
||||
static TextAttributes convertRawProp(
|
||||
const RawProps &rawProps,
|
||||
const TextAttributes defaultTextAttributes) {
|
||||
auto textAttributes = TextAttributes{};
|
||||
|
||||
// Color
|
||||
textAttributes.foregroundColor =
|
||||
convertRawProp(rawProps, "color", defaultTextAttributes.foregroundColor);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.backgroundColor = convertRawProp(
|
||||
rawProps, "backgroundColor", defaultTextAttributes.backgroundColor);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.opacity =
|
||||
convertRawProp(rawProps, "opacity", defaultTextAttributes.opacity);
|
||||
|
||||
// Font
|
||||
textAttributes.fontFamily =
|
||||
convertRawProp(rawProps, "fontFamily", defaultTextAttributes.fontFamily);
|
||||
textAttributes.fontSize =
|
||||
convertRawProp(rawProps, "fontSize", defaultTextAttributes.fontSize);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
// is this maxFontSizeMultiplier?
|
||||
textAttributes.fontSizeMultiplier = convertRawProp(
|
||||
rawProps, "fontSizeMultiplier", defaultTextAttributes.fontSizeMultiplier);
|
||||
textAttributes.fontWeight =
|
||||
convertRawProp(rawProps, "fontWeight", defaultTextAttributes.fontWeight);
|
||||
textAttributes.fontStyle =
|
||||
convertRawProp(rawProps, "fontStyle", defaultTextAttributes.fontStyle);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.fontVariant = convertRawProp(
|
||||
rawProps, "fontVariant", defaultTextAttributes.fontVariant);
|
||||
textAttributes.allowFontScaling = convertRawProp(
|
||||
rawProps, "allowFontScaling", defaultTextAttributes.allowFontScaling);
|
||||
textAttributes.letterSpacing = convertRawProp(
|
||||
rawProps, "letterSpacing", defaultTextAttributes.letterSpacing);
|
||||
|
||||
// Paragraph
|
||||
textAttributes.lineHeight =
|
||||
convertRawProp(rawProps, "lineHeight", defaultTextAttributes.lineHeight);
|
||||
textAttributes.alignment =
|
||||
convertRawProp(rawProps, "textAlign", defaultTextAttributes.alignment);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.baseWritingDirection = convertRawProp(
|
||||
rawProps,
|
||||
"baseWritingDirection",
|
||||
defaultTextAttributes.baseWritingDirection);
|
||||
|
||||
// Decoration
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.textDecorationColor = convertRawProp(
|
||||
rawProps,
|
||||
"textDecorationColor",
|
||||
defaultTextAttributes.textDecorationColor);
|
||||
textAttributes.textDecorationLineType = convertRawProp(
|
||||
rawProps,
|
||||
"textDecorationLine",
|
||||
defaultTextAttributes.textDecorationLineType);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.textDecorationLineStyle = convertRawProp(
|
||||
rawProps,
|
||||
"textDecorationLineStyle",
|
||||
defaultTextAttributes.textDecorationLineStyle);
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.textDecorationLinePattern = convertRawProp(
|
||||
rawProps,
|
||||
"textDecorationLinePattern",
|
||||
defaultTextAttributes.textDecorationLinePattern);
|
||||
|
||||
// Shadow
|
||||
textAttributes.textShadowOffset = convertRawProp(
|
||||
rawProps, "textShadowOffset", defaultTextAttributes.textShadowOffset);
|
||||
textAttributes.textShadowRadius = convertRawProp(
|
||||
rawProps, "textShadowRadius", defaultTextAttributes.textShadowRadius);
|
||||
textAttributes.textShadowColor = convertRawProp(
|
||||
rawProps, "textShadowColor", defaultTextAttributes.textShadowColor);
|
||||
|
||||
// Special
|
||||
// Todo T53300333: not found in AndroidTextInput (java) and/or TextInput
|
||||
textAttributes.isHighlighted = convertRawProp(
|
||||
rawProps, "isHighlighted", defaultTextAttributes.isHighlighted);
|
||||
|
||||
return textAttributes;
|
||||
}
|
||||
|
||||
AndroidTextInputProps::AndroidTextInputProps(
|
||||
const AndroidTextInputProps &sourceProps,
|
||||
const RawProps &rawProps)
|
||||
: ViewProps(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, {})),
|
||||
textAttributes(convertRawProp(rawProps, sourceProps.textAttributes)) {}
|
||||
|
||||
// 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;
|
||||
return props;
|
||||
}
|
||||
|
||||
#pragma mark - DebugStringConvertible
|
||||
|
||||
#if RN_DEBUG_STRING_CONVERTIBLE
|
||||
// TODO: codegen these
|
||||
SharedDebugStringConvertibleList TextProps::getDebugProps() const {
|
||||
return {};
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* 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/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:
|
||||
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{};
|
||||
|
||||
/**
|
||||
* TextAttributes: see all BaseText. These attributes are not set
|
||||
* directly; see convertRawProps.
|
||||
*/
|
||||
const TextAttributes textAttributes{};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/**
|
||||
* 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 <fb/fbjni.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>
|
||||
|
||||
#include <Glog/logging.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 {
|
||||
auto textAttributes = TextAttributes::defaultTextAttributes();
|
||||
textAttributes.apply(getProps()->textAttributes);
|
||||
|
||||
// Use BaseTextShadowNode to get attributed string from children
|
||||
return BaseTextShadowNode::getAttributedString(
|
||||
textAttributes, shared_from_this());
|
||||
}
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
Size AndroidTextInputShadowNode::measure(
|
||||
LayoutConstraints layoutConstraints) const {
|
||||
AttributedString attributedString = getAttributedString();
|
||||
|
||||
if (attributedString.isEmpty()) {
|
||||
return {0, 0};
|
||||
}
|
||||
|
||||
const jni::global_ref<jobject> &fabricUIManager =
|
||||
contextContainer_->at<jni::global_ref<jobject>>("FabricUIManager");
|
||||
|
||||
static auto measure =
|
||||
jni::findClassStatic("com/facebook/react/fabric/FabricUIManager")
|
||||
->getMethod<jlong(
|
||||
jstring,
|
||||
ReadableMap::javaobject,
|
||||
ReadableMap::javaobject,
|
||||
ReadableMap::javaobject,
|
||||
jfloat,
|
||||
jfloat,
|
||||
jfloat,
|
||||
jfloat)>("measure");
|
||||
|
||||
auto minimumSize = layoutConstraints.minimumSize;
|
||||
auto maximumSize = layoutConstraints.maximumSize;
|
||||
|
||||
local_ref<JString> componentName =
|
||||
make_jstring(AndroidTextInputComponentName);
|
||||
|
||||
local_ref<ReadableNativeMap::javaobject> attributedStringRNM =
|
||||
ReadableNativeMap::newObjectCxxArgs(toDynamic(attributedString));
|
||||
local_ref<ReadableMap::javaobject> attributedStringRM = make_local(
|
||||
reinterpret_cast<ReadableMap::javaobject>(attributedStringRNM.get()));
|
||||
|
||||
local_ref<ReadableNativeMap::javaobject> nativeLocalProps = make_local(
|
||||
ReadableNativeMap::createWithContents(getProps()->getDynamic()));
|
||||
local_ref<ReadableMap::javaobject> props = make_local(
|
||||
reinterpret_cast<ReadableMap::javaobject>(nativeLocalProps.get()));
|
||||
|
||||
// For AndroidTextInput purposes:
|
||||
// localData == textAttributes
|
||||
return yogaMeassureToSize(measure(
|
||||
fabricUIManager,
|
||||
componentName.get(),
|
||||
attributedStringRM.get(),
|
||||
props.get(),
|
||||
nullptr,
|
||||
minimumSize.width,
|
||||
maximumSize.width,
|
||||
minimumSize.height,
|
||||
maximumSize.height));
|
||||
}
|
||||
|
||||
void AndroidTextInputShadowNode::layout(LayoutContext layoutContext) {
|
||||
ConcreteViewShadowNode::layout(layoutContext);
|
||||
}
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "AndroidTextInputEventEmitter.h"
|
||||
#include "AndroidTextInputProps.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> {
|
||||
public:
|
||||
using ConcreteViewShadowNode::ConcreteViewShadowNode;
|
||||
|
||||
void setContextContainer(ContextContainer *contextContainer);
|
||||
|
||||
/*
|
||||
* Returns a `AttributedString` which represents text content of the node.
|
||||
*/
|
||||
AttributedString getAttributedString() const;
|
||||
|
||||
#pragma mark - LayoutableShadowNode
|
||||
|
||||
Size measure(LayoutConstraints layoutConstraints) const override;
|
||||
void layout(LayoutContext layoutContext) override;
|
||||
|
||||
private:
|
||||
ContextContainer *contextContainer_{};
|
||||
};
|
||||
|
||||
} // namespace react
|
||||
} // namespace facebook
|
||||
@@ -18,6 +18,8 @@
|
||||
#include <react/debug/SystraceSection.h>
|
||||
#include <yoga/Yoga.h>
|
||||
|
||||
#include <Glog/logging.h>
|
||||
|
||||
namespace facebook {
|
||||
namespace react {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user