diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponent.js b/packages/react-dom-bindings/src/client/ReactDOMComponent.js
index 9f7b23026f758..ac95c91c596a8 100644
--- a/packages/react-dom-bindings/src/client/ReactDOMComponent.js
+++ b/packages/react-dom-bindings/src/client/ReactDOMComponent.js
@@ -16,7 +16,6 @@ import {
possibleRegistrationNames,
} from '../events/EventRegistry';
-import {canUseDOM} from 'shared/ExecutionEnvironment';
import {checkHtmlStringCoercion} from 'shared/CheckStringCoercion';
import {checkAttributeStringCoercion} from 'shared/CheckStringCoercion';
import {checkControlledValueProps} from '../shared/ReactControlledValuePropTypes';
@@ -50,7 +49,6 @@ import {
} from './ReactDOMTextarea';
import {validateTextNesting} from './validateDOMNesting';
import {track} from './inputValueTracking';
-import setInnerHTML from './setInnerHTML';
import setTextContent from './setTextContent';
import {
createDangerousStringForStyles,
@@ -66,7 +64,6 @@ import {validateProperties as validateUnknownProperties} from '../shared/ReactDO
import sanitizeURL from '../shared/sanitizeURL';
import {
- disableIEWorkarounds,
enableTrustedTypesIntegration,
enableFilterEmptyStringAttributesDOM,
} from 'shared/ReactFeatureFlags';
@@ -83,19 +80,8 @@ let didWarnFormActionTarget = false;
let didWarnFormActionMethod = false;
let didWarnForNewBooleanPropsWithEmptyValue: {[string]: boolean};
let didWarnPopoverTargetObject = false;
-let canDiffStyleForHydrationWarning;
if (__DEV__) {
didWarnForNewBooleanPropsWithEmptyValue = {};
- // IE 11 parses & normalizes the style attribute as opposed to other
- // browsers. It adds spaces and sorts the properties in some
- // non-alphabetical order. Handling that would require sorting CSS
- // properties in the client & server versions or applying
- // `expectedStyle` to a temporary DOM node to read its `style` attribute
- // 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 =
- disableIEWorkarounds || (canUseDOM && !document.documentMode);
}
function validatePropertiesInDevelopment(type: string, props: any) {
@@ -579,11 +565,7 @@ function setProp(
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.',
);
}
- if (disableIEWorkarounds) {
- domElement.innerHTML = nextHtml;
- } else {
- setInnerHTML(domElement, nextHtml);
- }
+ domElement.innerHTML = nextHtml;
}
}
break;
@@ -939,11 +921,7 @@ function setPropOnCustomElement(
'Can only set one of `children` or `props.dangerouslySetInnerHTML`.',
);
}
- if (disableIEWorkarounds) {
- domElement.innerHTML = nextHtml;
- } else {
- setInnerHTML(domElement, nextHtml);
- }
+ domElement.innerHTML = nextHtml;
}
}
break;
@@ -1931,27 +1909,23 @@ function diffHydratedStyles(
}
return;
}
- if (canDiffStyleForHydrationWarning) {
- // First we compare the string form and see if it's equivalent.
- // This lets us bail out on anything that used to pass in this form.
- // It also lets us compare anything that's not parsed by this browser.
- const clientValue = createDangerousStringForStyles(value);
- const serverValue = domElement.getAttribute('style');
+ // First we compare the string form and see if it's equivalent.
+ // This lets us bail out on anything that used to pass in this form.
+ // It also lets us compare anything that's not parsed by this browser.
+ const clientValue = createDangerousStringForStyles(value);
+ const serverValue = domElement.getAttribute('style');
- if (serverValue === clientValue) {
- return;
- }
- const normalizedClientValue =
- normalizeMarkupForTextOrAttribute(clientValue);
- const normalizedServerValue =
- normalizeMarkupForTextOrAttribute(serverValue);
- if (normalizedServerValue === normalizedClientValue) {
- return;
- }
-
- // Otherwise, we create the object from the DOM for the diff view.
- serverDifferences.style = getStylesObjectFromElement(domElement);
+ if (serverValue === clientValue) {
+ return;
+ }
+ const normalizedClientValue = normalizeMarkupForTextOrAttribute(clientValue);
+ const normalizedServerValue = normalizeMarkupForTextOrAttribute(serverValue);
+ if (normalizedServerValue === normalizedClientValue) {
+ return;
}
+
+ // Otherwise, we create the object from the DOM for the diff view.
+ serverDifferences.style = getStylesObjectFromElement(domElement);
}
function hydrateAttribute(
diff --git a/packages/react-dom-bindings/src/client/setInnerHTML.js b/packages/react-dom-bindings/src/client/setInnerHTML.js
deleted file mode 100644
index 5f0d630fd38b5..0000000000000
--- a/packages/react-dom-bindings/src/client/setInnerHTML.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/**
- * Copyright (c) Meta Platforms, Inc. and affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- *
- * @flow
- */
-
-/* globals MSApp */
-
-import {SVG_NAMESPACE} from './DOMNamespaces';
-import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
-
-// SVG temp container for IE lacking innerHTML
-let reusableSVGContainer: HTMLElement;
-
-function setInnerHTMLImpl(
- node: Element,
- html: {valueOf(): {toString(): string, ...}, ...},
-): void {
- if (node.namespaceURI === SVG_NAMESPACE) {
- if (__DEV__) {
- if (enableTrustedTypesIntegration) {
- // TODO: reconsider the text of this warning and when it should show
- // before enabling the feature flag.
- if (typeof trustedTypes !== 'undefined') {
- console.error(
- "Using 'dangerouslySetInnerHTML' in an svg element with " +
- 'Trusted Types enabled in an Internet Explorer will cause ' +
- 'the trusted value to be converted to string. Assigning string ' +
- "to 'innerHTML' will throw an error if Trusted Types are enforced. " +
- "You can try to wrap your svg element inside a div and use 'dangerouslySetInnerHTML' " +
- 'on the enclosing div instead.',
- );
- }
- }
- }
- if (!('innerHTML' in node)) {
- // IE does not have innerHTML for SVG nodes, so instead we inject the
- // new markup in a temp node and then move the child nodes across into
- // the target node
- reusableSVGContainer =
- reusableSVGContainer || document.createElement('div');
- reusableSVGContainer.innerHTML =
- '';
- const svgNode = reusableSVGContainer.firstChild;
- while (node.firstChild) {
- node.removeChild(node.firstChild);
- }
- // $FlowFixMe[incompatible-use]
- // $FlowFixMe[incompatible-type]
- while (svgNode.firstChild) {
- node.appendChild(svgNode.firstChild);
- }
- return;
- }
- }
- node.innerHTML = (html: any);
-}
-
-let setInnerHTML: (
- node: Element,
- html: {valueOf(): {toString(): string, ...}, ...},
-) => void = setInnerHTMLImpl;
-// $FlowFixMe[cannot-resolve-name]
-if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
- /**
- * Create a function which has 'unsafe' privileges (required by windows8 apps)
- */
- setInnerHTML = function (
- node: Element,
- html: {valueOf(): {toString(): string, ...}, ...},
- ): void {
- // $FlowFixMe[cannot-resolve-name]
- return MSApp.execUnsafeLocalFunction(function () {
- return setInnerHTMLImpl(node, html);
- });
- };
-}
-
-export default setInnerHTML;
diff --git a/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js b/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js
index 64b4c0b0f7c98..ccbd41c2f30ad 100644
--- a/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js
+++ b/packages/react-dom/src/client/__tests__/dangerouslySetInnerHTML-test.js
@@ -27,73 +27,4 @@ describe('dangerouslySetInnerHTML', () => {
expect(container.firstChild.innerHTML).toBe('
Hello
');
});
});
-
- describe('when the node does not have an innerHTML property', () => {
- let innerHTMLDescriptor;
-
- // In some versions of IE (TODO: which ones?) SVG nodes don't have
- // innerHTML. To simulate this, we will take it off the Element prototype
- // and put it onto the HTMLDivElement prototype. We expect that the logic
- // checks for existence of innerHTML on SVG, and if one doesn't exist, falls
- // back to using appendChild and removeChild.
-
- beforeEach(() => {
- innerHTMLDescriptor = Object.getOwnPropertyDescriptor(
- Element.prototype,
- 'innerHTML',
- );
- delete Element.prototype.innerHTML;
- Object.defineProperty(
- HTMLDivElement.prototype,
- 'innerHTML',
- innerHTMLDescriptor,
- );
- });
-
- afterEach(() => {
- delete HTMLDivElement.prototype.innerHTML;
- Object.defineProperty(
- Element.prototype,
- 'innerHTML',
- innerHTMLDescriptor,
- );
- });
-
- // @gate !disableIEWorkarounds
- it('sets innerHTML on it', async () => {
- const html = '';
- const container = document.createElementNS(
- 'http://www.w3.org/2000/svg',
- 'svg',
- );
- const root = ReactDOMClient.createRoot(container);
- await act(() => {
- root.render();
- });
- const circle = container.firstChild.firstChild;
- expect(circle.tagName).toBe('circle');
- });
-
- // @gate !disableIEWorkarounds
- it('clears previous children', async () => {
- const firstHtml = '';
- const secondHtml = '';
-
- const container = document.createElementNS(
- 'http://www.w3.org/2000/svg',
- 'svg',
- );
- const root = ReactDOMClient.createRoot(container);
- await act(() => {
- root.render();
- });
- const rect = container.firstChild.firstChild;
- expect(rect.tagName).toBe('rect');
- await act(() => {
- root.render();
- });
- const circle = container.firstChild.firstChild;
- expect(circle.tagName).toBe('circle');
- });
- });
});
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 abe707badd5ee..923ee1f5d81a6 100644
--- a/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js
+++ b/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js
@@ -206,56 +206,6 @@ describe('when Trusted Types are available in global object', () => {
}
});
- describe('dangerouslySetInnerHTML in svg elements in Internet Explorer', () => {
- let innerHTMLDescriptor;
-
- // simulate svg elements in Internet Explorer which don't have 'innerHTML' property
- beforeEach(() => {
- innerHTMLDescriptor = Object.getOwnPropertyDescriptor(
- Element.prototype,
- 'innerHTML',
- );
- delete Element.prototype.innerHTML;
- Object.defineProperty(
- HTMLDivElement.prototype,
- 'innerHTML',
- innerHTMLDescriptor,
- );
- });
-
- afterEach(() => {
- delete HTMLDivElement.prototype.innerHTML;
- Object.defineProperty(
- Element.prototype,
- 'innerHTML',
- innerHTMLDescriptor,
- );
- });
-
- // @gate !disableIEWorkarounds
- it('should log a warning', async () => {
- class Component extends React.Component {
- render() {
- return ;
- }
- }
- const root = ReactDOMClient.createRoot(container);
- await expect(async () => {
- await act(() => {
- root.render();
- });
- }).toErrorDev(
- "Using 'dangerouslySetInnerHTML' in an svg element with " +
- 'Trusted Types enabled in an Internet Explorer will cause ' +
- 'the trusted value to be converted to string. Assigning string ' +
- "to 'innerHTML' will throw an error if Trusted Types are enforced. " +
- "You can try to wrap your svg element inside a div and use 'dangerouslySetInnerHTML' " +
- 'on the enclosing div instead.',
- );
- expect(container.innerHTML).toBe('');
- });
- });
-
it('should warn once when rendering script tag in jsx on client', async () => {
const root = ReactDOMClient.createRoot(container);
await expect(async () => {
diff --git a/packages/shared/ReactFeatureFlags.js b/packages/shared/ReactFeatureFlags.js
index f8aadb9789406..edaf4b2419136 100644
--- a/packages/shared/ReactFeatureFlags.js
+++ b/packages/shared/ReactFeatureFlags.js
@@ -203,10 +203,6 @@ export const disableLegacyContextForFunctionComponents = true;
// TODO: clean up legacy once tests pass WWW.
export const useModernStrictMode = true;
-// Not ready to break experimental yet.
-// Remove IE and MsApp specific workarounds for innerHTML
-export const disableIEWorkarounds = true;
-
// 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 37991d4c8ffbd..1ecbcfe28f5ce 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-fb.js
@@ -36,7 +36,6 @@ export const debugRenderPhaseSideEffectsForStrictMode = __DEV__;
export const disableClientCache = true;
export const disableCommentsAsDOMContainers = true;
export const disableDefaultPropsExceptForClasses = true;
-export const disableIEWorkarounds = true;
export const disableInputAttributeSyncing = false;
export const disableLegacyContext = false;
export const disableLegacyContextForFunctionComponents = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.native-oss.js b/packages/shared/forks/ReactFeatureFlags.native-oss.js
index eb40dc9123752..0d97b0b68d263 100644
--- a/packages/shared/forks/ReactFeatureFlags.native-oss.js
+++ b/packages/shared/forks/ReactFeatureFlags.native-oss.js
@@ -23,7 +23,6 @@ export const alwaysThrottleRetries = false;
export const disableClientCache = true;
export const disableCommentsAsDOMContainers = true;
export const disableDefaultPropsExceptForClasses = true;
-export const disableIEWorkarounds = true;
export const disableInputAttributeSyncing = false;
export const disableLegacyContext = true;
export const disableLegacyContextForFunctionComponents = true;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
index 6673d056d9a09..28f96fb84e6bc 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.js
@@ -29,7 +29,6 @@ export const enablePostpone = false;
export const enableHalt = false;
export const disableCommentsAsDOMContainers = true;
export const disableInputAttributeSyncing = false;
-export const disableIEWorkarounds = true;
export const enableScopeAPI = false;
export const enableCreateEventHandleAPI = false;
export const enableSuspenseCallback = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
index 3ac86950277d4..fe3e2bd4813b8 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.native-fb.js
@@ -15,7 +15,6 @@ export const debugRenderPhaseSideEffectsForStrictMode = false;
export const disableClientCache = true;
export const disableCommentsAsDOMContainers = true;
export const disableDefaultPropsExceptForClasses = true;
-export const disableIEWorkarounds = true;
export const disableInputAttributeSyncing = false;
export const disableLegacyContext = false;
export const disableLegacyContextForFunctionComponents = false;
diff --git a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
index 8ebb4d0dbf8db..1badea3abf309 100644
--- a/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.test-renderer.www.js
@@ -29,7 +29,6 @@ export const enablePostpone = false;
export const enableHalt = 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.js b/packages/shared/forks/ReactFeatureFlags.www.js
index 7a5761932c820..2a432305635d3 100644
--- a/packages/shared/forks/ReactFeatureFlags.www.js
+++ b/packages/shared/forks/ReactFeatureFlags.www.js
@@ -53,7 +53,6 @@ export const enableFabricCompleteRootInCommitPhase = false;
export const enableSuspenseAvoidThisFallback = true;
export const enableSuspenseAvoidThisFallbackFizz = false;
-export const disableIEWorkarounds = true;
export const enableCPUSuspense = true;
export const enableUseMemoCacheHook = true;
export const enableUseEffectEventHook = true;
diff --git a/scripts/jest/setupTests.www.js b/scripts/jest/setupTests.www.js
index ba0ee287fd4bd..efee213861ca6 100644
--- a/scripts/jest/setupTests.www.js
+++ b/scripts/jest/setupTests.www.js
@@ -15,7 +15,6 @@ jest.mock('shared/ReactFeatureFlags', () => {
// These are hardcoded to true for the next release,
// but still run the tests against both variants until
// we remove the flag.
- actual.disableIEWorkarounds = __VARIANT__;
actual.disableClientCache = __VARIANT__;
return actual;