Skip to content

Commit a8dc53b

Browse files
committed
unify resource opt-out semantics and improve warnings
1 parent 49b6b62 commit a8dc53b

File tree

4 files changed

+257
-226
lines changed

4 files changed

+257
-226
lines changed

packages/react-dom-bindings/src/client/ReactDOMHostConfig.js

Lines changed: 65 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1596,51 +1596,60 @@ export function isHostHoistableType(
15961596
namespace = hostContextProd;
15971597
}
15981598
switch (type) {
1599-
case 'meta': {
1600-
return true;
1601-
}
1599+
case 'meta':
16021600
case 'title': {
16031601
return namespace !== SVG_NAMESPACE;
16041602
}
16051603
case 'style': {
1606-
if (__DEV__) {
1607-
if (outsideHostContainerContext) {
1608-
console.error(
1609-
'Cannot render a <style> outside the main document without knowing its precedence and a unique href key.' +
1610-
' React can hoist and deduplicate <style> tags if you provide a `precedence` prop along with an `href` prop that' +
1611-
' does not conflic with the `href` values used in any other hoisted <style> or <link rel="stylesheet" ...> tags. ' +
1612-
' Note that hoisting <style> tags is considered an advanced feature that most will not use directly.' +
1613-
' Consider moving the <style> tag to the <head> or consider adding a `precedence="default"` and `href="some unique resource identifier"`, or move the <style>' +
1614-
' to the <style> tag.',
1615-
);
1604+
if (
1605+
typeof props.precedence !== 'string' ||
1606+
typeof props.href !== 'string' ||
1607+
props.href === '' ||
1608+
namespace === SVG_NAMESPACE
1609+
) {
1610+
if (__DEV__) {
1611+
if (outsideHostContainerContext) {
1612+
console.error(
1613+
'Cannot render a <style> outside the main document without knowing its precedence and a unique href key.' +
1614+
' React can hoist and deduplicate <style> tags if you provide a `precedence` prop along with an `href` prop that' +
1615+
' does not conflic with the `href` values used in any other hoisted <style> or <link rel="stylesheet" ...> tags. ' +
1616+
' Note that hoisting <style> tags is considered an advanced feature that most will not use directly.' +
1617+
' Consider moving the <style> tag to the <head> or consider adding a `precedence="default"` and `href="some unique resource identifier"`, or move the <style>' +
1618+
' to the <style> tag.',
1619+
);
1620+
}
16161621
}
1622+
return false;
16171623
}
1618-
return (
1619-
namespace !== SVG_NAMESPACE && typeof props.precedence === 'string'
1620-
);
1624+
return true;
16211625
}
16221626
case 'link': {
1623-
const {onLoad, onError, rel, href} = props;
16241627
if (
1625-
namespace === SVG_NAMESPACE ||
1626-
typeof rel !== 'string' ||
1627-
typeof href !== 'string' ||
1628-
href === '' ||
1629-
onLoad ||
1630-
onError
1628+
typeof props.rel !== 'string' ||
1629+
typeof props.href !== 'string' ||
1630+
props.href === '' ||
1631+
props.onLoad ||
1632+
props.onError ||
1633+
namespace === SVG_NAMESPACE
16311634
) {
16321635
if (__DEV__) {
1636+
if (
1637+
props.rel === 'stylesheet' &&
1638+
typeof props.precedence === 'string'
1639+
) {
1640+
validateLinkPropsForStyleResource(props);
1641+
}
16331642
if (outsideHostContainerContext) {
16341643
if (
1635-
typeof rel !== 'string' ||
1636-
typeof href !== 'string' ||
1637-
href === ''
1644+
typeof props.rel !== 'string' ||
1645+
typeof props.href !== 'string' ||
1646+
props.href === ''
16381647
) {
16391648
console.error(
16401649
'Cannot render a <link> outside the main document without a `rel` and `href` prop.' +
16411650
' Try adding a `rel` and/or `href` prop to this <link> or moving the link into the <head> tag',
16421651
);
1643-
} else if (onError || onLoad) {
1652+
} else if (props.onError || props.onLoad) {
16441653
console.error(
16451654
'Cannot render a <link> with onLoad or onError listeners outside the main document.' +
16461655
' Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or' +
@@ -1655,7 +1664,6 @@ export function isHostHoistableType(
16551664
case 'stylesheet': {
16561665
const {precedence, disabled} = props;
16571666
if (__DEV__) {
1658-
validateLinkPropsForStyleResource(props);
16591667
if (typeof precedence !== 'string') {
16601668
if (outsideHostContainerContext) {
16611669
console.error(
@@ -1673,34 +1681,39 @@ export function isHostHoistableType(
16731681
}
16741682
}
16751683
case 'script': {
1676-
// We don't validate because it is valid to use async with onLoad/onError unlike combining
1677-
// precedence with these for style resources
1678-
const {src, async, onLoad, onError} = props;
1679-
if (__DEV__) {
1680-
if (async !== true) {
1681-
if (outsideHostContainerContext) {
1682-
console.error(
1683-
'Cannot render a sync or defer <script> outside the main document without knowing its order.' +
1684-
' Try adding async="" or moving it into the root <head> tag.',
1685-
);
1686-
}
1687-
} else if (onLoad || onError) {
1684+
if (
1685+
props.async !== true ||
1686+
props.onLoad ||
1687+
props.onError ||
1688+
typeof props.src !== 'string' ||
1689+
!props.src ||
1690+
namespace === SVG_NAMESPACE
1691+
) {
1692+
if (__DEV__) {
16881693
if (outsideHostContainerContext) {
1689-
console.error(
1690-
'Cannot render a <script> with onLoad or onError listeners outside the main document.' +
1691-
' Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or' +
1692-
' somewhere in the <body>.',
1693-
);
1694+
if (props.async !== true) {
1695+
console.error(
1696+
'Cannot render a sync or defer <script> outside the main document without knowing its order.' +
1697+
' Try adding async="" or moving it into the root <head> tag.',
1698+
);
1699+
} else if (props.onLoad || props.onError) {
1700+
console.error(
1701+
'Cannot render a <script> with onLoad or onError listeners outside the main document.' +
1702+
' Try removing onLoad={...} and onError={...} or moving it into the root <head> tag or' +
1703+
' somewhere in the <body>.',
1704+
);
1705+
} else {
1706+
console.error(
1707+
'Cannot render a <script> outside the main document without `async={true}` and a non-empty `src` prop.' +
1708+
' Ensure there is a valid `src` and either make the script async or move it into the root <head> tag or' +
1709+
' somewhere in the <body>.',
1710+
);
1711+
}
16941712
}
16951713
}
1714+
return false;
16961715
}
1697-
return (
1698-
namespace !== SVG_NAMESPACE &&
1699-
(async: any) &&
1700-
typeof src === 'string' &&
1701-
!onLoad &&
1702-
!onError
1703-
);
1716+
return true;
17041717
}
17051718
case 'noscript':
17061719
case 'template': {

0 commit comments

Comments
 (0)