/* * 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 #include #include #include #include #include #include #include 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 { auto const &attributedString = BaseTextShadowNode::getAttributedString(textAttributes, *this); if (!attributedString.isEmpty()) { return std::move(attributedString); } } // Return placeholder text instead, if text was empty. auto placeholderAttributedString = AttributedString{}; auto fragment = AttributedString::Fragment{}; fragment.string = getProps()->placeholder; // 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. if (fragment.string == "") { fragment.string = " "; } fragment.textAttributes = textAttributes; fragment.parentShadowView = ShadowView(*this); placeholderAttributedString.appendFragment(fragment); return placeholderAttributedString; } #pragma mark - LayoutableShadowNode Size AndroidTextInputShadowNode::measure( LayoutConstraints layoutConstraints) const { AttributedString attributedString = getAttributedString(); if (attributedString.isEmpty()) { return {0, 0}; } const jni::global_ref &fabricUIManager = contextContainer_->at>("FabricUIManager"); static auto measure = jni::findClassStatic("com/facebook/react/fabric/FabricUIManager") ->getMethod("measure"); auto minimumSize = layoutConstraints.minimumSize; auto maximumSize = layoutConstraints.maximumSize; local_ref componentName = make_jstring(AndroidTextInputComponentName); local_ref attributedStringRNM = ReadableNativeMap::newObjectCxxArgs(toDynamic(attributedString)); local_ref attributedStringRM = make_local( reinterpret_cast(attributedStringRNM.get())); local_ref nativeLocalProps = make_local( ReadableNativeMap::createWithContents(getProps()->getDynamic())); local_ref props = make_local( reinterpret_cast(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