/** * 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 #include #include #include #include #include #include #include #include namespace facebook { namespace react { /* * Template for all -like classes (classes which have all same props * as and similar basic behaviour). * For example: , , but not , . */ template < const char *concreteComponentName, typename ViewPropsT = ViewProps, typename ViewEventEmitterT = ViewEventEmitter, typename... Ts> class ConcreteViewShadowNode : public ConcreteShadowNode< concreteComponentName, ViewPropsT, ViewEventEmitterT, Ts...>, public AccessibleShadowNode, public YogaLayoutableShadowNode { static_assert( std::is_base_of::value, "ViewPropsT must be a descendant of ViewProps"); static_assert( std::is_base_of::value, "ViewPropsT must be a descendant of YogaStylableProps"); static_assert( std::is_base_of::value, "ViewPropsT must be a descendant of AccessibilityProps"); public: using BaseShadowNode = ConcreteShadowNode< concreteComponentName, ViewPropsT, ViewEventEmitterT, Ts...>; using ConcreteViewProps = ViewPropsT; ConcreteViewShadowNode( const ShadowNodeFragment &fragment, const ComponentDescriptor &componentDescriptor) : BaseShadowNode(fragment, componentDescriptor), AccessibleShadowNode( std::static_pointer_cast(fragment.props)), YogaLayoutableShadowNode() { YogaLayoutableShadowNode::setProps( *std::static_pointer_cast(fragment.props)); YogaLayoutableShadowNode::setChildren( BaseShadowNode::template getChildrenSlice()); }; ConcreteViewShadowNode( const ShadowNode &sourceShadowNode, const ShadowNodeFragment &fragment) : BaseShadowNode(sourceShadowNode, fragment), AccessibleShadowNode( static_cast(sourceShadowNode), std::static_pointer_cast(fragment.props)), YogaLayoutableShadowNode( static_cast(sourceShadowNode)) { if (fragment.props) { YogaLayoutableShadowNode::setProps( *std::static_pointer_cast(fragment.props)); } if (fragment.children) { YogaLayoutableShadowNode::setChildren( BaseShadowNode::template getChildrenSlice< YogaLayoutableShadowNode>()); } }; void appendChild(const SharedShadowNode &child) { ensureUnsealed(); ShadowNode::appendChild(child); auto nonConstChild = const_cast(child.get()); auto yogaLayoutableChild = dynamic_cast(nonConstChild); if (yogaLayoutableChild) { YogaLayoutableShadowNode::appendChild(yogaLayoutableChild); } } LayoutableShadowNode *cloneAndReplaceChild( LayoutableShadowNode *child, int suggestedIndex = -1) override { ensureUnsealed(); auto childShadowNode = static_cast(child); auto clonedChildShadowNode = std::static_pointer_cast( childShadowNode->clone({})); ShadowNode::replaceChild( childShadowNode->shared_from_this(), clonedChildShadowNode, suggestedIndex); return clonedChildShadowNode.get(); } #pragma mark - DebugStringConvertible #if RN_DEBUG_STRING_CONVERTIBLE SharedDebugStringConvertibleList getDebugProps() const override { auto list = SharedDebugStringConvertibleList{}; auto basePropsList = ShadowNode::getDebugProps(); std::move( basePropsList.begin(), basePropsList.end(), std::back_inserter(list)); list.push_back(std::make_shared( "layout", "", LayoutableShadowNode::getDebugProps())); return list; } #endif }; } // namespace react } // namespace facebook