diff --git a/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js b/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js
index cd1d055c09d..63baa38c710 100644
--- a/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMAttribute-test.js
@@ -171,7 +171,13 @@ describe('ReactDOM unknown attribute', () => {
const test = () =>
testUnknownAttributeAssignment(new TemporalLike(), null);
- await expect(test).rejects.toThrowError(new TypeError('prod message'));
+ if (gate('enableTrustedTypesIntegration') && !__DEV__) {
+ // TODO: this still throws in DEV even though it's not toString'd in prod.
+ await expect(test).rejects.toThrowError('2020-01-01');
+ } else {
+ await expect(test).rejects.toThrowError(new TypeError('prod message'));
+ }
+
assertConsoleErrorDev([
'The provided `unknown` attribute is an unsupported type TemporalLike.' +
' This value must be coerced to a string before using it here.\n' +
diff --git a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js
index ed3d3e08805..e2065efa69c 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFloat-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFloat-test.js
@@ -608,6 +608,14 @@ describe('ReactDOMFloat', () => {
'> ');
+ if (gate('enableTrustedTypesIntegration')) {
+ assertConsoleErrorDev([
+ 'Encountered a script tag while rendering React component. ' +
+ 'Scripts inside React components are never executed when rendering on the client. ' +
+ 'Consider using template tag instead (https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).\n' +
+ ' in script (at **)\n' +
+ ' in TogglingComponent (at **)',
+ ]);
+ }
+
const container2 = document.createElement('div');
const root2 = ReactDOMClient.createRoot(container2);
expect(() => {
@@ -189,6 +202,7 @@ describe('ReactEmptyComponent', () => {
'mount SCRIPT',
'update undefined',
]);
+ expect(container2.innerHTML).toBe('');
});
it(
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 5a43a9ec2f0..06744581ae9 100644
--- a/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js
+++ b/packages/react-dom/src/client/__tests__/trustedTypes-test.internal.js
@@ -12,7 +12,6 @@
describe('when Trusted Types are available in global object', () => {
let React;
let ReactDOMClient;
- let ReactFeatureFlags;
let act;
let assertConsoleErrorDev;
let container;
@@ -33,8 +32,6 @@ describe('when Trusted Types are available in global object', () => {
isScript: () => false,
isScriptURL: () => false,
};
- ReactFeatureFlags = require('shared/ReactFeatureFlags');
- ReactFeatureFlags.enableTrustedTypesIntegration = true;
React = require('react');
ReactDOMClient = require('react-dom/client');
({act, assertConsoleErrorDev} = require('internal-test-utils'));
@@ -118,7 +115,11 @@ describe('when Trusted Types are available in global object', () => {
expect(setAttributeCalls[0][0]).toBe(container.firstChild);
expect(setAttributeCalls[0][1]).toBe('data-foo');
// Ensure it didn't get stringified when passed to a DOM sink:
- expect(setAttributeCalls[0][2]).toBe(ttObject1);
+ if (gate('enableTrustedTypesIntegration')) {
+ expect(setAttributeCalls[0][2]).toBe(ttObject1);
+ } else {
+ expect(setAttributeCalls[0][2]).toBe('Hi');
+ }
setAttributeCalls.length = 0;
await act(() => {
@@ -129,7 +130,11 @@ describe('when Trusted Types are available in global object', () => {
expect(setAttributeCalls[0][0]).toBe(container.firstChild);
expect(setAttributeCalls[0][1]).toBe('data-foo');
// Ensure it didn't get stringified when passed to a DOM sink:
- expect(setAttributeCalls[0][2]).toBe(ttObject2);
+ if (gate('enableTrustedTypesIntegration')) {
+ expect(setAttributeCalls[0][2]).toBe(ttObject2);
+ } else {
+ expect(setAttributeCalls[0][2]).toBe('Bye');
+ }
} finally {
Element.prototype.setAttribute = setAttribute;
}
@@ -153,7 +158,11 @@ describe('when Trusted Types are available in global object', () => {
expect(setAttributeCalls[0][0]).toBe(container.firstChild);
expect(setAttributeCalls[0][1]).toBe('class');
// Ensure it didn't get stringified when passed to a DOM sink:
- expect(setAttributeCalls[0][2]).toBe(ttObject1);
+ if (gate('enableTrustedTypesIntegration')) {
+ expect(setAttributeCalls[0][2]).toBe(ttObject1);
+ } else {
+ expect(setAttributeCalls[0][2]).toBe('Hi');
+ }
setAttributeCalls.length = 0;
await act(() => {
@@ -164,7 +173,11 @@ describe('when Trusted Types are available in global object', () => {
expect(setAttributeCalls[0][0]).toBe(container.firstChild);
expect(setAttributeCalls[0][1]).toBe('class');
// Ensure it didn't get stringified when passed to a DOM sink:
- expect(setAttributeCalls[0][2]).toBe(ttObject2);
+ if (gate('enableTrustedTypesIntegration')) {
+ expect(setAttributeCalls[0][2]).toBe(ttObject2);
+ } else {
+ expect(setAttributeCalls[0][2]).toBe('Bye');
+ }
} finally {
Element.prototype.setAttribute = setAttribute;
}
@@ -189,7 +202,11 @@ describe('when Trusted Types are available in global object', () => {
expect(setAttributeNSCalls[0][1]).toBe('http://www.w3.org/1999/xlink');
expect(setAttributeNSCalls[0][2]).toBe('xlink:href');
// Ensure it didn't get stringified when passed to a DOM sink:
- expect(setAttributeNSCalls[0][3]).toBe(ttObject1);
+ if (gate('enableTrustedTypesIntegration')) {
+ expect(setAttributeNSCalls[0][3]).toBe(ttObject1);
+ } else {
+ expect(setAttributeNSCalls[0][3]).toBe('Hi');
+ }
setAttributeNSCalls.length = 0;
await act(() => {
@@ -201,7 +218,11 @@ describe('when Trusted Types are available in global object', () => {
expect(setAttributeNSCalls[0][1]).toBe('http://www.w3.org/1999/xlink');
expect(setAttributeNSCalls[0][2]).toBe('xlink:href');
// Ensure it didn't get stringified when passed to a DOM sink:
- expect(setAttributeNSCalls[0][3]).toBe(ttObject2);
+ if (gate('enableTrustedTypesIntegration')) {
+ expect(setAttributeNSCalls[0][3]).toBe(ttObject2);
+ } else {
+ expect(setAttributeNSCalls[0][3]).toBe('Bye');
+ }
} finally {
Element.prototype.setAttributeNS = setAttributeNS;
}
@@ -212,13 +233,15 @@ describe('when Trusted Types are available in global object', () => {
await act(() => {
root.render();
});
- assertConsoleErrorDev([
- 'Encountered a script tag while rendering React component. ' +
- 'Scripts inside React components are never executed when rendering ' +
- 'on the client. Consider using template tag instead ' +
- '(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).\n' +
- ' in script (at **)',
- ]);
+ if (gate('enableTrustedTypesIntegration')) {
+ assertConsoleErrorDev([
+ 'Encountered a script tag while rendering React component. ' +
+ 'Scripts inside React components are never executed when rendering ' +
+ 'on the client. Consider using template tag instead ' +
+ '(https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).\n' +
+ ' in script (at **)',
+ ]);
+ }
// check that the warning is printed only once
await act(() => {
diff --git a/packages/shared/CheckStringCoercion.js b/packages/shared/CheckStringCoercion.js
index a186d6755d9..0165d8b19c1 100644
--- a/packages/shared/CheckStringCoercion.js
+++ b/packages/shared/CheckStringCoercion.js
@@ -76,6 +76,8 @@ export function checkAttributeStringCoercion(
attributeName: string,
): void | string {
if (__DEV__) {
+ // TODO: for enableTrustedTypesIntegration we don't toString this
+ // so we shouldn't need the DEV warning.
if (willCoercionThrow(value)) {
console.error(
'The provided `%s` attribute is an unsupported type %s.' +
diff --git a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
index a8d829ee3e3..3a6c456c928 100644
--- a/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
+++ b/packages/shared/forks/ReactFeatureFlags.www-dynamic.js
@@ -35,12 +35,11 @@ export const enableScrollEndPolyfill: boolean = __VARIANT__;
export const enableFragmentRefs: boolean = __VARIANT__;
export const enableFragmentRefsScrollIntoView: boolean = __VARIANT__;
export const enableAsyncDebugInfo: boolean = __VARIANT__;
-
export const enableInternalInstanceMap: boolean = __VARIANT__;
+export const enableTrustedTypesIntegration: boolean = __VARIANT__;
// TODO: These flags are hard-coded to the default values used in open source.
// Update the tests so that they pass in either mode, then set these
// to __VARIANT__.
-export const enableTrustedTypesIntegration: boolean = false;
// You probably *don't* want to add more hardcoded ones.
// Instead, try to add them above with the __VARIANT__ value.