Skip to content

Commit

Permalink
Remove disableIEWorkarounds (#31756)
Browse files Browse the repository at this point in the history
Based off #31755

This is landed everywhere.
  • Loading branch information
rickhanlonii authored Dec 13, 2024
1 parent 17ca4b1 commit fb12845
Show file tree
Hide file tree
Showing 12 changed files with 17 additions and 255 deletions.
60 changes: 17 additions & 43 deletions packages/react-dom-bindings/src/client/ReactDOMComponent.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand All @@ -66,7 +64,6 @@ import {validateProperties as validateUnknownProperties} from '../shared/ReactDO
import sanitizeURL from '../shared/sanitizeURL';

import {
disableIEWorkarounds,
enableTrustedTypesIntegration,
enableFilterEmptyStringAttributesDOM,
} from 'shared/ReactFeatureFlags';
Expand All @@ -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) {
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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(
Expand Down
82 changes: 0 additions & 82 deletions packages/react-dom-bindings/src/client/setInnerHTML.js

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -27,73 +27,4 @@ describe('dangerouslySetInnerHTML', () => {
expect(container.firstChild.innerHTML).toBe('<h1>Hello</h1>');
});
});

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 = '<circle></circle>';
const container = document.createElementNS(
'http://www.w3.org/2000/svg',
'svg',
);
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(<g dangerouslySetInnerHTML={{__html: html}} />);
});
const circle = container.firstChild.firstChild;
expect(circle.tagName).toBe('circle');
});

// @gate !disableIEWorkarounds
it('clears previous children', async () => {
const firstHtml = '<rect></rect>';
const secondHtml = '<circle></circle>';

const container = document.createElementNS(
'http://www.w3.org/2000/svg',
'svg',
);
const root = ReactDOMClient.createRoot(container);
await act(() => {
root.render(<g dangerouslySetInnerHTML={{__html: firstHtml}} />);
});
const rect = container.firstChild.firstChild;
expect(rect.tagName).toBe('rect');
await act(() => {
root.render(<g dangerouslySetInnerHTML={{__html: secondHtml}} />);
});
const circle = container.firstChild.firstChild;
expect(circle.tagName).toBe('circle');
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -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 <svg dangerouslySetInnerHTML={{__html: 'unsafe html'}} />;
}
}
const root = ReactDOMClient.createRoot(container);
await expect(async () => {
await act(() => {
root.render(<Component />);
});
}).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('<svg>unsafe html</svg>');
});
});

it('should warn once when rendering script tag in jsx on client', async () => {
const root = ReactDOMClient.createRoot(container);
await expect(async () => {
Expand Down
4 changes: 0 additions & 4 deletions packages/shared/ReactFeatureFlags.js
Original file line number Diff line number Diff line change
Expand Up @@ -203,10 +203,6 @@ export const disableLegacyContextForFunctionComponents = true;
// TODO: clean up legacy <StrictMode /> 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. <img src=""> from making an unnecessary HTTP
// request for certain browsers.
Expand Down
1 change: 0 additions & 1 deletion packages/shared/forks/ReactFeatureFlags.native-fb.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion packages/shared/forks/ReactFeatureFlags.native-oss.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion packages/shared/forks/ReactFeatureFlags.test-renderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion packages/shared/forks/ReactFeatureFlags.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 0 additions & 1 deletion scripts/jest/setupTests.www.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit fb12845

Please sign in to comment.