diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponent.js b/packages/react-dom-bindings/src/client/ReactDOMComponent.js index 037d787197c8..57689ca6145c 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMComponent.js +++ b/packages/react-dom-bindings/src/client/ReactDOMComponent.js @@ -74,6 +74,7 @@ import { enableCustomElementPropertySupport, enableClientRenderFallbackOnTextMismatch, enableHostSingletons, + disableIEWorkarounds, } from 'shared/ReactFeatureFlags'; import { mediaEventTypes, @@ -116,7 +117,8 @@ if (__DEV__) { // normalized. Since it only affects IE, we're skipping style warnings // in that browser completely in favor of doing all that work. // See https://github.com/facebook/react/issues/11807 - canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode; + canDiffStyleForHydrationWarning = + disableIEWorkarounds || (canUseDOM && !document.documentMode); } function validatePropertiesInDevelopment(type: string, props: any) { @@ -308,7 +310,11 @@ function setInitialDOMProperties( } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { const nextHtml = nextProp ? nextProp[HTML] : undefined; if (nextHtml != null) { - setInnerHTML(domElement, nextHtml); + if (disableIEWorkarounds) { + domElement.innerHTML = nextHtml; + } else { + setInnerHTML(domElement, nextHtml); + } } } else if (propKey === CHILDREN) { if (typeof nextProp === 'string') { @@ -366,7 +372,11 @@ function updateDOMProperties( if (propKey === STYLE) { setValueForStyles(domElement, propValue); } else if (propKey === DANGEROUSLY_SET_INNER_HTML) { - setInnerHTML(domElement, propValue); + if (disableIEWorkarounds) { + domElement.innerHTML = propValue; + } else { + setInnerHTML(domElement, propValue); + } } else if (propKey === CHILDREN) { setTextContent(domElement, propValue); } else { diff --git a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js index d6a06842492e..a9ae22f1f567 100644 --- a/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js +++ b/packages/react-dom/src/__tests__/ReactServerRenderingHydration-test.js @@ -195,6 +195,7 @@ describe('ReactDOMServerHydration', () => { ); }); + // @gate !disableIEWorkarounds || !__DEV__ it('should not warn when the style property differs on whitespace or order in IE', () => { document.documentMode = 11; jest.resetModules(); diff --git a/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js b/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js index 25aece64a073..71f9249a1e82 100644 --- a/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js +++ b/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js @@ -55,6 +55,7 @@ describe('dangerouslySetInnerHTML', () => { ); }); + // @gate !disableIEWorkarounds it('sets innerHTML on it', () => { const html = ''; const container = document.createElementNS( @@ -69,6 +70,7 @@ describe('dangerouslySetInnerHTML', () => { expect(circle.tagName).toBe('circle'); }); + // @gate !disableIEWorkarounds it('clears previous children', () => { const firstHtml = ''; const secondHtml = ''; diff --git a/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js b/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js index 7483d15e7fcc..777ef41756ce 100644 --- a/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js +++ b/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js @@ -208,6 +208,7 @@ describe('when Trusted Types are available in global object', () => { ); }); + // @gate !disableIEWorkarounds it('should log a warning', () => { class Component extends React.Component { render() { diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js index 1bba854339b9..c0e3c2eac0ad 100644 --- a/packages/shared/ReactFeatureFlags.js +++ b/packages/shared/ReactFeatureFlags.js @@ -169,6 +169,9 @@ export const enableTrustedTypesIntegration = false; // DOM properties export const disableInputAttributeSyncing = false; +// Remove IE and MsApp specific workarounds for innerHTML +export const disableIEWorkarounds = __EXPERIMENTAL__; + // Filter certain DOM attributes (e.g. src, href) if their values are empty // strings. This prevents e.g. from making an unnecessary HTTP // request for certain browsers. diff --git a/packages/shared/forks/ReactFeatureFlags.native-fb.js b/packages/shared/forks/ReactFeatureFlags.native-fb.js index 7482b84e7cf9..19ec4fc39750 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-fb.js +++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js @@ -36,6 +36,7 @@ export const debugRenderPhaseSideEffectsForStrictMode = true; export const disableJavaScriptURLs = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; +export const disableIEWorkarounds = true; export const replayFailedUnitOfWorkWithInvokeGuardedCallback = __DEV__; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js index 29259deed6ec..2c4b7993a6c3 100644 --- a/packages/shared/forks/ReactFeatureFlags.native-oss.js +++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js @@ -26,6 +26,7 @@ export const enableFetchInstrumentation = false; export const disableJavaScriptURLs = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; +export const disableIEWorkarounds = true; export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js index 2e0079d5eccf..1a1549a7d98e 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js @@ -26,6 +26,7 @@ export const enableFetchInstrumentation = true; export const disableJavaScriptURLs = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; +export const disableIEWorkarounds = true; export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js index 92f5a8ed4eda..e6dabd338bb2 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native.js @@ -26,6 +26,7 @@ export const enableFetchInstrumentation = false; export const disableJavaScriptURLs = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; +export const disableIEWorkarounds = true; export const enableSchedulerDebugging = false; export const enableScopeAPI = false; export const enableCreateEventHandleAPI = false; diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js index c3ccf711f766..dbd8b2ff69f3 100644 --- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js +++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js @@ -27,6 +27,7 @@ export const enableSchedulerDebugging = false; export const disableJavaScriptURLs = false; export const disableCommentsAsDOMContainers = true; export const disableInputAttributeSyncing = false; +export const disableIEWorkarounds = true; export const enableScopeAPI = true; export const enableCreateEventHandleAPI = false; export const enableSuspenseCallback = true; diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js index c754e1843070..53a293dab56f 100644 --- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js +++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js @@ -14,6 +14,7 @@ // with the __VARIANT__ set to `true`, and once set to `false`. export const disableInputAttributeSyncing = __VARIANT__; +export const disableIEWorkarounds = __VARIANT__; export const enableFilterEmptyStringAttributesDOM = __VARIANT__; export const enableLegacyFBSupport = __VARIANT__; export const skipUnmountedBoundaries = __VARIANT__; diff --git a/packages/shared/forks/ReactFeatureFlags.www.js b/packages/shared/forks/ReactFeatureFlags.www.js index aa247e2c23b5..4150dc9c8e90 100644 --- a/packages/shared/forks/ReactFeatureFlags.www.js +++ b/packages/shared/forks/ReactFeatureFlags.www.js @@ -16,6 +16,7 @@ const dynamicFeatureFlags: DynamicFeatureFlags = require('ReactFeatureFlags'); export const { disableInputAttributeSyncing, + disableIEWorkarounds, enableTrustedTypesIntegration, disableSchedulerTimeoutBasedOnReactExpirationTime, replayFailedUnitOfWorkWithInvokeGuardedCallback,