mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
3093010ea5
Summary: This diff moves fabric C++ code from ReactCommon/fabric to ReactCommon/react/renderer As part of this diff I also refactored components, codegen and callsites on CatalystApp, FB4A and venice Script: P137350694 changelog: [internal] internal refactor Reviewed By: fkgozali Differential Revision: D22852139 fbshipit-source-id: f85310ba858b6afd81abfd9cbe6d70b28eca7415
124 lines
4.1 KiB
C++
124 lines
4.1 KiB
C++
/*
|
|
* 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 "TextInputShadowNode.h"
|
|
|
|
#include <react/renderer/attributedstring/AttributedStringBox.h>
|
|
#include <react/renderer/attributedstring/TextAttributes.h>
|
|
#include <react/renderer/core/LayoutConstraints.h>
|
|
#include <react/renderer/core/LayoutContext.h>
|
|
#include <react/renderer/core/conversions.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
extern char const TextInputComponentName[] = "TextInput";
|
|
|
|
AttributedStringBox TextInputShadowNode::attributedStringBoxToMeasure(
|
|
LayoutContext const &layoutContext) const {
|
|
bool hasMeaningfulState =
|
|
getState() && getState()->getRevision() != State::initialRevisionValue;
|
|
|
|
if (hasMeaningfulState) {
|
|
auto attributedStringBox = getStateData().attributedStringBox;
|
|
if (attributedStringBox.getMode() ==
|
|
AttributedStringBox::Mode::OpaquePointer ||
|
|
!attributedStringBox.getValue().isEmpty()) {
|
|
return getStateData().attributedStringBox;
|
|
}
|
|
}
|
|
|
|
auto attributedString = hasMeaningfulState
|
|
? AttributedString{}
|
|
: getAttributedString(layoutContext);
|
|
|
|
if (attributedString.isEmpty()) {
|
|
auto placeholder = getConcreteProps().placeholder;
|
|
// Note: `zero-width space` is insufficient in some cases (e.g. when we need
|
|
// to measure the "hight" of the font).
|
|
// TODO T67606511: We will redefine the measurement of empty strings as part
|
|
// of T67606511
|
|
auto string = !placeholder.empty()
|
|
? placeholder
|
|
: BaseTextShadowNode::getEmptyPlaceholder();
|
|
auto textAttributes = getConcreteProps().getEffectiveTextAttributes(
|
|
layoutContext.fontSizeMultiplier);
|
|
attributedString.appendFragment({string, textAttributes, {}});
|
|
}
|
|
|
|
return AttributedStringBox{attributedString};
|
|
}
|
|
|
|
AttributedString TextInputShadowNode::getAttributedString(
|
|
LayoutContext const &layoutContext) const {
|
|
auto textAttributes = getConcreteProps().getEffectiveTextAttributes(
|
|
layoutContext.fontSizeMultiplier);
|
|
auto attributedString = AttributedString{};
|
|
|
|
attributedString.appendFragment(
|
|
AttributedString::Fragment{getConcreteProps().text, textAttributes});
|
|
|
|
auto attachments = Attachments{};
|
|
BaseTextShadowNode::buildAttributedString(
|
|
textAttributes, *this, attributedString, attachments);
|
|
|
|
return attributedString;
|
|
}
|
|
|
|
void TextInputShadowNode::setTextLayoutManager(
|
|
TextLayoutManager::Shared const &textLayoutManager) {
|
|
ensureUnsealed();
|
|
textLayoutManager_ = textLayoutManager;
|
|
}
|
|
|
|
void TextInputShadowNode::updateStateIfNeeded(
|
|
LayoutContext const &layoutContext) {
|
|
ensureUnsealed();
|
|
|
|
auto reactTreeAttributedString = getAttributedString(layoutContext);
|
|
auto const &state = getStateData();
|
|
|
|
assert(textLayoutManager_);
|
|
assert(
|
|
(!state.layoutManager || state.layoutManager == textLayoutManager_) &&
|
|
"`StateData` refers to a different `TextLayoutManager`");
|
|
|
|
if (state.reactTreeAttributedString == reactTreeAttributedString &&
|
|
state.layoutManager == textLayoutManager_) {
|
|
return;
|
|
}
|
|
|
|
auto newState = TextInputState{};
|
|
newState.attributedStringBox = AttributedStringBox{reactTreeAttributedString};
|
|
newState.paragraphAttributes = getConcreteProps().paragraphAttributes;
|
|
newState.reactTreeAttributedString = reactTreeAttributedString;
|
|
newState.layoutManager = textLayoutManager_;
|
|
newState.mostRecentEventCount = getConcreteProps().mostRecentEventCount;
|
|
setStateData(std::move(newState));
|
|
}
|
|
|
|
#pragma mark - LayoutableShadowNode
|
|
|
|
Size TextInputShadowNode::measureContent(
|
|
LayoutContext const &layoutContext,
|
|
LayoutConstraints const &layoutConstraints) const {
|
|
return textLayoutManager_
|
|
->measure(
|
|
attributedStringBoxToMeasure(layoutContext),
|
|
getConcreteProps().getEffectiveParagraphAttributes(),
|
|
layoutConstraints)
|
|
.size;
|
|
}
|
|
|
|
void TextInputShadowNode::layout(LayoutContext layoutContext) {
|
|
updateStateIfNeeded(layoutContext);
|
|
ConcreteViewShadowNode::layout(layoutContext);
|
|
}
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|