mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
This reverts commit 815ee89bf5.
This commit is contained in:
+92
-90
@@ -441,108 +441,110 @@ describe('ReactDOMComponent', () => {
|
||||
expect(node.hasAttribute('data-foo')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not add an empty src attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<img src="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the src attribute. ' +
|
||||
'This may cause the browser to download the whole page again over the network. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to src instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('src')).toBe(false);
|
||||
if (ReactFeatureFlags.enableFilterEmptyStringAttributesDOM) {
|
||||
it('should not add an empty src attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<img src="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the src attribute. ' +
|
||||
'This may cause the browser to download the whole page again over the network. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to src instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('src')).toBe(false);
|
||||
|
||||
ReactDOM.render(<img src="abc" />, container);
|
||||
expect(node.hasAttribute('src')).toBe(true);
|
||||
ReactDOM.render(<img src="abc" />, container);
|
||||
expect(node.hasAttribute('src')).toBe(true);
|
||||
|
||||
expect(() => ReactDOM.render(<img src="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the src attribute. ' +
|
||||
'This may cause the browser to download the whole page again over the network. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to src instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('src')).toBe(false);
|
||||
});
|
||||
expect(() => ReactDOM.render(<img src="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the src attribute. ' +
|
||||
'This may cause the browser to download the whole page again over the network. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to src instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('src')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not add an empty href attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<link href="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the href attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to href instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('href')).toBe(false);
|
||||
it('should not add an empty href attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<link href="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the href attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to href instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('href')).toBe(false);
|
||||
|
||||
ReactDOM.render(<link href="abc" />, container);
|
||||
expect(node.hasAttribute('href')).toBe(true);
|
||||
ReactDOM.render(<link href="abc" />, container);
|
||||
expect(node.hasAttribute('href')).toBe(true);
|
||||
|
||||
expect(() => ReactDOM.render(<link href="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the href attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to href instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('href')).toBe(false);
|
||||
});
|
||||
expect(() => ReactDOM.render(<link href="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the href attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to href instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('href')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not add an empty action attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<form action="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the action attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to action instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('action')).toBe(false);
|
||||
it('should not add an empty action attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() => ReactDOM.render(<form action="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the action attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to action instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('action')).toBe(false);
|
||||
|
||||
ReactDOM.render(<form action="abc" />, container);
|
||||
expect(node.hasAttribute('action')).toBe(true);
|
||||
ReactDOM.render(<form action="abc" />, container);
|
||||
expect(node.hasAttribute('action')).toBe(true);
|
||||
|
||||
expect(() => ReactDOM.render(<form action="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the action attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to action instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('action')).toBe(false);
|
||||
});
|
||||
expect(() => ReactDOM.render(<form action="" />, container)).toErrorDev(
|
||||
'An empty string ("") was passed to the action attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to action instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('action')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not add an empty formAction attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() =>
|
||||
ReactDOM.render(<button formAction="" />, container),
|
||||
).toErrorDev(
|
||||
'An empty string ("") was passed to the formAction attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to formAction instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('formAction')).toBe(false);
|
||||
it('should not add an empty formAction attribute', () => {
|
||||
const container = document.createElement('div');
|
||||
expect(() =>
|
||||
ReactDOM.render(<button formAction="" />, container),
|
||||
).toErrorDev(
|
||||
'An empty string ("") was passed to the formAction attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to formAction instead of an empty string.',
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('formAction')).toBe(false);
|
||||
|
||||
ReactDOM.render(<button formAction="abc" />, container);
|
||||
expect(node.hasAttribute('formAction')).toBe(true);
|
||||
ReactDOM.render(<button formAction="abc" />, container);
|
||||
expect(node.hasAttribute('formAction')).toBe(true);
|
||||
|
||||
expect(() =>
|
||||
ReactDOM.render(<button formAction="" />, container),
|
||||
).toErrorDev(
|
||||
'An empty string ("") was passed to the formAction attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to formAction instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('formAction')).toBe(false);
|
||||
});
|
||||
expect(() =>
|
||||
ReactDOM.render(<button formAction="" />, container),
|
||||
).toErrorDev(
|
||||
'An empty string ("") was passed to the formAction attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to formAction instead of an empty string.',
|
||||
);
|
||||
expect(node.hasAttribute('formAction')).toBe(false);
|
||||
});
|
||||
|
||||
it('should not filter attributes for custom elements', () => {
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(
|
||||
<some-custom-element action="" formAction="" href="" src="" />,
|
||||
container,
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('action')).toBe(true);
|
||||
expect(node.hasAttribute('formAction')).toBe(true);
|
||||
expect(node.hasAttribute('href')).toBe(true);
|
||||
expect(node.hasAttribute('src')).toBe(true);
|
||||
});
|
||||
it('should not filter attributes for custom elements', () => {
|
||||
const container = document.createElement('div');
|
||||
ReactDOM.render(
|
||||
<some-custom-element action="" formAction="" href="" src="" />,
|
||||
container,
|
||||
);
|
||||
const node = container.firstChild;
|
||||
expect(node.hasAttribute('action')).toBe(true);
|
||||
expect(node.hasAttribute('formAction')).toBe(true);
|
||||
expect(node.hasAttribute('href')).toBe(true);
|
||||
expect(node.hasAttribute('src')).toBe(true);
|
||||
});
|
||||
}
|
||||
|
||||
it('should apply React-specific aliases to HTML elements', () => {
|
||||
const container = document.createElement('div');
|
||||
|
||||
+26
-21
@@ -7,7 +7,10 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import {enableDeprecatedFlareAPI} from 'shared/ReactFeatureFlags';
|
||||
import {
|
||||
enableDeprecatedFlareAPI,
|
||||
enableFilterEmptyStringAttributesDOM,
|
||||
} from 'shared/ReactFeatureFlags';
|
||||
|
||||
type PropertyType = 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
||||
|
||||
@@ -164,28 +167,30 @@ export function shouldRemoveAttribute(
|
||||
return false;
|
||||
}
|
||||
if (propertyInfo !== null) {
|
||||
if (propertyInfo.removeEmptyString && value === '') {
|
||||
if (__DEV__) {
|
||||
if (name === 'src') {
|
||||
console.error(
|
||||
'An empty string ("") was passed to the %s attribute. ' +
|
||||
'This may cause the browser to download the whole page again over the network. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to %s instead of an empty string.',
|
||||
name,
|
||||
name,
|
||||
);
|
||||
} else {
|
||||
console.error(
|
||||
'An empty string ("") was passed to the %s attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to %s instead of an empty string.',
|
||||
name,
|
||||
name,
|
||||
);
|
||||
if (enableFilterEmptyStringAttributesDOM) {
|
||||
if (propertyInfo.removeEmptyString && value === '') {
|
||||
if (__DEV__) {
|
||||
if (name === 'src') {
|
||||
console.error(
|
||||
'An empty string ("") was passed to the %s attribute. ' +
|
||||
'This may cause the browser to download the whole page again over the network. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to %s instead of an empty string.',
|
||||
name,
|
||||
name,
|
||||
);
|
||||
} else {
|
||||
console.error(
|
||||
'An empty string ("") was passed to the %s attribute. ' +
|
||||
'To fix this, either do not render the element at all ' +
|
||||
'or pass null to %s instead of an empty string.',
|
||||
name,
|
||||
name,
|
||||
);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
switch (propertyInfo.type) {
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
* @flow strict
|
||||
*/
|
||||
|
||||
// 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.
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
|
||||
// Adds verbose console logging for e.g. state updates, suspense, and work loop stuff.
|
||||
// Intended to enable React core members to more easily debug scheduling issues in DEV builds.
|
||||
export const enableDebugTracing = false;
|
||||
|
||||
@@ -44,6 +44,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = false;
|
||||
export const enableLegacyFBSupport = false;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
export const disableOnScrollBubbling = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
|
||||
@@ -43,6 +43,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = false;
|
||||
export const enableLegacyFBSupport = false;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
export const disableOnScrollBubbling = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
|
||||
@@ -43,6 +43,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = true;
|
||||
export const enableLegacyFBSupport = false;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
export const disableOnScrollBubbling = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
|
||||
@@ -43,6 +43,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = false;
|
||||
export const enableLegacyFBSupport = false;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
export const deferRenderPhaseUpdateToNextBatch = true;
|
||||
|
||||
@@ -43,6 +43,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = true;
|
||||
export const enableLegacyFBSupport = false;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
export const disableOnScrollBubbling = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
|
||||
@@ -43,6 +43,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = true;
|
||||
export const enableLegacyFBSupport = false;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
export const disableOnScrollBubbling = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
|
||||
@@ -43,6 +43,7 @@ export const warnUnstableRenderSubtreeIntoContainer = false;
|
||||
export const warnAboutSpreadingKeyToJSX = false;
|
||||
export const enableComponentStackLocations = true;
|
||||
export const enableLegacyFBSupport = !__EXPERIMENTAL__;
|
||||
export const enableFilterEmptyStringAttributesDOM = false;
|
||||
export const disableOnScrollBubbling = false;
|
||||
|
||||
export const enableNewReconciler = false;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
|
||||
export const warnAboutSpreadingKeyToJSX = __VARIANT__;
|
||||
export const disableInputAttributeSyncing = __VARIANT__;
|
||||
export const enableFilterEmptyStringAttributesDOM = __VARIANT__;
|
||||
export const enableLegacyFBSupport = __VARIANT__;
|
||||
export const decoupleUpdatePriorityFromScheduler = __VARIANT__;
|
||||
export const disableOnScrollBubbling = __VARIANT__;
|
||||
|
||||
@@ -21,6 +21,7 @@ export const {
|
||||
disableSchedulerTimeoutBasedOnReactExpirationTime,
|
||||
warnAboutSpreadingKeyToJSX,
|
||||
replayFailedUnitOfWorkWithInvokeGuardedCallback,
|
||||
enableFilterEmptyStringAttributesDOM,
|
||||
enableLegacyFBSupport,
|
||||
deferRenderPhaseUpdateToNextBatch,
|
||||
decoupleUpdatePriorityFromScheduler,
|
||||
|
||||
Reference in New Issue
Block a user