/** * Copyright (c) 2015-present, Facebook, Inc. * * 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 > class ConcreteViewShadowNode: public ConcreteShadowNode< concreteComponentName, ViewPropsT, ViewEventEmitterT >, 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 >; using ConcreteViewProps = ViewPropsT; ConcreteViewShadowNode( const ShadowNodeFragment &fragment, const ShadowNodeCloneFunction &cloneFunction ): BaseShadowNode( fragment, cloneFunction ), 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()); } }; 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 - Equality bool operator==(const ShadowNode& rhs) const override { if (!ShadowNode::operator==(rhs)) { return false; } const auto &other = static_cast(rhs); return getLayoutMetrics() == other.getLayoutMetrics(); } #pragma mark - DebugStringConvertible SharedDebugStringConvertibleList getDebugProps() const override { SharedDebugStringConvertibleList list = {}; 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; } }; } // namespace react } // namespace facebook