Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Re-add old Fabric Offscreen impl behind flag #22018

Merged
merged 2 commits into from
Aug 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions packages/react-native-renderer/src/ReactFabricHostConfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,32 @@ export function getOffscreenContainerProps(
}
}

export function cloneHiddenInstance(
instance: Instance,
type: string,
props: Props,
internalInstanceHandle: Object,
): Instance {
const viewConfig = instance.canonical.viewConfig;
const node = instance.node;
const updatePayload = create(
{style: {display: 'none'}},
viewConfig.validAttributes,
);
return {
node: cloneNodeWithNewProps(node, updatePayload),
canonical: instance.canonical,
};
}

export function cloneHiddenTextInstance(
instance: Instance,
text: string,
internalInstanceHandle: Object,
): TextInstance {
throw new Error('Not yet implemented.');
}

export function createContainerChildSet(container: Container): ChildSet {
return createChildNodeSet(container);
}
Expand Down
48 changes: 48 additions & 0 deletions packages/react-noop-renderer/src/createReactNoop.js
Original file line number Diff line number Diff line change
Expand Up @@ -582,6 +582,54 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
children,
};
},

cloneHiddenInstance(
instance: Instance,
type: string,
props: Props,
internalInstanceHandle: Object,
): Instance {
const clone = cloneInstance(
instance,
null,
type,
props,
props,
internalInstanceHandle,
true,
null,
);
clone.hidden = true;
return clone;
},

cloneHiddenTextInstance(
instance: TextInstance,
text: string,
internalInstanceHandle: Object,
): TextInstance {
const clone = {
text: instance.text,
id: instance.id,
parent: instance.parent,
hidden: true,
context: instance.context,
};
// Hide from unit tests
Object.defineProperty(clone, 'id', {
value: clone.id,
enumerable: false,
});
Object.defineProperty(clone, 'parent', {
value: clone.parent,
enumerable: false,
});
Object.defineProperty(clone, 'context', {
value: clone.context,
enumerable: false,
});
return clone;
},
};

const NoopRenderer = reconciler(hostConfig);
Expand Down
12 changes: 5 additions & 7 deletions packages/react-reconciler/src/ReactFiberBeginWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
enableLazyContextPropagation,
enableSuspenseLayoutEffectSemantics,
enableSchedulingProfiler,
enablePersistentOffscreenHostContainer,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
Expand Down Expand Up @@ -146,7 +147,6 @@ import {
registerSuspenseInstanceRetry,
supportsHydration,
isPrimaryRenderer,
supportsMutation,
supportsPersistence,
getOffscreenContainerProps,
} from './ReactFiberHostConfig';
Expand Down Expand Up @@ -744,7 +744,7 @@ function updateOffscreenComponent(
workInProgress.updateQueue = spawnedCachePool;
}

if (supportsPersistence) {
if (enablePersistentOffscreenHostContainer && supportsPersistence) {
// In persistent mode, the offscreen children are wrapped in a host node.
// TODO: Optimize this to use the OffscreenComponent fiber instead of
// an extra HostComponent fiber. Need to make sure this doesn't break Fabric
Expand All @@ -760,12 +760,10 @@ function updateOffscreenComponent(
renderLanes,
);
return offscreenContainer;
}
if (supportsMutation) {
} else {
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
}
return null;
}

function reconcileOffscreenHostContainer(
Expand Down Expand Up @@ -2383,7 +2381,7 @@ function updateSuspenseFallbackChildren(
currentPrimaryChildFragment.treeBaseDuration;
}

if (supportsPersistence) {
if (enablePersistentOffscreenHostContainer && supportsPersistence) {
// In persistent mode, the offscreen children are wrapped in a host node.
// We need to complete it now, because we're going to skip over its normal
// complete phase and go straight to rendering the fallback.
Expand Down Expand Up @@ -2411,7 +2409,7 @@ function updateSuspenseFallbackChildren(
primaryChildProps,
);

if (supportsPersistence) {
if (enablePersistentOffscreenHostContainer && supportsPersistence) {
// In persistent mode, the offscreen children are wrapped in a host node.
// We need to complete it now, because we're going to skip over its normal
// complete phase and go straight to rendering the fallback.
Expand Down
12 changes: 5 additions & 7 deletions packages/react-reconciler/src/ReactFiberBeginWork.old.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ import {
enableLazyContextPropagation,
enableSuspenseLayoutEffectSemantics,
enableSchedulingProfiler,
enablePersistentOffscreenHostContainer,
} from 'shared/ReactFeatureFlags';
import invariant from 'shared/invariant';
import isArray from 'shared/isArray';
Expand Down Expand Up @@ -146,7 +147,6 @@ import {
registerSuspenseInstanceRetry,
supportsHydration,
isPrimaryRenderer,
supportsMutation,
supportsPersistence,
getOffscreenContainerProps,
} from './ReactFiberHostConfig';
Expand Down Expand Up @@ -744,7 +744,7 @@ function updateOffscreenComponent(
workInProgress.updateQueue = spawnedCachePool;
}

if (supportsPersistence) {
if (enablePersistentOffscreenHostContainer && supportsPersistence) {
// In persistent mode, the offscreen children are wrapped in a host node.
// TODO: Optimize this to use the OffscreenComponent fiber instead of
// an extra HostComponent fiber. Need to make sure this doesn't break Fabric
Expand All @@ -760,12 +760,10 @@ function updateOffscreenComponent(
renderLanes,
);
return offscreenContainer;
}
if (supportsMutation) {
} else {
reconcileChildren(current, workInProgress, nextChildren, renderLanes);
return workInProgress.child;
}
return null;
}

function reconcileOffscreenHostContainer(
Expand Down Expand Up @@ -2383,7 +2381,7 @@ function updateSuspenseFallbackChildren(
currentPrimaryChildFragment.treeBaseDuration;
}

if (supportsPersistence) {
if (enablePersistentOffscreenHostContainer && supportsPersistence) {
// In persistent mode, the offscreen children are wrapped in a host node.
// We need to complete it now, because we're going to skip over its normal
// complete phase and go straight to rendering the fallback.
Expand Down Expand Up @@ -2411,7 +2409,7 @@ function updateSuspenseFallbackChildren(
primaryChildProps,
);

if (supportsPersistence) {
if (enablePersistentOffscreenHostContainer && supportsPersistence) {
// In persistent mode, the offscreen children are wrapped in a host node.
// We need to complete it now, because we're going to skip over its normal
// complete phase and go straight to rendering the fallback.
Expand Down
87 changes: 77 additions & 10 deletions packages/react-reconciler/src/ReactFiberCompleteWork.new.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ import {
supportsMutation,
supportsPersistence,
cloneInstance,
cloneHiddenInstance,
cloneHiddenTextInstance,
createContainerChildSet,
appendChildToContainerChildSet,
finalizeContainerChildren,
Expand Down Expand Up @@ -128,6 +130,7 @@ import {
enableProfilerTimer,
enableCache,
enableSuspenseLayoutEffectSemantics,
enablePersistentOffscreenHostContainer,
} from 'shared/ReactFeatureFlags';
import {
renderDidSuspend,
Expand Down Expand Up @@ -198,7 +201,12 @@ let updateHostText;
if (supportsMutation) {
// Mutation mode

appendAllChildren = function(parent: Instance, workInProgress: Fiber) {
appendAllChildren = function(
parent: Instance,
workInProgress: Fiber,
needsVisibilityToggle: boolean,
isHidden: boolean,
) {
// We only have the top Fiber that was created but we need recurse down its
// children to find all the terminal nodes.
let node = workInProgress.child;
Expand Down Expand Up @@ -286,22 +294,53 @@ if (supportsMutation) {
} else if (supportsPersistence) {
// Persistent host tree mode

appendAllChildren = function(parent: Instance, workInProgress: Fiber) {
appendAllChildren = function(
parent: Instance,
workInProgress: Fiber,
needsVisibilityToggle: boolean,
isHidden: boolean,
) {
// We only have the top Fiber that was created but we need recurse down its
// children to find all the terminal nodes.
let node = workInProgress.child;
while (node !== null) {
// eslint-disable-next-line no-labels
branches: if (node.tag === HostComponent) {
const instance = node.stateNode;
let instance = node.stateNode;
if (needsVisibilityToggle && isHidden) {
// This child is inside a timed out tree. Hide it.
const props = node.memoizedProps;
const type = node.type;
instance = cloneHiddenInstance(instance, type, props, node);
}
appendInitialChild(parent, instance);
} else if (node.tag === HostText) {
const instance = node.stateNode;
let instance = node.stateNode;
if (needsVisibilityToggle && isHidden) {
// This child is inside a timed out tree. Hide it.
const text = node.memoizedProps;
instance = cloneHiddenTextInstance(instance, text, node);
}
appendInitialChild(parent, instance);
} else if (node.tag === HostPortal) {
// If we have a portal child, then we don't want to traverse
// down its children. Instead, we'll get insertions from each child in
// the portal directly.
} else if (
node.tag === OffscreenComponent &&
node.memoizedState !== null
) {
// The children in this boundary are hidden. Toggle their visibility
// before appending.
const child = node.child;
if (child !== null) {
child.return = node;
}
if (enablePersistentOffscreenHostContainer) {
appendAllChildren(parent, node, false, false);
} else {
appendAllChildren(parent, node, true, true);
}
} else if (node.child !== null) {
node.child.return = node;
node = node.child;
Expand All @@ -327,22 +366,50 @@ if (supportsMutation) {
const appendAllChildrenToContainer = function(
containerChildSet: ChildSet,
workInProgress: Fiber,
needsVisibilityToggle: boolean,
isHidden: boolean,
) {
// We only have the top Fiber that was created but we need recurse down its
// children to find all the terminal nodes.
let node = workInProgress.child;
while (node !== null) {
// eslint-disable-next-line no-labels
branches: if (node.tag === HostComponent) {
const instance = node.stateNode;
let instance = node.stateNode;
if (needsVisibilityToggle && isHidden) {
// This child is inside a timed out tree. Hide it.
const props = node.memoizedProps;
const type = node.type;
instance = cloneHiddenInstance(instance, type, props, node);
}
appendChildToContainerChildSet(containerChildSet, instance);
} else if (node.tag === HostText) {
const instance = node.stateNode;
let instance = node.stateNode;
if (needsVisibilityToggle && isHidden) {
// This child is inside a timed out tree. Hide it.
const text = node.memoizedProps;
instance = cloneHiddenTextInstance(instance, text, node);
}
appendChildToContainerChildSet(containerChildSet, instance);
} else if (node.tag === HostPortal) {
// If we have a portal child, then we don't want to traverse
// down its children. Instead, we'll get insertions from each child in
// the portal directly.
} else if (
node.tag === OffscreenComponent &&
node.memoizedState !== null
) {
// The children in this boundary are hidden. Toggle their visibility
// before appending.
const child = node.child;
if (child !== null) {
child.return = node;
}
if (enablePersistentOffscreenHostContainer) {
appendAllChildrenToContainer(containerChildSet, node, false, false);
} else {
appendAllChildrenToContainer(containerChildSet, node, true, true);
}
} else if (node.child !== null) {
node.child.return = node;
node = node.child;
Expand Down Expand Up @@ -376,7 +443,7 @@ if (supportsMutation) {
const container = portalOrRoot.containerInfo;
const newChildSet = createContainerChildSet(container);
// If children might have changed, we have to add them all to the set.
appendAllChildrenToContainer(newChildSet, workInProgress);
appendAllChildrenToContainer(newChildSet, workInProgress, false, false);
portalOrRoot.pendingChildren = newChildSet;
// Schedule an update on the container to swap out the container.
markUpdate(workInProgress);
Expand Down Expand Up @@ -449,7 +516,7 @@ if (supportsMutation) {
markUpdate(workInProgress);
} else {
// If children might have changed, we have to add them all to the set.
appendAllChildren(newInstance, workInProgress);
appendAllChildren(newInstance, workInProgress, false, false);
}
};
updateHostText = function(
Expand Down Expand Up @@ -722,7 +789,7 @@ export function completeSuspendedOffscreenHostContainer(
workInProgress,
);

appendAllChildren(instance, workInProgress);
appendAllChildren(instance, workInProgress, false, false);

workInProgress.stateNode = instance;

Expand Down Expand Up @@ -869,7 +936,7 @@ function completeWork(
workInProgress,
);

appendAllChildren(instance, workInProgress);
appendAllChildren(instance, workInProgress, false, false);

workInProgress.stateNode = instance;

Expand Down
Loading