guardia-messenger/node_modules/react-native/ReactCommon/react/renderer/observers/mutation/MutationObserver.cpp
DESKTOP-TKLFCPRython f29f525c77 refactor: 101.79.17.164 → zioinfo.co.kr 전체 도메인 변환 + Manager UI 배포
- 37개 파일 IP → zioinfo.co.kr 치환 (소스/매뉴얼/설정/하네스)
- Manager DrConsole/NetworkConsole/CsapConsole 빌드 + /var/www/manager/ 배포
- 테스트: Manager HTTP 200, ITSM 신규 API 7개 전체 200

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 10:09:17 +09:00

201 lines
6.2 KiB
C++

/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#include "MutationObserver.h"
#include <react/renderer/core/ShadowNodeTraits.h>
#include <react/renderer/uimanager/primitives.h>
namespace facebook::react {
MutationObserver::MutationObserver(MutationObserverId mutationObserverId)
: mutationObserverId_(mutationObserverId) {}
void MutationObserver::observe(
ShadowNode::Shared targetShadowNode,
bool observeSubtree) {
if (observeSubtree) {
deeplyObservedShadowNodes_.push_back(targetShadowNode);
} else {
shallowlyObservedShadowNodes_.push_back(targetShadowNode);
}
}
void MutationObserver::unobserve(const ShadowNode& targetShadowNode) {
// We don't know if it's being observed deeply or not, so we need to check
// both possibilities.
deeplyObservedShadowNodes_.erase(
std::remove_if(
deeplyObservedShadowNodes_.begin(),
deeplyObservedShadowNodes_.end(),
[&targetShadowNode](auto shadowNode) {
return ShadowNode::sameFamily(*shadowNode, targetShadowNode);
}),
deeplyObservedShadowNodes_.end());
shallowlyObservedShadowNodes_.erase(
std::remove_if(
shallowlyObservedShadowNodes_.begin(),
shallowlyObservedShadowNodes_.end(),
[&targetShadowNode](const auto shadowNode) {
return ShadowNode::sameFamily(*shadowNode, targetShadowNode);
}),
shallowlyObservedShadowNodes_.end());
}
bool MutationObserver::isObserving() const {
return !deeplyObservedShadowNodes_.empty() ||
!shallowlyObservedShadowNodes_.empty();
}
static ShadowNode::Shared getShadowNodeInTree(
const ShadowNode& shadowNode,
const ShadowNode& newTree) {
auto ancestors = shadowNode.getFamily().getAncestors(newTree);
if (ancestors.empty()) {
return nullptr;
}
auto pair = ancestors.rbegin();
return pair->first.get().getChildren().at(pair->second);
}
static ShadowNode::Shared findNodeOfSameFamily(
const ShadowNode::ListOfShared& list,
const ShadowNode& node) {
for (auto& current : list) {
if (ShadowNode::sameFamily(node, *current)) {
return current;
}
}
return nullptr;
}
void MutationObserver::recordMutations(
const RootShadowNode& oldRootShadowNode,
const RootShadowNode& newRootShadowNode,
std::vector<MutationRecord>& recordedMutations) const {
// This tracks the nodes that have already been processed by this observer,
// so we avoid unnecessary work and duplicated entries.
SetOfShadowNodePointers processedNodes;
// We go over the deeply observed nodes first to avoid skipping nodes that
// have only been checked shallowly.
for (auto targetShadowNode : deeplyObservedShadowNodes_) {
recordMutationsInTarget(
targetShadowNode,
oldRootShadowNode,
newRootShadowNode,
true,
recordedMutations,
processedNodes);
}
for (auto targetShadowNode : shallowlyObservedShadowNodes_) {
recordMutationsInTarget(
targetShadowNode,
oldRootShadowNode,
newRootShadowNode,
false,
recordedMutations,
processedNodes);
}
}
void MutationObserver::recordMutationsInTarget(
ShadowNode::Shared targetShadowNode,
const RootShadowNode& oldRootShadowNode,
const RootShadowNode& newRootShadowNode,
bool observeSubtree,
std::vector<MutationRecord>& recordedMutations,
SetOfShadowNodePointers& processedNodes) const {
// If the node isnt't present in the old tree, it's either:
// - A new node. In that case, the mutation happened in its parent, not in the
// node itself.
// - A non-existent node. In that case, there are no new mutations.
auto oldTargetShadowNode =
getShadowNodeInTree(*targetShadowNode, oldRootShadowNode);
if (!oldTargetShadowNode) {
return;
}
// If the node isn't present in the new tree (and we didn't return in the
// previous check), it means the whole node was removed. In that case we don't
// record any mutations in the node itself (maybe in its parent if there are
// other observers set up).
auto newTargetShadowNode =
getShadowNodeInTree(*targetShadowNode, newRootShadowNode);
if (!newTargetShadowNode) {
return;
}
recordMutationsInSubtrees(
std::move(targetShadowNode),
*oldTargetShadowNode,
*newTargetShadowNode,
observeSubtree,
recordedMutations,
processedNodes);
}
void MutationObserver::recordMutationsInSubtrees(
ShadowNode::Shared targetShadowNode,
const ShadowNode& oldNode,
const ShadowNode& newNode,
bool observeSubtree,
std::vector<MutationRecord>& recordedMutations,
SetOfShadowNodePointers processedNodes) const {
bool isSameNode = &oldNode == &newNode;
// If the nodes are referentially equal, their children are also the same.
if (isSameNode || processedNodes.find(&newNode) != processedNodes.end()) {
return;
}
processedNodes.insert(&newNode);
auto oldChildren = oldNode.getChildren();
auto newChildren = newNode.getChildren();
std::vector<ShadowNode::Shared> addedNodes;
std::vector<ShadowNode::Shared> removedNodes;
// Check for removed nodes (and equal nodes for further inspection)
for (auto& oldChild : oldChildren) {
auto newChild = findNodeOfSameFamily(newChildren, *oldChild);
if (!newChild) {
removedNodes.push_back(oldChild);
} else if (observeSubtree) {
// Nodes are present in both tress. If `subtree` is set to true,
// we continue checking their children.
recordMutationsInSubtrees(
targetShadowNode,
*oldChild,
*newChild,
observeSubtree,
recordedMutations,
processedNodes);
}
}
// Check for added nodes
for (auto& newChild : newChildren) {
auto oldChild = findNodeOfSameFamily(oldChildren, *newChild);
if (!oldChild) {
addedNodes.push_back(newChild);
}
}
if (!addedNodes.empty() || !removedNodes.empty()) {
recordedMutations.emplace_back(MutationRecord{
mutationObserverId_,
targetShadowNode,
std::move(addedNodes),
std::move(removedNodes)});
}
}
} // namespace facebook::react