@@ -64,15 +64,6 @@ private static class NodeIndexPair {
6464 private final ShadowNodeRegistry mShadowNodeRegistry ;
6565 private final SparseBooleanArray mTagsWithLayoutVisited = new SparseBooleanArray ();
6666
67- public static void assertNodeSupportedWithoutOptimizer (ReactShadowNode node ) {
68- // NativeKind.LEAF nodes require the optimizer. They are not ViewGroups so they cannot host
69- // their native children themselves. Their native children need to be hoisted by the optimizer
70- // to an ancestor which is a ViewGroup.
71- Assertions .assertCondition (
72- node .getNativeKind () != NativeKind .LEAF ,
73- "Nodes with NativeKind.LEAF are not supported when the optimizer is disabled" );
74- }
75-
7667 public NativeViewHierarchyOptimizer (
7768 UIViewOperationQueue uiViewOperationQueue ,
7869 ShadowNodeRegistry shadowNodeRegistry ) {
@@ -88,7 +79,6 @@ public void handleCreateView(
8879 ThemedReactContext themedContext ,
8980 @ Nullable ReactStylesDiffMap initialProps ) {
9081 if (!ENABLED ) {
91- assertNodeSupportedWithoutOptimizer (node );
9282 int tag = node .getReactTag ();
9383 mUIViewOperationQueue .enqueueCreateView (
9484 themedContext ,
@@ -102,7 +92,7 @@ public void handleCreateView(
10292 isLayoutOnlyAndCollapsable (initialProps );
10393 node .setIsLayoutOnly (isLayoutOnly );
10494
105- if (node . getNativeKind () != NativeKind . NONE ) {
95+ if (! isLayoutOnly ) {
10696 mUIViewOperationQueue .enqueueCreateView (
10797 themedContext ,
10898 node .getReactTag (),
@@ -128,7 +118,6 @@ public void handleUpdateView(
128118 String className ,
129119 ReactStylesDiffMap props ) {
130120 if (!ENABLED ) {
131- assertNodeSupportedWithoutOptimizer (node );
132121 mUIViewOperationQueue .enqueueUpdateProperties (node .getReactTag (), className , props );
133122 return ;
134123 }
@@ -159,7 +148,6 @@ public void handleManageChildren(
159148 int [] tagsToDelete ,
160149 int [] indicesToDelete ) {
161150 if (!ENABLED ) {
162- assertNodeSupportedWithoutOptimizer (nodeToManage );
163151 mUIViewOperationQueue .enqueueManageChildren (
164152 nodeToManage .getReactTag (),
165153 indicesToRemove ,
@@ -201,7 +189,6 @@ public void handleSetChildren(
201189 ReadableArray childrenTags
202190 ) {
203191 if (!ENABLED ) {
204- assertNodeSupportedWithoutOptimizer (nodeToManage );
205192 mUIViewOperationQueue .enqueueSetChildren (
206193 nodeToManage .getReactTag (),
207194 childrenTags );
@@ -221,9 +208,8 @@ public void handleSetChildren(
221208 */
222209 public void handleUpdateLayout (ReactShadowNode node ) {
223210 if (!ENABLED ) {
224- assertNodeSupportedWithoutOptimizer (node );
225211 mUIViewOperationQueue .enqueueUpdateLayout (
226- Assertions .assertNotNull (node .getLayoutParent ()).getReactTag (),
212+ Assertions .assertNotNull (node .getParent ()).getReactTag (),
227213 node .getReactTag (),
228214 node .getScreenX (),
229215 node .getScreenY (),
@@ -235,12 +221,6 @@ public void handleUpdateLayout(ReactShadowNode node) {
235221 applyLayoutBase (node );
236222 }
237223
238- public void handleForceViewToBeNonLayoutOnly (ReactShadowNode node ) {
239- if (node .isLayoutOnly ()) {
240- transitionLayoutOnlyViewToNativeView (node , null );
241- }
242- }
243-
244224 /**
245225 * Processes the shadow hierarchy to dispatch all necessary updateLayout calls to the native
246226 * hierarchy. Should be called after all updateLayout calls for a batch have been handled.
@@ -249,18 +229,16 @@ public void onBatchComplete() {
249229 mTagsWithLayoutVisited .clear ();
250230 }
251231
252- private NodeIndexPair walkUpUntilNativeKindIsParent (
232+ private NodeIndexPair walkUpUntilNonLayoutOnly (
253233 ReactShadowNode node ,
254234 int indexInNativeChildren ) {
255- while (node .getNativeKind () != NativeKind . PARENT ) {
235+ while (node .isLayoutOnly () ) {
256236 ReactShadowNode parent = node .getParent ();
257237 if (parent == null ) {
258238 return null ;
259239 }
260240
261- indexInNativeChildren = indexInNativeChildren +
262- (node .getNativeKind () == NativeKind .LEAF ? 1 : 0 ) +
263- parent .getNativeOffsetForChild (node );
241+ indexInNativeChildren = indexInNativeChildren + parent .getNativeOffsetForChild (node );
264242 node = parent ;
265243 }
266244
@@ -269,8 +247,8 @@ private NodeIndexPair walkUpUntilNativeKindIsParent(
269247
270248 private void addNodeToNode (ReactShadowNode parent , ReactShadowNode child , int index ) {
271249 int indexInNativeChildren = parent .getNativeOffsetForChild (parent .getChildAt (index ));
272- if (parent .getNativeKind () != NativeKind . PARENT ) {
273- NodeIndexPair result = walkUpUntilNativeKindIsParent (parent , indexInNativeChildren );
250+ if (parent .isLayoutOnly () ) {
251+ NodeIndexPair result = walkUpUntilNonLayoutOnly (parent , indexInNativeChildren );
274252 if (result == null ) {
275253 // If the parent hasn't been attached to its native parent yet, don't issue commands to the
276254 // native hierarchy. We'll do that when the parent node actually gets attached somewhere.
@@ -280,26 +258,20 @@ private void addNodeToNode(ReactShadowNode parent, ReactShadowNode child, int in
280258 indexInNativeChildren = result .index ;
281259 }
282260
283- if (child .getNativeKind () != NativeKind . NONE ) {
284- addNativeChild (parent , child , indexInNativeChildren );
261+ if (! child .isLayoutOnly () ) {
262+ addNonLayoutNode (parent , child , indexInNativeChildren );
285263 } else {
286- addNonNativeChild (parent , child , indexInNativeChildren );
264+ addLayoutOnlyNode (parent , child , indexInNativeChildren );
287265 }
288266 }
289267
290268 /**
291- * For handling node removal from manageChildren. In the case of removing a node which isn't
292- * hosting its own children (e.g. layout-only or NativeKind.LEAF), we need to recursively remove
293- * all its children from their native parents.
269+ * For handling node removal from manageChildren. In the case of removing a layout-only node, we
270+ * need to instead recursively remove all its children from their native parents.
294271 */
295272 private void removeNodeFromParent (ReactShadowNode nodeToRemove , boolean shouldDelete ) {
296- if (nodeToRemove .getNativeKind () != NativeKind .PARENT ) {
297- for (int i = nodeToRemove .getChildCount () - 1 ; i >= 0 ; i --) {
298- removeNodeFromParent (nodeToRemove .getChildAt (i ), shouldDelete );
299- }
300- }
301-
302273 ReactShadowNode nativeNodeToRemoveFrom = nodeToRemove .getNativeParent ();
274+
303275 if (nativeNodeToRemoveFrom != null ) {
304276 int index = nativeNodeToRemoveFrom .indexOfNativeChild (nodeToRemove );
305277 nativeNodeToRemoveFrom .removeNativeChildAt (index );
@@ -310,17 +282,21 @@ private void removeNodeFromParent(ReactShadowNode nodeToRemove, boolean shouldDe
310282 null ,
311283 shouldDelete ? new int [] {nodeToRemove .getReactTag ()} : null ,
312284 shouldDelete ? new int [] {index } : null );
285+ } else {
286+ for (int i = nodeToRemove .getChildCount () - 1 ; i >= 0 ; i --) {
287+ removeNodeFromParent (nodeToRemove .getChildAt (i ), shouldDelete );
288+ }
313289 }
314290 }
315291
316- private void addNonNativeChild (
317- ReactShadowNode nativeParent ,
318- ReactShadowNode nonNativeChild ,
292+ private void addLayoutOnlyNode (
293+ ReactShadowNode nonLayoutOnlyNode ,
294+ ReactShadowNode layoutOnlyNode ,
319295 int index ) {
320- addGrandchildren (nativeParent , nonNativeChild , index );
296+ addGrandchildren (nonLayoutOnlyNode , layoutOnlyNode , index );
321297 }
322298
323- private void addNativeChild (
299+ private void addNonLayoutNode (
324300 ReactShadowNode parent ,
325301 ReactShadowNode child ,
326302 int index ) {
@@ -331,33 +307,30 @@ private void addNativeChild(
331307 new ViewAtIndex [] {new ViewAtIndex (child .getReactTag (), index )},
332308 null ,
333309 null );
334-
335- if (child .getNativeKind () != NativeKind .PARENT ) {
336- addGrandchildren (parent , child , index + 1 );
337- }
338310 }
339311
340312 private void addGrandchildren (
341313 ReactShadowNode nativeParent ,
342314 ReactShadowNode child ,
343315 int index ) {
344- Assertions .assertCondition (child . getNativeKind () != NativeKind . PARENT );
316+ Assertions .assertCondition (! nativeParent . isLayoutOnly () );
345317
346318 // `child` can't hold native children. Add all of `child`'s children to `parent`.
347319 int currentIndex = index ;
348320 for (int i = 0 ; i < child .getChildCount (); i ++) {
349321 ReactShadowNode grandchild = child .getChildAt (i );
350322 Assertions .assertCondition (grandchild .getNativeParent () == null );
351323
352- // Adding this child could result in adding multiple native views
353- int grandchildCountBefore = nativeParent .getNativeChildCount ();
354- if (grandchild .getNativeKind () == NativeKind .NONE ) {
355- addNonNativeChild (nativeParent , grandchild , currentIndex );
324+ if (grandchild .isLayoutOnly ()) {
325+ // Adding this child could result in adding multiple native views
326+ int grandchildCountBefore = nativeParent .getNativeChildCount ();
327+ addLayoutOnlyNode (nativeParent , grandchild , currentIndex );
328+ int grandchildCountAfter = nativeParent .getNativeChildCount ();
329+ currentIndex += grandchildCountAfter - grandchildCountBefore ;
356330 } else {
357- addNativeChild (nativeParent , grandchild , currentIndex );
331+ addNonLayoutNode (nativeParent , grandchild , currentIndex );
332+ currentIndex ++;
358333 }
359- int grandchildCountAfter = nativeParent .getNativeChildCount ();
360- currentIndex += grandchildCountAfter - grandchildCountBefore ;
361334 }
362335 }
363336
@@ -376,16 +349,10 @@ private void applyLayoutBase(ReactShadowNode node) {
376349 int x = node .getScreenX ();
377350 int y = node .getScreenY ();
378351
379- while (parent != null && parent .getNativeKind () != NativeKind .PARENT ) {
380- if (!parent .isVirtual ()) {
381- // Skip these additions for virtual nodes. This has the same effect as `getLayout*`
382- // returning `0`. Virtual nodes aren't in the Yoga tree so we can't call `getLayout*` on
383- // them.
384-
385- // TODO(7854667): handle and test proper clipping
386- x += Math .round (parent .getLayoutX ());
387- y += Math .round (parent .getLayoutY ());
388- }
352+ while (parent != null && parent .isLayoutOnly ()) {
353+ // TODO(7854667): handle and test proper clipping
354+ x += Math .round (parent .getLayoutX ());
355+ y += Math .round (parent .getLayoutY ());
389356
390357 parent = parent .getParent ();
391358 }
@@ -394,10 +361,10 @@ private void applyLayoutBase(ReactShadowNode node) {
394361 }
395362
396363 private void applyLayoutRecursive (ReactShadowNode toUpdate , int x , int y ) {
397- if (toUpdate .getNativeKind () != NativeKind . NONE && toUpdate .getNativeParent () != null ) {
364+ if (! toUpdate .isLayoutOnly () && toUpdate .getNativeParent () != null ) {
398365 int tag = toUpdate .getReactTag ();
399366 mUIViewOperationQueue .enqueueUpdateLayout (
400- toUpdate .getLayoutParent ().getReactTag (),
367+ toUpdate .getNativeParent ().getReactTag (),
401368 tag ,
402369 x ,
403370 y ,
0 commit comments