Files
react-native/ReactCommon/fabric/attributedstring/AttributedString.h
David Vacca 89f647d521 Redefine hashcode for AttributedString
Summary:
This diff changes the method to calculate the hash of an AttributedString (removing shadowNode and parentShadowNode from it).
This is necessary becuase otherwise hashcode of clonned parent keep changing in every state change, when the text doesnt change

With this change we are able to cache spannables in android properly

Reviewed By: shergin

Differential Revision: D13189110

fbshipit-source-id: c1f7372809ce98a5b4d091485cc15281a4ab5e1e
2018-11-25 17:21:00 -08:00

111 lines
2.9 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.
*/
#pragma once
#include <functional>
#include <memory>
#include <folly/Optional.h>
#include <react/attributedstring/TextAttributes.h>
#include <react/core/Sealable.h>
#include <react/core/ShadowNode.h>
#include <react/debug/DebugStringConvertible.h>
namespace facebook {
namespace react {
class AttributedString;
using SharedAttributedString = std::shared_ptr<const AttributedString>;
/*
* Simple, cross-platfrom, React-specific implementation of attributed string
* (aka spanned string).
* `AttributedString` is basically a list of `Fragments` which have `string` and
* `textAttributes` + `shadowNode` associated with the `string`.
*/
class AttributedString : public Sealable, public DebugStringConvertible {
public:
class Fragment {
public:
std::string string;
TextAttributes textAttributes;
SharedShadowNode shadowNode;
SharedShadowNode parentShadowNode;
bool operator==(const Fragment &rhs) const;
bool operator!=(const Fragment &rhs) const;
};
using Fragments = std::vector<Fragment>;
/*
* Appends and prepends a `fragment` to the string.
*/
void appendFragment(const Fragment &fragment);
void prependFragment(const Fragment &fragment);
/*
* Appends and prepends an `attributedString` (all its fragments) to
* the string.
*/
void appendAttributedString(const AttributedString &attributedString);
void prependAttributedString(const AttributedString &attributedString);
/*
* Returns read-only reference to a list of fragments.
*/
const Fragments &getFragments() const;
/*
* Returns a string constructed from all strings in all fragments.
*/
std::string getString() const;
bool operator==(const AttributedString &rhs) const;
bool operator!=(const AttributedString &rhs) const;
#pragma mark - DebugStringConvertible
#if RN_DEBUG_STRING_CONVERTIBLE
SharedDebugStringConvertibleList getDebugChildren() const override;
#endif
private:
Fragments fragments_;
};
} // namespace react
} // namespace facebook
namespace std {
template <>
struct hash<facebook::react::AttributedString::Fragment> {
size_t operator()(
const facebook::react::AttributedString::Fragment &fragment) const {
return std::hash<decltype(fragment.string)>{}(fragment.string) +
std::hash<decltype(fragment.textAttributes)>{}(fragment.textAttributes);
}
};
template <>
struct hash<facebook::react::AttributedString> {
size_t operator()(
const facebook::react::AttributedString &attributedString) const {
auto result = size_t{0};
for (const auto &fragment : attributedString.getFragments()) {
result +=
std::hash<facebook::react::AttributedString::Fragment>{}(fragment);
}
return result;
}
};
} // namespace std