mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
c18cc76e58
Summary: Instead of comparing the entire AttributedString, compare just the strings and the TextAttributes of Fragments. Concretely what I'm seeing is that the Frame of the associated parent ShadowViews are changing very frequently, making it impossible to actually modify the TextInput in some cases. However, we shouldn't forcibly reset the content of the TextInput if the frame of the parent is changing and not the actual child contents. Changelog: [Internal] Fabric TextInput bug fix Reviewed By: shergin Differential Revision: D20319359 fbshipit-source-id: 2f51f521ad76fff9da6f6c8b5e795f03c33e496f
148 lines
3.4 KiB
C++
148 lines
3.4 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 "AttributedString.h"
|
|
|
|
#include <react/debug/DebugStringConvertibleItem.h>
|
|
|
|
namespace facebook {
|
|
namespace react {
|
|
|
|
using Fragment = AttributedString::Fragment;
|
|
using Fragments = AttributedString::Fragments;
|
|
|
|
#pragma mark - Fragment
|
|
|
|
std::string Fragment::AttachmentCharacter() {
|
|
return "\uFFFC"; // Unicode `OBJECT REPLACEMENT CHARACTER`
|
|
}
|
|
|
|
bool Fragment::isAttachment() const {
|
|
return string == AttachmentCharacter();
|
|
}
|
|
|
|
bool Fragment::operator==(const Fragment &rhs) const {
|
|
return std::tie(
|
|
string,
|
|
textAttributes,
|
|
parentShadowView.tag,
|
|
parentShadowView.layoutMetrics) ==
|
|
std::tie(
|
|
rhs.string,
|
|
rhs.textAttributes,
|
|
rhs.parentShadowView.tag,
|
|
rhs.parentShadowView.layoutMetrics);
|
|
}
|
|
|
|
bool Fragment::operator!=(const Fragment &rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
#pragma mark - AttributedString
|
|
|
|
void AttributedString::appendFragment(const Fragment &fragment) {
|
|
ensureUnsealed();
|
|
|
|
if (fragment.string.empty()) {
|
|
return;
|
|
}
|
|
|
|
fragments_.push_back(fragment);
|
|
}
|
|
|
|
void AttributedString::prependFragment(const Fragment &fragment) {
|
|
ensureUnsealed();
|
|
|
|
if (fragment.string.empty()) {
|
|
return;
|
|
}
|
|
|
|
fragments_.insert(fragments_.begin(), fragment);
|
|
}
|
|
|
|
void AttributedString::appendAttributedString(
|
|
const AttributedString &attributedString) {
|
|
ensureUnsealed();
|
|
fragments_.insert(
|
|
fragments_.end(),
|
|
attributedString.fragments_.begin(),
|
|
attributedString.fragments_.end());
|
|
}
|
|
|
|
void AttributedString::prependAttributedString(
|
|
const AttributedString &attributedString) {
|
|
ensureUnsealed();
|
|
fragments_.insert(
|
|
fragments_.begin(),
|
|
attributedString.fragments_.begin(),
|
|
attributedString.fragments_.end());
|
|
}
|
|
|
|
const Fragments &AttributedString::getFragments() const {
|
|
return fragments_;
|
|
}
|
|
|
|
std::string AttributedString::getString() const {
|
|
auto string = std::string{};
|
|
for (const auto &fragment : fragments_) {
|
|
string += fragment.string;
|
|
}
|
|
return string;
|
|
}
|
|
|
|
bool AttributedString::isEmpty() const {
|
|
return fragments_.empty();
|
|
}
|
|
|
|
bool AttributedString::compareTextAttributesWithoutFrame(
|
|
const AttributedString &rhs) const {
|
|
if (fragments_.size() != rhs.fragments_.size()) {
|
|
return false;
|
|
}
|
|
|
|
for (unsigned i = 0; i < fragments_.size(); i++) {
|
|
if (fragments_[i].textAttributes != rhs.fragments_[i].textAttributes ||
|
|
fragments_[i].string != rhs.fragments_[i].string) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool AttributedString::operator==(const AttributedString &rhs) const {
|
|
return fragments_ == rhs.fragments_;
|
|
}
|
|
|
|
bool AttributedString::operator!=(const AttributedString &rhs) const {
|
|
return !(*this == rhs);
|
|
}
|
|
|
|
#pragma mark - DebugStringConvertible
|
|
|
|
#if RN_DEBUG_STRING_CONVERTIBLE
|
|
SharedDebugStringConvertibleList AttributedString::getDebugChildren() const {
|
|
auto list = SharedDebugStringConvertibleList{};
|
|
|
|
for (auto &&fragment : fragments_) {
|
|
auto propsList =
|
|
fragment.textAttributes.DebugStringConvertible::getDebugProps();
|
|
|
|
list.push_back(std::make_shared<DebugStringConvertibleItem>(
|
|
"Fragment",
|
|
fragment.string,
|
|
SharedDebugStringConvertibleList(),
|
|
propsList));
|
|
}
|
|
|
|
return list;
|
|
}
|
|
#endif
|
|
|
|
} // namespace react
|
|
} // namespace facebook
|