From bc2588022f49f9ab146a863006c063ea0b580437 Mon Sep 17 00:00:00 2001
From: Henrique Limas
Date: Wed, 24 May 2023 08:18:57 -0700
Subject: [PATCH 1/2] Add support for 'crossorigin' attribute on
bootstrapScripts and bootstrapModules
---
.../src/server/ReactFizzConfigDOM.js | 18 ++++++
.../src/__tests__/ReactDOMFizzServer-test.js | 58 +++++++++++++++++++
2 files changed, 76 insertions(+)
diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
index 5314564242ed9..fee7eecc1a642 100644
--- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
@@ -163,6 +163,7 @@ const startScriptSrc = stringToPrecomputedChunk('');
/**
@@ -192,6 +193,7 @@ const scriptReplacer = (
export type BootstrapScriptDescriptor = {
src: string,
integrity?: string,
+ crossOrigin?: string,
};
export type ExternalRuntimeScript = {
src: string,
@@ -265,6 +267,8 @@ export function createResponseState(
typeof scriptConfig === 'string' ? scriptConfig : scriptConfig.src;
const integrity =
typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity;
+ const crossOrigin =
+ typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin;
bootstrapChunks.push(
startScriptSrc,
@@ -282,6 +286,12 @@ export function createResponseState(
stringToChunk(escapeTextForBrowser(integrity)),
);
}
+ if (crossOrigin) {
+ bootstrapChunks.push(
+ scriptCrossOrigin,
+ stringToChunk(escapeTextForBrowser(crossOrigin)),
+ );
+ }
bootstrapChunks.push(endAsyncScript);
}
}
@@ -292,6 +302,8 @@ export function createResponseState(
typeof scriptConfig === 'string' ? scriptConfig : scriptConfig.src;
const integrity =
typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity;
+ const crossOrigin =
+ typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin;
bootstrapChunks.push(
startModuleSrc,
@@ -310,6 +322,12 @@ export function createResponseState(
stringToChunk(escapeTextForBrowser(integrity)),
);
}
+ if (crossOrigin) {
+ bootstrapChunks.push(
+ scriptCrossOrigin,
+ stringToChunk(escapeTextForBrowser(crossOrigin)),
+ );
+ }
bootstrapChunks.push(endAsyncScript);
}
}
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
index 2bf48eae39b18..6e8e2477dd3c3 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
@@ -3777,6 +3777,64 @@ describe('ReactDOMFizzServer', () => {
]);
});
+ it('accepts a crossOrigin property for bootstrapScripts and bootstrapModules', async () => {
+ await act(() => {
+ const {pipe} = renderToPipeableStream(
+
+
+
+ hello world
+
+ ,
+ {
+ bootstrapScripts: [
+ 'foo',
+ {
+ src: 'bar',
+ },
+ {
+ src: 'baz',
+ crossOrigin: 'anonymous',
+ },
+ ],
+ bootstrapModules: [
+ 'quux',
+ {
+ src: 'corge',
+ },
+ {
+ src: 'grault',
+ crossOrigin: 'use-credentials',
+ },
+ ],
+ },
+ );
+ pipe(writable);
+ });
+
+ expect(getVisibleChildren(document)).toEqual(
+
+
+ hello world
+
+ ,
+ );
+ expect(
+ stripExternalRuntimeInNodes(
+ document.getElementsByTagName('script'),
+ renderOptions.unstable_externalRuntimeSrc,
+ ).map(n => n.outerHTML),
+ ).toEqual([
+ '',
+ '',
+ '',
+ '',
+ '',
+ '',
+ ]);
+ });
+
describe('bootstrapScriptContent escaping', () => {
it('the "S" in "?[Ss]cript" strings are replaced with unicode escaped lowercase s or S depending on case, preserving case sensitivity of nearby characters', async () => {
window.__test_outlet = '';
From 08774ccd3ecb5b68344a6fc497a514da1b5806a7 Mon Sep 17 00:00:00 2001
From: Henrique Limas
Date: Wed, 31 May 2023 20:36:31 -0700
Subject: [PATCH 2/2] Limit crossOrigin value usage
---
.../src/server/ReactFizzConfigDOM.js | 16 ++++++++++++----
.../src/__tests__/ReactDOMFizzServer-test.js | 9 +++++++--
2 files changed, 19 insertions(+), 6 deletions(-)
diff --git a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
index fee7eecc1a642..b74492102158d 100644
--- a/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
+++ b/packages/react-dom-bindings/src/server/ReactFizzConfigDOM.js
@@ -268,7 +268,11 @@ export function createResponseState(
const integrity =
typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity;
const crossOrigin =
- typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin;
+ typeof scriptConfig === 'string' || scriptConfig.crossOrigin == null
+ ? undefined
+ : scriptConfig.crossOrigin === 'use-credentials'
+ ? 'use-credentials'
+ : '';
bootstrapChunks.push(
startScriptSrc,
@@ -286,7 +290,7 @@ export function createResponseState(
stringToChunk(escapeTextForBrowser(integrity)),
);
}
- if (crossOrigin) {
+ if (typeof crossOrigin === 'string') {
bootstrapChunks.push(
scriptCrossOrigin,
stringToChunk(escapeTextForBrowser(crossOrigin)),
@@ -303,7 +307,11 @@ export function createResponseState(
const integrity =
typeof scriptConfig === 'string' ? undefined : scriptConfig.integrity;
const crossOrigin =
- typeof scriptConfig === 'string' ? undefined : scriptConfig.crossOrigin;
+ typeof scriptConfig === 'string' || scriptConfig.crossOrigin == null
+ ? undefined
+ : scriptConfig.crossOrigin === 'use-credentials'
+ ? 'use-credentials'
+ : '';
bootstrapChunks.push(
startModuleSrc,
@@ -322,7 +330,7 @@ export function createResponseState(
stringToChunk(escapeTextForBrowser(integrity)),
);
}
- if (crossOrigin) {
+ if (typeof crossOrigin === 'string') {
bootstrapChunks.push(
scriptCrossOrigin,
stringToChunk(escapeTextForBrowser(crossOrigin)),
diff --git a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
index 6e8e2477dd3c3..be4a2353a1077 100644
--- a/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
+++ b/packages/react-dom/src/__tests__/ReactDOMFizzServer-test.js
@@ -3794,7 +3794,11 @@ describe('ReactDOMFizzServer', () => {
},
{
src: 'baz',
- crossOrigin: 'anonymous',
+ crossOrigin: '',
+ },
+ {
+ src: 'qux',
+ crossOrigin: 'defaults-to-empty',
},
],
bootstrapModules: [
@@ -3828,7 +3832,8 @@ describe('ReactDOMFizzServer', () => {
).toEqual([
'',
'',
- '',
+ '',
+ '',
'',
'',
'',