From abfa63c67e22b985edc65a1e856d4733c339480c Mon Sep 17 00:00:00 2001 From: Valentin Shergin Date: Tue, 20 Jun 2017 17:09:52 -0700 Subject: [PATCH] Introducing -[RCTShadowView canHaveSubviews] Summary: Override `canHaveSubviews` in RCTShadowView subclass to disallow any nested content. For now, this prop will be checked only in DEV mode for performance reasons. Reviewed By: javache Differential Revision: D5189083 fbshipit-source-id: 87087dd806e1fd7320128dab969b13642174f81c --- React/Views/RCTShadowView.h | 15 ++++++++++++++- React/Views/RCTShadowView.m | 7 +++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/React/Views/RCTShadowView.h b/React/Views/RCTShadowView.h index bcf0522f82a01c..90f21c86355894 100644 --- a/React/Views/RCTShadowView.h +++ b/React/Views/RCTShadowView.h @@ -217,9 +217,22 @@ typedef void (^RCTApplierBlock)(NSDictionary *viewRegistry absolutePosition:(CGPoint)absolutePosition; /** - * Return whether or not this node acts as a leaf node in the eyes of Yoga. + * Returns whether or not this view can have any subviews. + * Adding/inserting a child view to leaf view (`canHaveSubviews` equals `NO`) + * will throw an error. + * Return `NO` for components which must not have any descendants + * (like , for example.) + * Defaults to `YES`. Can be overridden in subclasses. + * Don't confuse this with `isYogaLeafNode`. + */ +- (BOOL)canHaveSubviews; + +/** + * Returns whether or not this node acts as a leaf node in the eyes of Yoga. * For example `RCTShadowText` has children which it does not want Yoga * to lay out so in the eyes of Yoga it is a leaf node. + * Defaults to `NO`. Can be overridden in subclasses. + * Don't confuse this with `canHaveSubviews`. */ - (BOOL)isYogaLeafNode; diff --git a/React/Views/RCTShadowView.m b/React/Views/RCTShadowView.m index 61b992cb1ca30b..2e7d4794c6569a 100644 --- a/React/Views/RCTShadowView.m +++ b/React/Views/RCTShadowView.m @@ -365,6 +365,11 @@ - (void)dealloc YGNodeFree(_yogaNode); } +- (BOOL)canHaveSubviews +{ + return NO; +} + - (BOOL)isYogaLeafNode { return NO; @@ -403,6 +408,8 @@ - (void)setTextComputed - (void)insertReactSubview:(RCTShadowView *)subview atIndex:(NSInteger)atIndex { + RCTAssert(!self.canHaveSubviews, @"Attempt to insert subview inside leaf view."); + [_reactSubviews insertObject:subview atIndex:atIndex]; if (![self isYogaLeafNode]) { YGNodeInsertChild(_yogaNode, subview.yogaNode, (uint32_t)atIndex);