Skip to content

Trying a few compat optimizations #3903

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 2, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions compat/src/render.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ export const REACT_ELEMENT_TYPE =
0xeac7;

const CAMEL_PROPS = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/;
const ON_ANI = /^on(Ani|Tra|Tou|BeforeInp|Compo)/;
const CAMEL_REPLACE = /[A-Z0-9]/g;

const IS_DOM = typeof document !== 'undefined';

Expand All @@ -19,8 +21,8 @@ const IS_DOM = typeof document !== 'undefined';
// (IE11 doesn't support Symbol, which we use here to turn `rad` into `ra` which matches "range")
const onChangeInputType = type =>
(typeof Symbol != 'undefined' && typeof Symbol() == 'symbol'
? /fil|che|rad/i
: /fil|che|ra/i
? /fil|che|rad/
: /fil|che|ra/
).test(type);

// Some libraries like `react-virtualized` explicitly check for this.
Expand Down Expand Up @@ -114,24 +116,23 @@ options.vnode = vnode => {

// only normalize props on Element nodes
if (typeof type === 'string') {
const nonCustomElement = type.indexOf('-') === -1;
normalizedProps = {};

for (let i in props) {
let value = props[i];

if (IS_DOM && i === 'children' && type === 'noscript') {
if (
(i === 'value' && 'defaultValue' in props && value == null) ||
// Emulate React's behavior of not rendering the contents of noscript tags on the client.
continue;
} else if (i === 'value' && 'defaultValue' in props && value == null) {
(IS_DOM && i === 'children' && type === 'noscript')
) {
// Skip applying value if it is null/undefined and we already set
// a default value
continue;
} else if (
i === 'defaultValue' &&
'value' in props &&
props.value == null
) {
}

let lowerCased = i.toLowerCase();
if (i === 'defaultValue' && 'value' in props && props.value == null) {
// `defaultValue` is treated as a fallback `value` when a value prop is present but null/undefined.
// `defaultValue` for Elements with no value prop is the same as the DOM defaultValue property.
i = 'value';
Expand All @@ -142,29 +143,30 @@ options.vnode = vnode => {
// value will be used as the file name and the file will be called
// "true" upon downloading it.
value = '';
} else if (/ondoubleclick/i.test(i)) {
} else if (lowerCased === 'ondoubleclick') {
i = 'ondblclick';
} else if (
/^onchange(textarea|input)/i.test(i + type) &&
lowerCased === 'onchange' &&
(type === 'input' || type === 'textarea') &&
!onChangeInputType(props.type)
) {
i = 'oninput';
} else if (/^onfocus$/i.test(i)) {
lowerCased = i = 'oninput';
} else if (lowerCased === 'onfocus') {
i = 'onfocusin';
} else if (/^onblur$/i.test(i)) {
} else if (lowerCased === 'onblur') {
i = 'onfocusout';
} else if (/^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(i)) {
i = i.toLowerCase();
} else if (nonCustomElement && CAMEL_PROPS.test(i)) {
i = i.replace(/[A-Z0-9]/g, '-$&').toLowerCase();
} else if (ON_ANI.test(i)) {
i = lowerCased;
} else if (type.indexOf('-') === -1 && CAMEL_PROPS.test(i)) {
i = i.replace(CAMEL_REPLACE, '-$&').toLowerCase();
} else if (value === null) {
value = undefined;
}

// Add support for onInput and onChange, see #3561
// if we have an oninput prop already change it to oninputCapture
if (/^oninput$/i.test(i)) {
i = i.toLowerCase();
if (lowerCased === 'oninput') {
i = lowerCased;
if (normalizedProps[i]) {
i = 'oninputCapture';
}
Expand Down