Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Commit aba370f

Browse files
authored
Add moveBefore Experiment (#31596)
A long standing issue for React has been that if you reorder stateful nodes, they may lose their state and reload. The thing moving loses its state. There's no way to solve this in general where two stateful nodes swap. The [`moveBefore()` proposal](https://chromestatus.com/feature/5135990159835136?gate=5177450351558656) has now moved to [intent-to-ship](https://groups.google.com/a/chromium.org/g/blink-dev/c/YE_xLH6MkRs/m/_7CD0NYMAAAJ). This function is kind of like `insertBefore` but preserves state. There's [a demo here](https://state-preserving-atomic-move.glitch.me/). Ideally we'd port this demo to a fixture so we can try it. Currently this flag is always off - even in experimental. That's because this is still behind a Chrome flag so it's a little early to turn it on even in experimental. So you need a custom build. It's on in RN but only because it doesn't apply there which makes it easier to tell that it's safe to ship once it's on everywhere else. The other reason it's still off is because there's currently a semantic breaking change. `moveBefore()` errors if both nodes are disconnected. That happens if we're inside a completely disconnected React root. That's not usually how you should use React because it means effects can't read layout etc. However, it is currently supported. To handle this we'd have to try/catch the `moveBefore` to handle this case but we hope this semantic will change before it ships. Before we turn this on in experimental we either have to wait for the implementation to not error in the disconnected-disconnected case in Chrome or we'd have to add try/catch.
1 parent 1345c37 commit aba370f

8 files changed

Lines changed: 29 additions & 2 deletions

‎packages/react-dom-bindings/src/client/ReactFiberConfigDOM.js‎

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ import {
9393
enableTrustedTypesIntegration,
9494
enableAsyncActions,
9595
disableLegacyMode,
96+
enableMoveBefore,
9697
}from'shared/ReactFeatureFlags';
9798
import{
9899
HostComponent,
@@ -525,6 +526,7 @@ export function appendInitialChild(
525526
parentInstance: Instance,
526527
child: Instance|TextInstance,
527528
): void{
529+
// Note: This should not use moveBefore() because initial are appended while disconnected.
528530
parentInstance.appendChild(child);
529531
}
530532

@@ -757,11 +759,22 @@ export function commitTextUpdate(
757759
textInstance.nodeValue=newText;
758760
}
759761

762+
constsupportsMoveBefore=
763+
// $FlowFixMe[prop-missing]: We're doing the feature detection here.
764+
enableMoveBefore&&
765+
typeofwindow!=='undefined'&&
766+
typeofwindow.Node.prototype.moveBefore==='function';
767+
760768
exportfunctionappendChild(
761769
parentInstance: Instance,
762770
child: Instance|TextInstance,
763771
): void{
764-
parentInstance.appendChild(child);
772+
if(supportsMoveBefore){
773+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
774+
parentInstance.moveBefore(child,null);
775+
}else{
776+
parentInstance.appendChild(child);
777+
}
765778
}
766779

767780
exportfunctionappendChildToContainer(
@@ -799,7 +812,12 @@ export function insertBefore(
799812
child: Instance|TextInstance,
800813
beforeChild: Instance|TextInstance|SuspenseInstance,
801814
): void{
802-
parentInstance.insertBefore(child,beforeChild);
815+
if(supportsMoveBefore){
816+
// $FlowFixMe[prop-missing]: We've checked this with supportsMoveBefore.
817+
parentInstance.moveBefore(child,beforeChild);
818+
}else{
819+
parentInstance.insertBefore(child,beforeChild);
820+
}
803821
}
804822

805823
exportfunctioninsertInContainerBefore(

‎packages/shared/ReactFeatureFlags.js‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,9 @@ export const disableIEWorkarounds = true;
210210
// request for certain browsers.
211211
exportconstenableFilterEmptyStringAttributesDOM=true;
212212

213+
// Enable the moveBefore() alternative to insertBefore(). This preserves states of moves.
214+
exportconstenableMoveBefore=false;
215+
213216
// Disabled caching behavior of `react/cache` in client runtimes.
214217
exportconstdisableClientCache=true;
215218

‎packages/shared/forks/ReactFeatureFlags.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ export const enableDebugTracing = false;
5555
exportconstenableDeferRootSchedulingToMicrotask=true;
5656
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
5757
exportconstenableFilterEmptyStringAttributesDOM=true;
58+
exportconstenableMoveBefore=true;
5859
exportconstenableFizzExternalRuntime=true;
5960
exportconstenableFlightReadableStream=true;
6061
exportconstenableGetInspectorDataForInstanceInProduction=true;

‎packages/shared/forks/ReactFeatureFlags.native-oss.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export const enableDeferRootSchedulingToMicrotask = true;
4444
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
4545
exportconstenableFabricCompleteRootInCommitPhase=false;
4646
exportconstenableFilterEmptyStringAttributesDOM=true;
47+
exportconstenableMoveBefore=true;
4748
exportconstenableFizzExternalRuntime=true;
4849
exportconstenableFlightReadableStream=true;
4950
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ export const favorSafetyOverHydrationPerf = true;
4545
exportconstenableComponentStackLocations=true;
4646
exportconstenableLegacyFBSupport=false;
4747
exportconstenableFilterEmptyStringAttributesDOM=true;
48+
exportconstenableMoveBefore=false;
4849
exportconstenableGetInspectorDataForInstanceInProduction=false;
4950
exportconstenableFabricCompleteRootInCommitPhase=false;
5051
exportconstenableHiddenSubtreeInsertionEffectCleanup=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ export const enableDebugTracing = false;
3535
exportconstenableDeferRootSchedulingToMicrotask=true;
3636
exportconstenableDO_NOT_USE_disableStrictPassiveEffect=false;
3737
exportconstenableFilterEmptyStringAttributesDOM=true;
38+
exportconstenableMoveBefore=false;
3839
exportconstenableFizzExternalRuntime=true;
3940
exportconstenableFlightReadableStream=true;
4041
exportconstenableGetInspectorDataForInstanceInProduction=false;

‎packages/shared/forks/ReactFeatureFlags.test-renderer.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export const favorSafetyOverHydrationPerf = true;
4747
exportconstenableComponentStackLocations=true;
4848
exportconstenableLegacyFBSupport=false;
4949
exportconstenableFilterEmptyStringAttributesDOM=true;
50+
exportconstenableMoveBefore=false;
5051
exportconstenableGetInspectorDataForInstanceInProduction=false;
5152
exportconstenableRenderableContext=false;
5253
exportconstenableFabricCompleteRootInCommitPhase=false;

‎packages/shared/forks/ReactFeatureFlags.www.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export const enableCPUSuspense = true;
5757
exportconstenableUseMemoCacheHook=true;
5858
exportconstenableUseEffectEventHook=true;
5959
exportconstenableFilterEmptyStringAttributesDOM=true;
60+
exportconstenableMoveBefore=false;
6061
exportconstenableAsyncActions=true;
6162
exportconstdisableInputAttributeSyncing=false;
6263
exportconstenableLegacyFBSupport=true;

0 commit comments

Comments
 (0)