Skip to content

Commit 46a8f79

Browse files
committed
[Fizz] Fix children rendering in custom elements with enableCustomElementPropertySupport (#27511)
The `enableCustomElementPropertySupport` flag changes React's handling of custom elements in a way that is more useful that just treating every prop as an attribute. However when server rendering we have no choice but to serialize props as attributes. When this flag is on and React supports more prop types on the client like functions and objects the server implementation needs to be a bit more naunced in how it renders these components. With this flag on `false`, function, and object props are omitted entirely and `true` is normalized to `""`. There was a bug however in the implementation which caused children more complex than a single string to be omitted because it matched the object type filter. This change reorganizes the code a bit to put these filters in the default prop handline case, leaving children, style, and innerHTML to be handled via normal logic. fixes: #27286 DiffTrain build for [bb77852](bb77852)
1 parent 9b5375d commit 46a8f79

9 files changed

Lines changed: 161 additions & 182 deletions

compiled/facebook-www/REVISION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1fc58281af73ca4507c41d53a3e08dc2038b0c1f
1+
bb778528d1ca22b44dad832f0258aaa4c0e6d4a4

compiled/facebook-www/ReactART-dev.modern.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ function _assertThisInitialized(self) {
6969
return self;
7070
}
7171

72-
var ReactVersion = "18.3.0-www-modern-5fb559f6";
72+
var ReactVersion = "18.3.0-www-modern-70e823a6";
7373

7474
var LegacyRoot = 0;
7575
var ConcurrentRoot = 1;

compiled/facebook-www/ReactART-prod.modern.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9780,7 +9780,7 @@ var slice = Array.prototype.slice,
97809780
return null;
97819781
},
97829782
bundleType: 0,
9783-
version: "18.3.0-www-modern-21a11200",
9783+
version: "18.3.0-www-modern-7f660f7a",
97849784
rendererPackageName: "react-art"
97859785
};
97869786
var internals$jscomp$inline_1286 = {
@@ -9811,7 +9811,7 @@ var internals$jscomp$inline_1286 = {
98119811
scheduleRoot: null,
98129812
setRefreshHandler: null,
98139813
getCurrentFiber: null,
9814-
reconcilerVersion: "18.3.0-www-modern-21a11200"
9814+
reconcilerVersion: "18.3.0-www-modern-7f660f7a"
98159815
};
98169816
if ("undefined" !== typeof __REACT_DEVTOOLS_GLOBAL_HOOK__) {
98179817
var hook$jscomp$inline_1287 = __REACT_DEVTOOLS_GLOBAL_HOOK__;

compiled/facebook-www/ReactDOMServer-dev.classic.js

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ if (__DEV__) {
1919
var React = require("react");
2020
var ReactDOM = require("react-dom");
2121

22-
var ReactVersion = "18.3.0-www-classic-0d5846ce";
22+
var ReactVersion = "18.3.0-www-classic-c2645119";
2323

2424
// This refers to a WWW module.
2525
var warningWWW = require("warning");
@@ -4715,29 +4715,7 @@ function pushStartCustomElement(target, props, tag) {
47154715
continue;
47164716
}
47174717

4718-
if (
4719-
enableCustomElementPropertySupport &&
4720-
(typeof propValue === "function" || typeof propValue === "object")
4721-
) {
4722-
// It is normal to render functions and objects on custom elements when
4723-
// client rendering, but when server rendering the output isn't useful,
4724-
// so skip it.
4725-
continue;
4726-
}
4727-
4728-
if (enableCustomElementPropertySupport && propValue === false) {
4729-
continue;
4730-
}
4731-
4732-
if (enableCustomElementPropertySupport && propValue === true) {
4733-
propValue = "";
4734-
}
4735-
4736-
if (enableCustomElementPropertySupport && propKey === "className") {
4737-
// className gets rendered as class on the client, so it should be
4738-
// rendered as class on the server.
4739-
propKey = "class";
4740-
}
4718+
var attributeName = propKey;
47414719

47424720
switch (propKey) {
47434721
case "children":
@@ -4757,15 +4735,34 @@ function pushStartCustomElement(target, props, tag) {
47574735
// Ignored. These are built-in to React on the client.
47584736
break;
47594737

4738+
case "className":
4739+
if (enableCustomElementPropertySupport) {
4740+
// className gets rendered as class on the client, so it should be
4741+
// rendered as class on the server.
4742+
attributeName = "class";
4743+
}
4744+
4745+
// intentional fallthrough
4746+
47604747
default:
47614748
if (
47624749
isAttributeNameSafe(propKey) &&
47634750
typeof propValue !== "function" &&
47644751
typeof propValue !== "symbol"
47654752
) {
4753+
if (enableCustomElementPropertySupport) {
4754+
if (propValue === false) {
4755+
continue;
4756+
} else if (propValue === true) {
4757+
propValue = "";
4758+
} else if (typeof propValue === "object") {
4759+
continue;
4760+
}
4761+
}
4762+
47664763
target.push(
47674764
attributeSeparator,
4768-
stringToChunk(propKey),
4765+
stringToChunk(attributeName),
47694766
attributeAssign,
47704767
stringToChunk(escapeTextForBrowser(propValue)),
47714768
attributeEnd

compiled/facebook-www/ReactDOMServer-dev.modern.js

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ if (__DEV__) {
1919
var React = require("react");
2020
var ReactDOM = require("react-dom");
2121

22-
var ReactVersion = "18.3.0-www-modern-5fb559f6";
22+
var ReactVersion = "18.3.0-www-modern-70e823a6";
2323

2424
// This refers to a WWW module.
2525
var warningWWW = require("warning");
@@ -4715,29 +4715,7 @@ function pushStartCustomElement(target, props, tag) {
47154715
continue;
47164716
}
47174717

4718-
if (
4719-
enableCustomElementPropertySupport &&
4720-
(typeof propValue === "function" || typeof propValue === "object")
4721-
) {
4722-
// It is normal to render functions and objects on custom elements when
4723-
// client rendering, but when server rendering the output isn't useful,
4724-
// so skip it.
4725-
continue;
4726-
}
4727-
4728-
if (enableCustomElementPropertySupport && propValue === false) {
4729-
continue;
4730-
}
4731-
4732-
if (enableCustomElementPropertySupport && propValue === true) {
4733-
propValue = "";
4734-
}
4735-
4736-
if (enableCustomElementPropertySupport && propKey === "className") {
4737-
// className gets rendered as class on the client, so it should be
4738-
// rendered as class on the server.
4739-
propKey = "class";
4740-
}
4718+
var attributeName = propKey;
47414719

47424720
switch (propKey) {
47434721
case "children":
@@ -4757,15 +4735,34 @@ function pushStartCustomElement(target, props, tag) {
47574735
// Ignored. These are built-in to React on the client.
47584736
break;
47594737

4738+
case "className":
4739+
if (enableCustomElementPropertySupport) {
4740+
// className gets rendered as class on the client, so it should be
4741+
// rendered as class on the server.
4742+
attributeName = "class";
4743+
}
4744+
4745+
// intentional fallthrough
4746+
47604747
default:
47614748
if (
47624749
isAttributeNameSafe(propKey) &&
47634750
typeof propValue !== "function" &&
47644751
typeof propValue !== "symbol"
47654752
) {
4753+
if (enableCustomElementPropertySupport) {
4754+
if (propValue === false) {
4755+
continue;
4756+
} else if (propValue === true) {
4757+
propValue = "";
4758+
} else if (typeof propValue === "object") {
4759+
continue;
4760+
}
4761+
}
4762+
47664763
target.push(
47674764
attributeSeparator,
4768-
stringToChunk(propKey),
4765+
stringToChunk(attributeName),
47694766
attributeAssign,
47704767
stringToChunk(escapeTextForBrowser(propValue)),
47714768
attributeEnd

compiled/facebook-www/ReactDOMServer-prod.classic.js

Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1527,25 +1527,9 @@ function pushStartInstance(
15271527
for (propKey$jscomp$9 in props)
15281528
if (hasOwnProperty.call(props, propKey$jscomp$9)) {
15291529
var propValue$jscomp$9 = props[propKey$jscomp$9];
1530-
if (
1531-
!(
1532-
null == propValue$jscomp$9 ||
1533-
(enableCustomElementPropertySupport &&
1534-
("function" === typeof propValue$jscomp$9 ||
1535-
"object" === typeof propValue$jscomp$9)) ||
1536-
(enableCustomElementPropertySupport &&
1537-
!1 === propValue$jscomp$9)
1538-
)
1539-
)
1540-
switch (
1541-
(enableCustomElementPropertySupport &&
1542-
!0 === propValue$jscomp$9 &&
1543-
(propValue$jscomp$9 = ""),
1544-
enableCustomElementPropertySupport &&
1545-
"className" === propKey$jscomp$9 &&
1546-
(propKey$jscomp$9 = "class"),
1547-
propKey$jscomp$9)
1548-
) {
1530+
if (null != propValue$jscomp$9) {
1531+
var attributeName = propKey$jscomp$9;
1532+
switch (propKey$jscomp$9) {
15491533
case "children":
15501534
children$jscomp$7 = propValue$jscomp$9;
15511535
break;
@@ -1558,18 +1542,30 @@ function pushStartInstance(
15581542
case "suppressContentEditableWarning":
15591543
case "suppressHydrationWarning":
15601544
break;
1545+
case "className":
1546+
enableCustomElementPropertySupport &&
1547+
(attributeName = "class");
15611548
default:
1562-
isAttributeNameSafe(propKey$jscomp$9) &&
1549+
if (
1550+
isAttributeNameSafe(propKey$jscomp$9) &&
15631551
"function" !== typeof propValue$jscomp$9 &&
1564-
"symbol" !== typeof propValue$jscomp$9 &&
1552+
"symbol" !== typeof propValue$jscomp$9
1553+
) {
1554+
if (enableCustomElementPropertySupport)
1555+
if (!1 === propValue$jscomp$9) continue;
1556+
else if (!0 === propValue$jscomp$9)
1557+
propValue$jscomp$9 = "";
1558+
else if ("object" === typeof propValue$jscomp$9) continue;
15651559
target$jscomp$0.push(
15661560
" ",
1567-
propKey$jscomp$9,
1561+
attributeName,
15681562
'="',
15691563
escapeTextForBrowser(propValue$jscomp$9),
15701564
'"'
15711565
);
1566+
}
15721567
}
1568+
}
15731569
}
15741570
target$jscomp$0.push(">");
15751571
pushInnerHTML(target$jscomp$0, innerHTML$jscomp$6, children$jscomp$7);
@@ -2291,24 +2287,24 @@ function hoistStylesheetDependency(stylesheet) {
22912287
function createRenderState(resumableState, generateStaticMarkup) {
22922288
var idPrefix = resumableState.idPrefix;
22932289
resumableState = idPrefix + "P:";
2294-
var JSCompiler_object_inline_segmentPrefix_1568 = idPrefix + "S:";
2290+
var JSCompiler_object_inline_segmentPrefix_1569 = idPrefix + "S:";
22952291
idPrefix += "B:";
2296-
var JSCompiler_object_inline_preconnects_1580 = new Set(),
2297-
JSCompiler_object_inline_fontPreloads_1581 = new Set(),
2298-
JSCompiler_object_inline_highImagePreloads_1582 = new Set(),
2299-
JSCompiler_object_inline_styles_1583 = new Map(),
2300-
JSCompiler_object_inline_bootstrapScripts_1584 = new Set(),
2301-
JSCompiler_object_inline_scripts_1585 = new Set(),
2302-
JSCompiler_object_inline_bulkPreloads_1586 = new Set(),
2303-
JSCompiler_object_inline_preloads_1587 = {
2292+
var JSCompiler_object_inline_preconnects_1581 = new Set(),
2293+
JSCompiler_object_inline_fontPreloads_1582 = new Set(),
2294+
JSCompiler_object_inline_highImagePreloads_1583 = new Set(),
2295+
JSCompiler_object_inline_styles_1584 = new Map(),
2296+
JSCompiler_object_inline_bootstrapScripts_1585 = new Set(),
2297+
JSCompiler_object_inline_scripts_1586 = new Set(),
2298+
JSCompiler_object_inline_bulkPreloads_1587 = new Set(),
2299+
JSCompiler_object_inline_preloads_1588 = {
23042300
images: new Map(),
23052301
stylesheets: new Map(),
23062302
scripts: new Map(),
23072303
moduleScripts: new Map()
23082304
};
23092305
return {
23102306
placeholderPrefix: resumableState,
2311-
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1568,
2307+
segmentPrefix: JSCompiler_object_inline_segmentPrefix_1569,
23122308
boundaryPrefix: idPrefix,
23132309
startInlineScript: "<script>",
23142310
htmlChunks: null,
@@ -2320,14 +2316,14 @@ function createRenderState(resumableState, generateStaticMarkup) {
23202316
importMapChunks: [],
23212317
preloadChunks: [],
23222318
hoistableChunks: [],
2323-
preconnects: JSCompiler_object_inline_preconnects_1580,
2324-
fontPreloads: JSCompiler_object_inline_fontPreloads_1581,
2325-
highImagePreloads: JSCompiler_object_inline_highImagePreloads_1582,
2326-
styles: JSCompiler_object_inline_styles_1583,
2327-
bootstrapScripts: JSCompiler_object_inline_bootstrapScripts_1584,
2328-
scripts: JSCompiler_object_inline_scripts_1585,
2329-
bulkPreloads: JSCompiler_object_inline_bulkPreloads_1586,
2330-
preloads: JSCompiler_object_inline_preloads_1587,
2319+
preconnects: JSCompiler_object_inline_preconnects_1581,
2320+
fontPreloads: JSCompiler_object_inline_fontPreloads_1582,
2321+
highImagePreloads: JSCompiler_object_inline_highImagePreloads_1583,
2322+
styles: JSCompiler_object_inline_styles_1584,
2323+
bootstrapScripts: JSCompiler_object_inline_bootstrapScripts_1585,
2324+
scripts: JSCompiler_object_inline_scripts_1586,
2325+
bulkPreloads: JSCompiler_object_inline_bulkPreloads_1587,
2326+
preloads: JSCompiler_object_inline_preloads_1588,
23312327
boundaryResources: null,
23322328
stylesToHoist: !1,
23332329
generateStaticMarkup: generateStaticMarkup
@@ -5050,4 +5046,4 @@ exports.renderToString = function (children, options) {
50505046
'The server used "renderToString" which does not support Suspense. If you intended for this Suspense boundary to render the fallback content on the server consider throwing an Error somewhere within the Suspense boundary. If you intended to have the server wait for the suspended component please switch to "renderToReadableStream" which supports Suspense on the server'
50515047
);
50525048
};
5053-
exports.version = "18.3.0-www-classic-959d060f";
5049+
exports.version = "18.3.0-www-classic-d1253dd4";

0 commit comments

Comments
 (0)