Avoid meta programming to initialize functions in module scope (#26388)
I'm trying to get rid of all meta programming in the module scope so that closure can do a better job figuring out cyclic dependencies and ability to reorder. This is converting a lot of the patterns that assign functions conditionally to using function declarations instead. ``` let fn; if (__DEV__) { fn = function() { ... }; } ``` -> ``` function fn() { if (__DEV__) { ... } } ```
This commit is contained in:
parent
21aee59e45
commit
d310d654a7
|
@ -13,7 +13,7 @@
|
|||
* Change environment support for PointerEvent.
|
||||
*/
|
||||
|
||||
const emptyFunction = function () {};
|
||||
function emptyFunction() {}
|
||||
|
||||
export function hasPointerEvent() {
|
||||
return global != null && global.PointerEvent != null;
|
||||
|
|
|
@ -94,15 +94,8 @@ const HTML = '__html';
|
|||
let warnedUnknownTags: {
|
||||
[key: string]: boolean,
|
||||
};
|
||||
|
||||
let validatePropertiesInDevelopment;
|
||||
let warnForPropDifference;
|
||||
let warnForExtraAttributes;
|
||||
let warnForInvalidEventListener;
|
||||
let canDiffStyleForHydrationWarning;
|
||||
|
||||
let normalizeHTML;
|
||||
|
||||
if (__DEV__) {
|
||||
warnedUnknownTags = {
|
||||
// There are working polyfills for <dialog>. Let people use it.
|
||||
|
@ -115,15 +108,6 @@ if (__DEV__) {
|
|||
webview: true,
|
||||
};
|
||||
|
||||
validatePropertiesInDevelopment = function (type: string, props: any) {
|
||||
validateARIAProperties(type, props);
|
||||
validateInputProperties(type, props);
|
||||
validateUnknownProperties(type, props, {
|
||||
registrationNameDependencies,
|
||||
possibleRegistrationNames,
|
||||
});
|
||||
};
|
||||
|
||||
// IE 11 parses & normalizes the style attribute as opposed to other
|
||||
// browsers. It adds spaces and sorts the properties in some
|
||||
// non-alphabetical order. Handling that would require sorting CSS
|
||||
|
@ -133,12 +117,25 @@ if (__DEV__) {
|
|||
// in that browser completely in favor of doing all that work.
|
||||
// See https://github.com/facebook/react/issues/11807
|
||||
canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
|
||||
}
|
||||
|
||||
warnForPropDifference = function (
|
||||
propName: string,
|
||||
serverValue: mixed,
|
||||
clientValue: mixed,
|
||||
) {
|
||||
function validatePropertiesInDevelopment(type: string, props: any) {
|
||||
if (__DEV__) {
|
||||
validateARIAProperties(type, props);
|
||||
validateInputProperties(type, props);
|
||||
validateUnknownProperties(type, props, {
|
||||
registrationNameDependencies,
|
||||
possibleRegistrationNames,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function warnForPropDifference(
|
||||
propName: string,
|
||||
serverValue: mixed,
|
||||
clientValue: mixed,
|
||||
) {
|
||||
if (__DEV__) {
|
||||
if (didWarnInvalidHydration) {
|
||||
return;
|
||||
}
|
||||
|
@ -156,9 +153,11 @@ if (__DEV__) {
|
|||
JSON.stringify(normalizedServerValue),
|
||||
JSON.stringify(normalizedClientValue),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
warnForExtraAttributes = function (attributeNames: Set<string>) {
|
||||
function warnForExtraAttributes(attributeNames: Set<string>) {
|
||||
if (__DEV__) {
|
||||
if (didWarnInvalidHydration) {
|
||||
return;
|
||||
}
|
||||
|
@ -168,12 +167,11 @@ if (__DEV__) {
|
|||
names.push(name);
|
||||
});
|
||||
console.error('Extra attributes from the server: %s', names);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
warnForInvalidEventListener = function (
|
||||
registrationName: string,
|
||||
listener: any,
|
||||
) {
|
||||
function warnForInvalidEventListener(registrationName: string, listener: any) {
|
||||
if (__DEV__) {
|
||||
if (listener === false) {
|
||||
console.error(
|
||||
'Expected `%s` listener to be a function, instead got `false`.\n\n' +
|
||||
|
@ -190,11 +188,13 @@ if (__DEV__) {
|
|||
typeof listener,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Parse the HTML and read it back to normalize the HTML string so that it
|
||||
// can be used for comparison.
|
||||
normalizeHTML = function (parent: Element, html: string) {
|
||||
// Parse the HTML and read it back to normalize the HTML string so that it
|
||||
// can be used for comparison.
|
||||
function normalizeHTML(parent: Element, html: string) {
|
||||
if (__DEV__) {
|
||||
// We could have created a separate document here to avoid
|
||||
// re-initializing custom elements if they exist. But this breaks
|
||||
// how <noscript> is being handled. So we use the same document.
|
||||
|
@ -208,7 +208,7 @@ if (__DEV__) {
|
|||
);
|
||||
testElement.innerHTML = html;
|
||||
return testElement.innerHTML;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// HTML parsing normalizes CR and CRLF to LF.
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
/* globals MSApp */
|
||||
|
||||
/**
|
||||
* Create a function which has 'unsafe' privileges (required by windows8 apps)
|
||||
*/
|
||||
const createMicrosoftUnsafeLocalFunction = function (func) {
|
||||
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
|
||||
return function (arg0, arg1, arg2, arg3) {
|
||||
MSApp.execUnsafeLocalFunction(function () {
|
||||
return func(arg0, arg1, arg2, arg3);
|
||||
});
|
||||
};
|
||||
} else {
|
||||
return func;
|
||||
}
|
||||
};
|
||||
|
||||
export default createMicrosoftUnsafeLocalFunction;
|
|
@ -7,24 +7,15 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
/* globals MSApp */
|
||||
|
||||
import {SVG_NAMESPACE} from './DOMNamespaces';
|
||||
import createMicrosoftUnsafeLocalFunction from './createMicrosoftUnsafeLocalFunction';
|
||||
import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
|
||||
|
||||
// SVG temp container for IE lacking innerHTML
|
||||
let reusableSVGContainer: HTMLElement;
|
||||
|
||||
/**
|
||||
* Set the innerHTML property of a node
|
||||
*
|
||||
* @param {DOMElement} node
|
||||
* @param {string} html
|
||||
* @internal
|
||||
*/
|
||||
const setInnerHTML: (
|
||||
node: Element,
|
||||
html: {valueOf(): {toString(): string, ...}, ...},
|
||||
) => void = createMicrosoftUnsafeLocalFunction(function (
|
||||
function setInnerHTMLImpl(
|
||||
node: Element,
|
||||
html: {valueOf(): {toString(): string, ...}, ...},
|
||||
): void {
|
||||
|
@ -66,6 +57,26 @@ const setInnerHTML: (
|
|||
}
|
||||
}
|
||||
node.innerHTML = (html: any);
|
||||
});
|
||||
}
|
||||
|
||||
let setInnerHTML: (
|
||||
node: Element,
|
||||
html: {valueOf(): {toString(): string, ...}, ...},
|
||||
) => void = setInnerHTMLImpl;
|
||||
// $FlowFixMe[cannot-resolve-name]
|
||||
if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
|
||||
/**
|
||||
* Create a function which has 'unsafe' privileges (required by windows8 apps)
|
||||
*/
|
||||
setInnerHTML = function (
|
||||
node: Element,
|
||||
html: {valueOf(): {toString(): string, ...}, ...},
|
||||
): void {
|
||||
// $FlowFixMe[cannot-resolve-name]
|
||||
return MSApp.execUnsafeLocalFunction(function () {
|
||||
return setInnerHTMLImpl(node, html);
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
export default setInnerHTML;
|
||||
|
|
|
@ -18,7 +18,7 @@ import {TEXT_NODE} from './HTMLNodeType';
|
|||
* @param {string} text
|
||||
* @internal
|
||||
*/
|
||||
const setTextContent = function (node: Element, text: string): void {
|
||||
function setTextContent(node: Element, text: string): void {
|
||||
if (text) {
|
||||
const firstChild = node.firstChild;
|
||||
|
||||
|
@ -32,6 +32,6 @@ const setTextContent = function (node: Element, text: string): void {
|
|||
}
|
||||
}
|
||||
node.textContent = text;
|
||||
};
|
||||
}
|
||||
|
||||
export default setTextContent;
|
||||
|
|
|
@ -7,12 +7,6 @@
|
|||
* @flow
|
||||
*/
|
||||
|
||||
type ValidateDOMNesting = (?string, ?string, AncestorInfoDev) => void;
|
||||
let validateDOMNesting: ValidateDOMNesting = (() => {}: any);
|
||||
|
||||
type UpdatedAncestorInfoDev = (?AncestorInfoDev, string) => AncestorInfoDev;
|
||||
let updatedAncestorInfoDev: UpdatedAncestorInfoDev = (() => {}: any);
|
||||
|
||||
type Info = {tag: string};
|
||||
export type AncestorInfoDev = {
|
||||
current: ?Info,
|
||||
|
@ -30,156 +24,159 @@ export type AncestorInfoDev = {
|
|||
containerTagInScope: ?Info,
|
||||
};
|
||||
|
||||
if (__DEV__) {
|
||||
// This validation code was written based on the HTML5 parsing spec:
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
|
||||
//
|
||||
// Note: this does not catch all invalid nesting, nor does it try to (as it's
|
||||
// not clear what practical benefit doing so provides); instead, we warn only
|
||||
// for cases where the parser will give a parse tree differing from what React
|
||||
// intended. For example, <b><div></div></b> is invalid but we don't warn
|
||||
// because it still parses correctly; we do warn for other cases like nested
|
||||
// <p> tags where the beginning of the second element implicitly closes the
|
||||
// first, causing a confusing mess.
|
||||
// This validation code was written based on the HTML5 parsing spec:
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
|
||||
//
|
||||
// Note: this does not catch all invalid nesting, nor does it try to (as it's
|
||||
// not clear what practical benefit doing so provides); instead, we warn only
|
||||
// for cases where the parser will give a parse tree differing from what React
|
||||
// intended. For example, <b><div></div></b> is invalid but we don't warn
|
||||
// because it still parses correctly; we do warn for other cases like nested
|
||||
// <p> tags where the beginning of the second element implicitly closes the
|
||||
// first, causing a confusing mess.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#special
|
||||
const specialTags = [
|
||||
'address',
|
||||
'applet',
|
||||
'area',
|
||||
'article',
|
||||
'aside',
|
||||
'base',
|
||||
'basefont',
|
||||
'bgsound',
|
||||
'blockquote',
|
||||
'body',
|
||||
'br',
|
||||
'button',
|
||||
'caption',
|
||||
'center',
|
||||
'col',
|
||||
'colgroup',
|
||||
'dd',
|
||||
'details',
|
||||
'dir',
|
||||
'div',
|
||||
'dl',
|
||||
'dt',
|
||||
'embed',
|
||||
'fieldset',
|
||||
'figcaption',
|
||||
'figure',
|
||||
'footer',
|
||||
'form',
|
||||
'frame',
|
||||
'frameset',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'head',
|
||||
'header',
|
||||
'hgroup',
|
||||
'hr',
|
||||
'html',
|
||||
'iframe',
|
||||
'img',
|
||||
'input',
|
||||
'isindex',
|
||||
'li',
|
||||
'link',
|
||||
'listing',
|
||||
'main',
|
||||
'marquee',
|
||||
'menu',
|
||||
'menuitem',
|
||||
'meta',
|
||||
'nav',
|
||||
'noembed',
|
||||
'noframes',
|
||||
'noscript',
|
||||
'object',
|
||||
'ol',
|
||||
'p',
|
||||
'param',
|
||||
'plaintext',
|
||||
'pre',
|
||||
'script',
|
||||
'section',
|
||||
'select',
|
||||
'source',
|
||||
'style',
|
||||
'summary',
|
||||
'table',
|
||||
'tbody',
|
||||
'td',
|
||||
'template',
|
||||
'textarea',
|
||||
'tfoot',
|
||||
'th',
|
||||
'thead',
|
||||
'title',
|
||||
'tr',
|
||||
'track',
|
||||
'ul',
|
||||
'wbr',
|
||||
'xmp',
|
||||
];
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#special
|
||||
const specialTags = [
|
||||
'address',
|
||||
'applet',
|
||||
'area',
|
||||
'article',
|
||||
'aside',
|
||||
'base',
|
||||
'basefont',
|
||||
'bgsound',
|
||||
'blockquote',
|
||||
'body',
|
||||
'br',
|
||||
'button',
|
||||
'caption',
|
||||
'center',
|
||||
'col',
|
||||
'colgroup',
|
||||
'dd',
|
||||
'details',
|
||||
'dir',
|
||||
'div',
|
||||
'dl',
|
||||
'dt',
|
||||
'embed',
|
||||
'fieldset',
|
||||
'figcaption',
|
||||
'figure',
|
||||
'footer',
|
||||
'form',
|
||||
'frame',
|
||||
'frameset',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'h4',
|
||||
'h5',
|
||||
'h6',
|
||||
'head',
|
||||
'header',
|
||||
'hgroup',
|
||||
'hr',
|
||||
'html',
|
||||
'iframe',
|
||||
'img',
|
||||
'input',
|
||||
'isindex',
|
||||
'li',
|
||||
'link',
|
||||
'listing',
|
||||
'main',
|
||||
'marquee',
|
||||
'menu',
|
||||
'menuitem',
|
||||
'meta',
|
||||
'nav',
|
||||
'noembed',
|
||||
'noframes',
|
||||
'noscript',
|
||||
'object',
|
||||
'ol',
|
||||
'p',
|
||||
'param',
|
||||
'plaintext',
|
||||
'pre',
|
||||
'script',
|
||||
'section',
|
||||
'select',
|
||||
'source',
|
||||
'style',
|
||||
'summary',
|
||||
'table',
|
||||
'tbody',
|
||||
'td',
|
||||
'template',
|
||||
'textarea',
|
||||
'tfoot',
|
||||
'th',
|
||||
'thead',
|
||||
'title',
|
||||
'tr',
|
||||
'track',
|
||||
'ul',
|
||||
'wbr',
|
||||
'xmp',
|
||||
];
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
|
||||
const inScopeTags = [
|
||||
'applet',
|
||||
'caption',
|
||||
'html',
|
||||
'table',
|
||||
'td',
|
||||
'th',
|
||||
'marquee',
|
||||
'object',
|
||||
'template',
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
|
||||
const inScopeTags = [
|
||||
'applet',
|
||||
'caption',
|
||||
'html',
|
||||
'table',
|
||||
'td',
|
||||
'th',
|
||||
'marquee',
|
||||
'object',
|
||||
'template',
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
|
||||
// TODO: Distinguish by namespace here -- for <title>, including it here
|
||||
// errs on the side of fewer warnings
|
||||
'foreignObject',
|
||||
'desc',
|
||||
'title',
|
||||
];
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
|
||||
// TODO: Distinguish by namespace here -- for <title>, including it here
|
||||
// errs on the side of fewer warnings
|
||||
'foreignObject',
|
||||
'desc',
|
||||
'title',
|
||||
];
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
|
||||
const buttonScopeTags = inScopeTags.concat(['button']);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
|
||||
const buttonScopeTags = __DEV__ ? inScopeTags.concat(['button']) : [];
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
|
||||
const impliedEndTags = [
|
||||
'dd',
|
||||
'dt',
|
||||
'li',
|
||||
'option',
|
||||
'optgroup',
|
||||
'p',
|
||||
'rp',
|
||||
'rt',
|
||||
];
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
|
||||
const impliedEndTags = [
|
||||
'dd',
|
||||
'dt',
|
||||
'li',
|
||||
'option',
|
||||
'optgroup',
|
||||
'p',
|
||||
'rp',
|
||||
'rt',
|
||||
];
|
||||
|
||||
const emptyAncestorInfoDev: AncestorInfoDev = {
|
||||
current: null,
|
||||
const emptyAncestorInfoDev: AncestorInfoDev = {
|
||||
current: null,
|
||||
|
||||
formTag: null,
|
||||
aTagInScope: null,
|
||||
buttonTagInScope: null,
|
||||
nobrTagInScope: null,
|
||||
pTagInButtonScope: null,
|
||||
formTag: null,
|
||||
aTagInScope: null,
|
||||
buttonTagInScope: null,
|
||||
nobrTagInScope: null,
|
||||
pTagInButtonScope: null,
|
||||
|
||||
listItemTagAutoclosing: null,
|
||||
dlItemTagAutoclosing: null,
|
||||
listItemTagAutoclosing: null,
|
||||
dlItemTagAutoclosing: null,
|
||||
|
||||
containerTagInScope: null,
|
||||
};
|
||||
containerTagInScope: null,
|
||||
};
|
||||
|
||||
updatedAncestorInfoDev = function (oldInfo: ?AncestorInfoDev, tag: string) {
|
||||
function updatedAncestorInfoDev(
|
||||
oldInfo: ?AncestorInfoDev,
|
||||
tag: string,
|
||||
): AncestorInfoDev {
|
||||
if (__DEV__) {
|
||||
const ancestorInfo = {...(oldInfo || emptyAncestorInfoDev)};
|
||||
const info = {tag};
|
||||
|
||||
|
@ -234,213 +231,214 @@ if (__DEV__) {
|
|||
}
|
||||
|
||||
return ancestorInfo;
|
||||
};
|
||||
} else {
|
||||
return (null: any);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether
|
||||
*/
|
||||
const isTagValidWithParent = function (
|
||||
tag: string,
|
||||
parentTag: ?string,
|
||||
): boolean {
|
||||
// First, let's check if we're in an unusual parsing mode...
|
||||
switch (parentTag) {
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
|
||||
case 'select':
|
||||
return tag === 'option' || tag === 'optgroup' || tag === '#text';
|
||||
case 'optgroup':
|
||||
return tag === 'option' || tag === '#text';
|
||||
// Strictly speaking, seeing an <option> doesn't mean we're in a <select>
|
||||
// but
|
||||
case 'option':
|
||||
return tag === '#text';
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
|
||||
// No special behavior since these rules fall back to "in body" mode for
|
||||
// all except special table nodes which cause bad parsing behavior anyway.
|
||||
/**
|
||||
* Returns whether
|
||||
*/
|
||||
function isTagValidWithParent(tag: string, parentTag: ?string): boolean {
|
||||
// First, let's check if we're in an unusual parsing mode...
|
||||
switch (parentTag) {
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
|
||||
case 'select':
|
||||
return tag === 'option' || tag === 'optgroup' || tag === '#text';
|
||||
case 'optgroup':
|
||||
return tag === 'option' || tag === '#text';
|
||||
// Strictly speaking, seeing an <option> doesn't mean we're in a <select>
|
||||
// but
|
||||
case 'option':
|
||||
return tag === '#text';
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
|
||||
// No special behavior since these rules fall back to "in body" mode for
|
||||
// all except special table nodes which cause bad parsing behavior anyway.
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
|
||||
case 'tr':
|
||||
return (
|
||||
tag === 'th' ||
|
||||
tag === 'td' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
|
||||
case 'tbody':
|
||||
case 'thead':
|
||||
case 'tfoot':
|
||||
return (
|
||||
tag === 'tr' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
|
||||
case 'colgroup':
|
||||
return tag === 'col' || tag === 'template';
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
|
||||
case 'table':
|
||||
return (
|
||||
tag === 'caption' ||
|
||||
tag === 'colgroup' ||
|
||||
tag === 'tbody' ||
|
||||
tag === 'tfoot' ||
|
||||
tag === 'thead' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
|
||||
case 'head':
|
||||
return (
|
||||
tag === 'base' ||
|
||||
tag === 'basefont' ||
|
||||
tag === 'bgsound' ||
|
||||
tag === 'link' ||
|
||||
tag === 'meta' ||
|
||||
tag === 'title' ||
|
||||
tag === 'noscript' ||
|
||||
tag === 'noframes' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
|
||||
case 'html':
|
||||
return tag === 'head' || tag === 'body' || tag === 'frameset';
|
||||
case 'frameset':
|
||||
return tag === 'frame';
|
||||
case '#document':
|
||||
return tag === 'html';
|
||||
}
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
|
||||
case 'tr':
|
||||
return (
|
||||
tag === 'th' ||
|
||||
tag === 'td' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
|
||||
case 'tbody':
|
||||
case 'thead':
|
||||
case 'tfoot':
|
||||
return (
|
||||
tag === 'tr' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
|
||||
case 'colgroup':
|
||||
return tag === 'col' || tag === 'template';
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
|
||||
case 'table':
|
||||
return (
|
||||
tag === 'caption' ||
|
||||
tag === 'colgroup' ||
|
||||
tag === 'tbody' ||
|
||||
tag === 'tfoot' ||
|
||||
tag === 'thead' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
|
||||
case 'head':
|
||||
return (
|
||||
tag === 'base' ||
|
||||
tag === 'basefont' ||
|
||||
tag === 'bgsound' ||
|
||||
tag === 'link' ||
|
||||
tag === 'meta' ||
|
||||
tag === 'title' ||
|
||||
tag === 'noscript' ||
|
||||
tag === 'noframes' ||
|
||||
tag === 'style' ||
|
||||
tag === 'script' ||
|
||||
tag === 'template'
|
||||
);
|
||||
// https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
|
||||
case 'html':
|
||||
return tag === 'head' || tag === 'body' || tag === 'frameset';
|
||||
case 'frameset':
|
||||
return tag === 'frame';
|
||||
case '#document':
|
||||
return tag === 'html';
|
||||
}
|
||||
|
||||
// Probably in the "in body" parsing mode, so we outlaw only tag combos
|
||||
// where the parsing rules cause implicit opens or closes to be added.
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
|
||||
switch (tag) {
|
||||
case 'h1':
|
||||
case 'h2':
|
||||
case 'h3':
|
||||
case 'h4':
|
||||
case 'h5':
|
||||
case 'h6':
|
||||
return (
|
||||
parentTag !== 'h1' &&
|
||||
parentTag !== 'h2' &&
|
||||
parentTag !== 'h3' &&
|
||||
parentTag !== 'h4' &&
|
||||
parentTag !== 'h5' &&
|
||||
parentTag !== 'h6'
|
||||
);
|
||||
// Probably in the "in body" parsing mode, so we outlaw only tag combos
|
||||
// where the parsing rules cause implicit opens or closes to be added.
|
||||
// https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
|
||||
switch (tag) {
|
||||
case 'h1':
|
||||
case 'h2':
|
||||
case 'h3':
|
||||
case 'h4':
|
||||
case 'h5':
|
||||
case 'h6':
|
||||
return (
|
||||
parentTag !== 'h1' &&
|
||||
parentTag !== 'h2' &&
|
||||
parentTag !== 'h3' &&
|
||||
parentTag !== 'h4' &&
|
||||
parentTag !== 'h5' &&
|
||||
parentTag !== 'h6'
|
||||
);
|
||||
|
||||
case 'rp':
|
||||
case 'rt':
|
||||
return impliedEndTags.indexOf(parentTag) === -1;
|
||||
case 'rp':
|
||||
case 'rt':
|
||||
return impliedEndTags.indexOf(parentTag) === -1;
|
||||
|
||||
case 'body':
|
||||
case 'caption':
|
||||
case 'col':
|
||||
case 'colgroup':
|
||||
case 'frameset':
|
||||
case 'frame':
|
||||
case 'head':
|
||||
case 'html':
|
||||
case 'tbody':
|
||||
case 'td':
|
||||
case 'tfoot':
|
||||
case 'th':
|
||||
case 'thead':
|
||||
case 'tr':
|
||||
// These tags are only valid with a few parents that have special child
|
||||
// parsing rules -- if we're down here, then none of those matched and
|
||||
// so we allow it only if we don't know what the parent is, as all other
|
||||
// cases are invalid.
|
||||
return parentTag == null;
|
||||
}
|
||||
case 'body':
|
||||
case 'caption':
|
||||
case 'col':
|
||||
case 'colgroup':
|
||||
case 'frameset':
|
||||
case 'frame':
|
||||
case 'head':
|
||||
case 'html':
|
||||
case 'tbody':
|
||||
case 'td':
|
||||
case 'tfoot':
|
||||
case 'th':
|
||||
case 'thead':
|
||||
case 'tr':
|
||||
// These tags are only valid with a few parents that have special child
|
||||
// parsing rules -- if we're down here, then none of those matched and
|
||||
// so we allow it only if we don't know what the parent is, as all other
|
||||
// cases are invalid.
|
||||
return parentTag == null;
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether
|
||||
*/
|
||||
const findInvalidAncestorForTag = function (
|
||||
tag: string,
|
||||
ancestorInfo: AncestorInfoDev,
|
||||
): ?Info {
|
||||
switch (tag) {
|
||||
case 'address':
|
||||
case 'article':
|
||||
case 'aside':
|
||||
case 'blockquote':
|
||||
case 'center':
|
||||
case 'details':
|
||||
case 'dialog':
|
||||
case 'dir':
|
||||
case 'div':
|
||||
case 'dl':
|
||||
case 'fieldset':
|
||||
case 'figcaption':
|
||||
case 'figure':
|
||||
case 'footer':
|
||||
case 'header':
|
||||
case 'hgroup':
|
||||
case 'main':
|
||||
case 'menu':
|
||||
case 'nav':
|
||||
case 'ol':
|
||||
case 'p':
|
||||
case 'section':
|
||||
case 'summary':
|
||||
case 'ul':
|
||||
case 'pre':
|
||||
case 'listing':
|
||||
case 'table':
|
||||
case 'hr':
|
||||
case 'xmp':
|
||||
case 'h1':
|
||||
case 'h2':
|
||||
case 'h3':
|
||||
case 'h4':
|
||||
case 'h5':
|
||||
case 'h6':
|
||||
return ancestorInfo.pTagInButtonScope;
|
||||
/**
|
||||
* Returns whether
|
||||
*/
|
||||
function findInvalidAncestorForTag(
|
||||
tag: string,
|
||||
ancestorInfo: AncestorInfoDev,
|
||||
): ?Info {
|
||||
switch (tag) {
|
||||
case 'address':
|
||||
case 'article':
|
||||
case 'aside':
|
||||
case 'blockquote':
|
||||
case 'center':
|
||||
case 'details':
|
||||
case 'dialog':
|
||||
case 'dir':
|
||||
case 'div':
|
||||
case 'dl':
|
||||
case 'fieldset':
|
||||
case 'figcaption':
|
||||
case 'figure':
|
||||
case 'footer':
|
||||
case 'header':
|
||||
case 'hgroup':
|
||||
case 'main':
|
||||
case 'menu':
|
||||
case 'nav':
|
||||
case 'ol':
|
||||
case 'p':
|
||||
case 'section':
|
||||
case 'summary':
|
||||
case 'ul':
|
||||
case 'pre':
|
||||
case 'listing':
|
||||
case 'table':
|
||||
case 'hr':
|
||||
case 'xmp':
|
||||
case 'h1':
|
||||
case 'h2':
|
||||
case 'h3':
|
||||
case 'h4':
|
||||
case 'h5':
|
||||
case 'h6':
|
||||
return ancestorInfo.pTagInButtonScope;
|
||||
|
||||
case 'form':
|
||||
return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
|
||||
case 'form':
|
||||
return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
|
||||
|
||||
case 'li':
|
||||
return ancestorInfo.listItemTagAutoclosing;
|
||||
case 'li':
|
||||
return ancestorInfo.listItemTagAutoclosing;
|
||||
|
||||
case 'dd':
|
||||
case 'dt':
|
||||
return ancestorInfo.dlItemTagAutoclosing;
|
||||
case 'dd':
|
||||
case 'dt':
|
||||
return ancestorInfo.dlItemTagAutoclosing;
|
||||
|
||||
case 'button':
|
||||
return ancestorInfo.buttonTagInScope;
|
||||
case 'button':
|
||||
return ancestorInfo.buttonTagInScope;
|
||||
|
||||
case 'a':
|
||||
// Spec says something about storing a list of markers, but it sounds
|
||||
// equivalent to this check.
|
||||
return ancestorInfo.aTagInScope;
|
||||
case 'a':
|
||||
// Spec says something about storing a list of markers, but it sounds
|
||||
// equivalent to this check.
|
||||
return ancestorInfo.aTagInScope;
|
||||
|
||||
case 'nobr':
|
||||
return ancestorInfo.nobrTagInScope;
|
||||
}
|
||||
case 'nobr':
|
||||
return ancestorInfo.nobrTagInScope;
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
return null;
|
||||
}
|
||||
|
||||
const didWarn: {[string]: boolean} = {};
|
||||
const didWarn: {[string]: boolean} = {};
|
||||
|
||||
validateDOMNesting = function (
|
||||
childTag: ?string,
|
||||
childText: ?string,
|
||||
ancestorInfo: AncestorInfoDev,
|
||||
) {
|
||||
function validateDOMNesting(
|
||||
childTag: ?string,
|
||||
childText: ?string,
|
||||
ancestorInfo: AncestorInfoDev,
|
||||
): void {
|
||||
if (__DEV__) {
|
||||
ancestorInfo = ancestorInfo || emptyAncestorInfoDev;
|
||||
const parentInfo = ancestorInfo.current;
|
||||
const parentTag = parentInfo && parentInfo.tag;
|
||||
|
@ -517,7 +515,7 @@ if (__DEV__) {
|
|||
ancestorTag,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {updatedAncestorInfoDev, validateDOMNesting};
|
||||
|
|
|
@ -16,16 +16,18 @@ import isCustomComponent from './isCustomComponent';
|
|||
import possibleStandardNames from './possibleStandardNames';
|
||||
import hasOwnProperty from 'shared/hasOwnProperty';
|
||||
|
||||
let validateProperty = () => {};
|
||||
const warnedProperties = {};
|
||||
const EVENT_NAME_REGEX = /^on./;
|
||||
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
|
||||
const rARIA = __DEV__
|
||||
? new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$')
|
||||
: null;
|
||||
const rARIACamel = __DEV__
|
||||
? new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$')
|
||||
: null;
|
||||
|
||||
if (__DEV__) {
|
||||
const warnedProperties = {};
|
||||
const EVENT_NAME_REGEX = /^on./;
|
||||
const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
|
||||
const rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
|
||||
const rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
|
||||
|
||||
validateProperty = function (tagName, name, value, eventRegistry) {
|
||||
function validateProperty(tagName, name, value, eventRegistry) {
|
||||
if (__DEV__) {
|
||||
if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
|
||||
return true;
|
||||
}
|
||||
|
@ -234,10 +236,10 @@ if (__DEV__) {
|
|||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const warnUnknownProperties = function (type, props, eventRegistry) {
|
||||
function warnUnknownProperties(type, props, eventRegistry) {
|
||||
if (__DEV__) {
|
||||
const unknownProps = [];
|
||||
for (const key in props) {
|
||||
|
@ -268,7 +270,7 @@ const warnUnknownProperties = function (type, props, eventRegistry) {
|
|||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function validateProperties(type, props, eventRegistry) {
|
||||
if (isCustomComponent(type, props)) {
|
||||
|
|
|
@ -5,29 +5,27 @@
|
|||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
let warnValidStyle = () => {};
|
||||
// 'msTransform' is correct, but the other prefixes should be capitalized
|
||||
const badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
|
||||
const msPattern = /^-ms-/;
|
||||
const hyphenPattern = /-(.)/g;
|
||||
|
||||
if (__DEV__) {
|
||||
// 'msTransform' is correct, but the other prefixes should be capitalized
|
||||
const badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
|
||||
const msPattern = /^-ms-/;
|
||||
const hyphenPattern = /-(.)/g;
|
||||
// style values shouldn't contain a semicolon
|
||||
const badStyleValueWithSemicolonPattern = /;\s*$/;
|
||||
|
||||
// style values shouldn't contain a semicolon
|
||||
const badStyleValueWithSemicolonPattern = /;\s*$/;
|
||||
const warnedStyleNames = {};
|
||||
const warnedStyleValues = {};
|
||||
let warnedForNaNValue = false;
|
||||
let warnedForInfinityValue = false;
|
||||
|
||||
const warnedStyleNames = {};
|
||||
const warnedStyleValues = {};
|
||||
let warnedForNaNValue = false;
|
||||
let warnedForInfinityValue = false;
|
||||
function camelize(string) {
|
||||
return string.replace(hyphenPattern, function (_, character) {
|
||||
return character.toUpperCase();
|
||||
});
|
||||
}
|
||||
|
||||
const camelize = function (string) {
|
||||
return string.replace(hyphenPattern, function (_, character) {
|
||||
return character.toUpperCase();
|
||||
});
|
||||
};
|
||||
|
||||
const warnHyphenatedStyleName = function (name) {
|
||||
function warnHyphenatedStyleName(name) {
|
||||
if (__DEV__) {
|
||||
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
||||
return;
|
||||
}
|
||||
|
@ -41,9 +39,11 @@ if (__DEV__) {
|
|||
// is converted to lowercase `ms`.
|
||||
camelize(name.replace(msPattern, 'ms-')),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const warnBadVendoredStyleName = function (name) {
|
||||
function warnBadVendoredStyleName(name) {
|
||||
if (__DEV__) {
|
||||
if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
|
||||
return;
|
||||
}
|
||||
|
@ -54,9 +54,11 @@ if (__DEV__) {
|
|||
name,
|
||||
name.charAt(0).toUpperCase() + name.slice(1),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const warnStyleValueWithSemicolon = function (name, value) {
|
||||
function warnStyleValueWithSemicolon(name, value) {
|
||||
if (__DEV__) {
|
||||
if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
|
||||
return;
|
||||
}
|
||||
|
@ -68,9 +70,11 @@ if (__DEV__) {
|
|||
name,
|
||||
value.replace(badStyleValueWithSemicolonPattern, ''),
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const warnStyleValueIsNaN = function (name, value) {
|
||||
function warnStyleValueIsNaN(name, value) {
|
||||
if (__DEV__) {
|
||||
if (warnedForNaNValue) {
|
||||
return;
|
||||
}
|
||||
|
@ -80,9 +84,11 @@ if (__DEV__) {
|
|||
'`NaN` is an invalid value for the `%s` css style property.',
|
||||
name,
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
const warnStyleValueIsInfinity = function (name, value) {
|
||||
function warnStyleValueIsInfinity(name, value) {
|
||||
if (__DEV__) {
|
||||
if (warnedForInfinityValue) {
|
||||
return;
|
||||
}
|
||||
|
@ -92,9 +98,11 @@ if (__DEV__) {
|
|||
'`Infinity` is an invalid value for the `%s` css style property.',
|
||||
name,
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
warnValidStyle = function (name, value) {
|
||||
function warnValidStyle(name, value) {
|
||||
if (__DEV__) {
|
||||
if (name.indexOf('-') > -1) {
|
||||
warnHyphenatedStyleName(name);
|
||||
} else if (badVendoredStyleNamePattern.test(name)) {
|
||||
|
@ -110,7 +118,7 @@ if (__DEV__) {
|
|||
warnStyleValueIsInfinity(name, value);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export default warnValidStyle;
|
||||
|
|
|
@ -392,7 +392,7 @@ function executeDispatchesInOrder(event) {
|
|||
* @param {?object} event Synthetic event to be dispatched.
|
||||
* @private
|
||||
*/
|
||||
const executeDispatchesAndRelease = function (event /* ReactSyntheticEvent */) {
|
||||
function executeDispatchesAndRelease(event /* ReactSyntheticEvent */) {
|
||||
if (event) {
|
||||
executeDispatchesInOrder(event);
|
||||
|
||||
|
@ -400,7 +400,7 @@ const executeDispatchesAndRelease = function (event /* ReactSyntheticEvent */) {
|
|||
event.constructor.release(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isInteractive(tag) {
|
||||
return (
|
||||
|
|
|
@ -44,13 +44,13 @@ const EMPTY_NATIVE_EVENT = (({}: any): AnyNativeEvent);
|
|||
* @return {Array<Touch>} Subsequence of touch objects.
|
||||
*/
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
const touchSubsequence = function (touches, indices) {
|
||||
function touchSubsequence(touches, indices) {
|
||||
const ret = [];
|
||||
for (let i = 0; i < indices.length; i++) {
|
||||
ret.push(touches[indices[i]]);
|
||||
}
|
||||
return ret;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: Pool all of this.
|
||||
|
@ -63,7 +63,7 @@ const touchSubsequence = function (touches, indices) {
|
|||
* @param {Array<number>} indices Indices to remove from `touches`.
|
||||
* @return {Array<Touch>} Subsequence of removed touch objects.
|
||||
*/
|
||||
const removeTouchesAtIndices = function (
|
||||
function removeTouchesAtIndices(
|
||||
touches: Array<Object>,
|
||||
indices: Array<number>,
|
||||
): Array<Object> {
|
||||
|
@ -85,7 +85,7 @@ const removeTouchesAtIndices = function (
|
|||
}
|
||||
temp.length = fillAt;
|
||||
return rippedOut;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal version of `receiveEvent` in terms of normalized (non-tag)
|
||||
|
|
|
@ -28,49 +28,39 @@ if (__DEV__) {
|
|||
Object.freeze(emptyObject);
|
||||
}
|
||||
|
||||
let createHierarchy;
|
||||
let getHostNode;
|
||||
let getHostProps;
|
||||
let lastNonHostInstance;
|
||||
let getInspectorDataForInstance: (
|
||||
closestInstance: Fiber | null,
|
||||
) => InspectorData;
|
||||
let getOwnerHierarchy;
|
||||
let traverseOwnerTreeUp: (hierarchy: Array<$FlowFixMe>, instance: any) => void;
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
function createHierarchy(fiberHierarchy) {
|
||||
return fiberHierarchy.map(fiber => ({
|
||||
name: getComponentNameFromType(fiber.type),
|
||||
getInspectorData: findNodeHandle => {
|
||||
return {
|
||||
props: getHostProps(fiber),
|
||||
source: fiber._debugSource,
|
||||
measure: callback => {
|
||||
// If this is Fabric, we'll find a shadow node and use that to measure.
|
||||
const hostFiber = findCurrentHostFiber(fiber);
|
||||
const node =
|
||||
hostFiber != null &&
|
||||
hostFiber.stateNode !== null &&
|
||||
hostFiber.stateNode.node;
|
||||
|
||||
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
createHierarchy = function (fiberHierarchy) {
|
||||
return fiberHierarchy.map(fiber => ({
|
||||
name: getComponentNameFromType(fiber.type),
|
||||
getInspectorData: findNodeHandle => {
|
||||
return {
|
||||
props: getHostProps(fiber),
|
||||
source: fiber._debugSource,
|
||||
measure: callback => {
|
||||
// If this is Fabric, we'll find a shadow node and use that to measure.
|
||||
const hostFiber = findCurrentHostFiber(fiber);
|
||||
const node =
|
||||
hostFiber != null &&
|
||||
hostFiber.stateNode !== null &&
|
||||
hostFiber.stateNode.node;
|
||||
if (node) {
|
||||
nativeFabricUIManager.measure(node, callback);
|
||||
} else {
|
||||
return UIManager.measure(
|
||||
getHostNode(fiber, findNodeHandle),
|
||||
callback,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
||||
if (node) {
|
||||
nativeFabricUIManager.measure(node, callback);
|
||||
} else {
|
||||
return UIManager.measure(
|
||||
getHostNode(fiber, findNodeHandle),
|
||||
callback,
|
||||
);
|
||||
}
|
||||
},
|
||||
};
|
||||
},
|
||||
}));
|
||||
};
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
getHostNode = function (fiber: Fiber | null, findNodeHandle) {
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
function getHostNode(fiber: Fiber | null, findNodeHandle) {
|
||||
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
|
||||
let hostNode;
|
||||
// look for children first for the hostNode
|
||||
// as composite fibers do not have a hostNode
|
||||
|
@ -84,20 +74,22 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
|
|||
fiber = fiber.child;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
getHostProps = function (fiber) {
|
||||
const host = findCurrentHostFiber(fiber);
|
||||
if (host) {
|
||||
return host.memoizedProps || emptyObject;
|
||||
}
|
||||
return emptyObject;
|
||||
};
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
function getHostProps(fiber) {
|
||||
const host = findCurrentHostFiber(fiber);
|
||||
if (host) {
|
||||
return host.memoizedProps || emptyObject;
|
||||
}
|
||||
return emptyObject;
|
||||
}
|
||||
|
||||
getInspectorDataForInstance = function (
|
||||
closestInstance: Fiber | null,
|
||||
): InspectorData {
|
||||
function getInspectorDataForInstance(
|
||||
closestInstance: Fiber | null,
|
||||
): InspectorData {
|
||||
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
|
||||
// Handle case where user clicks outside of ReactNative
|
||||
if (!closestInstance) {
|
||||
return {
|
||||
|
@ -123,46 +115,44 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
|
|||
selectedIndex,
|
||||
source,
|
||||
};
|
||||
};
|
||||
} else {
|
||||
return (null: any);
|
||||
}
|
||||
}
|
||||
|
||||
getOwnerHierarchy = function (instance: any) {
|
||||
const hierarchy: Array<$FlowFixMe> = [];
|
||||
traverseOwnerTreeUp(hierarchy, instance);
|
||||
return hierarchy;
|
||||
};
|
||||
function getOwnerHierarchy(instance: any) {
|
||||
const hierarchy: Array<$FlowFixMe> = [];
|
||||
traverseOwnerTreeUp(hierarchy, instance);
|
||||
return hierarchy;
|
||||
}
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
lastNonHostInstance = function (hierarchy) {
|
||||
for (let i = hierarchy.length - 1; i > 1; i--) {
|
||||
const instance = hierarchy[i];
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
function lastNonHostInstance(hierarchy) {
|
||||
for (let i = hierarchy.length - 1; i > 1; i--) {
|
||||
const instance = hierarchy[i];
|
||||
|
||||
if (instance.tag !== HostComponent) {
|
||||
return instance;
|
||||
}
|
||||
if (instance.tag !== HostComponent) {
|
||||
return instance;
|
||||
}
|
||||
return hierarchy[0];
|
||||
};
|
||||
}
|
||||
return hierarchy[0];
|
||||
}
|
||||
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
traverseOwnerTreeUp = function (hierarchy, instance: any): void {
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
function traverseOwnerTreeUp(
|
||||
hierarchy: Array<$FlowFixMe>,
|
||||
instance: any,
|
||||
): void {
|
||||
if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
|
||||
if (instance) {
|
||||
hierarchy.unshift(instance);
|
||||
traverseOwnerTreeUp(hierarchy, instance._debugOwner);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
let getInspectorDataForViewTag: (viewTag: number) => Object;
|
||||
let getInspectorDataForViewAtPoint: (
|
||||
findNodeHandle: (componentOrHandle: any) => ?number,
|
||||
inspectedView: Object,
|
||||
locationX: number,
|
||||
locationY: number,
|
||||
callback: (viewData: TouchedViewDataAtPoint) => mixed,
|
||||
) => void;
|
||||
|
||||
if (__DEV__) {
|
||||
getInspectorDataForViewTag = function (viewTag: number): Object {
|
||||
function getInspectorDataForViewTag(viewTag: number): Object {
|
||||
if (__DEV__) {
|
||||
const closestInstance = getClosestInstanceFromNode(viewTag);
|
||||
|
||||
// Handle case where user clicks outside of ReactNative
|
||||
|
@ -189,15 +179,21 @@ if (__DEV__) {
|
|||
selectedIndex,
|
||||
source,
|
||||
};
|
||||
};
|
||||
} else {
|
||||
throw new Error(
|
||||
'getInspectorDataForViewTag() is not available in production',
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
getInspectorDataForViewAtPoint = function (
|
||||
findNodeHandle: (componentOrHandle: any) => ?number,
|
||||
inspectedView: Object,
|
||||
locationX: number,
|
||||
locationY: number,
|
||||
callback: (viewData: TouchedViewDataAtPoint) => mixed,
|
||||
): void {
|
||||
function getInspectorDataForViewAtPoint(
|
||||
findNodeHandle: (componentOrHandle: any) => ?number,
|
||||
inspectedView: Object,
|
||||
locationX: number,
|
||||
locationY: number,
|
||||
callback: (viewData: TouchedViewDataAtPoint) => mixed,
|
||||
): void {
|
||||
if (__DEV__) {
|
||||
let closestInstance = null;
|
||||
|
||||
const fabricInstanceHandle =
|
||||
|
@ -271,25 +267,11 @@ if (__DEV__) {
|
|||
|
||||
return;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
getInspectorDataForViewTag = () => {
|
||||
throw new Error(
|
||||
'getInspectorDataForViewTag() is not available in production',
|
||||
);
|
||||
};
|
||||
|
||||
getInspectorDataForViewAtPoint = (
|
||||
findNodeHandle: (componentOrHandle: any) => ?number,
|
||||
inspectedView: Object,
|
||||
locationX: number,
|
||||
locationY: number,
|
||||
callback: (viewData: TouchedViewDataAtPoint) => mixed,
|
||||
): void => {
|
||||
} else {
|
||||
throw new Error(
|
||||
'getInspectorDataForViewAtPoint() is not available in production.',
|
||||
);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
|
|
|
@ -15,7 +15,7 @@ type Options = {+unsafelyIgnoreFunctions?: boolean};
|
|||
/*
|
||||
* @returns {bool} true if different, false if equal
|
||||
*/
|
||||
const deepDiffer = function (
|
||||
function deepDiffer(
|
||||
one: any,
|
||||
two: any,
|
||||
maxDepthOrOptions: Options | number = -1,
|
||||
|
@ -79,6 +79,6 @@ const deepDiffer = function (
|
|||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = deepDiffer;
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
// TODO: move into react or fbjs
|
||||
|
||||
const deepFreezeAndThrowOnMutationInDev = function () {};
|
||||
function deepFreezeAndThrowOnMutationInDev() {}
|
||||
|
||||
module.exports = deepFreezeAndThrowOnMutationInDev;
|
||||
|
|
|
@ -9,6 +9,6 @@
|
|||
|
||||
// TODO: Move flattenStyle into react
|
||||
|
||||
const flattenStyle = function () {};
|
||||
function flattenStyle() {}
|
||||
|
||||
module.exports = flattenStyle;
|
||||
|
|
|
@ -25,7 +25,7 @@ let eventQueue: ?(Array<ReactSyntheticEvent> | ReactSyntheticEvent) = null;
|
|||
* @param {?object} event Synthetic event to be dispatched.
|
||||
* @private
|
||||
*/
|
||||
const executeDispatchesAndRelease = function (event: ReactSyntheticEvent) {
|
||||
function executeDispatchesAndRelease(event: ReactSyntheticEvent) {
|
||||
if (event) {
|
||||
executeDispatchesInOrder(event);
|
||||
|
||||
|
@ -33,11 +33,11 @@ const executeDispatchesAndRelease = function (event: ReactSyntheticEvent) {
|
|||
event.constructor.release(event);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
// $FlowFixMe[missing-local-annot]
|
||||
const executeDispatchesAndReleaseTopLevel = function (e) {
|
||||
function executeDispatchesAndReleaseTopLevel(e) {
|
||||
return executeDispatchesAndRelease(e);
|
||||
};
|
||||
}
|
||||
|
||||
export function runEventsInBatch(
|
||||
events: Array<ReactSyntheticEvent> | ReactSyntheticEvent | null,
|
||||
|
|
|
@ -30,9 +30,8 @@ export function setComponentTree(
|
|||
}
|
||||
}
|
||||
|
||||
let validateEventDispatches;
|
||||
if (__DEV__) {
|
||||
validateEventDispatches = function (event) {
|
||||
function validateEventDispatches(event) {
|
||||
if (__DEV__) {
|
||||
const dispatchListeners = event._dispatchListeners;
|
||||
const dispatchInstances = event._dispatchInstances;
|
||||
|
||||
|
@ -53,7 +52,7 @@ if (__DEV__) {
|
|||
if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
|
||||
console.error('EventPluginUtils: Invalid `event`.');
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,7 @@ let responderInst = null;
|
|||
*/
|
||||
let trackedTouchCount = 0;
|
||||
|
||||
const changeResponder = function (nextResponderInst, blockHostResponder) {
|
||||
function changeResponder(nextResponderInst, blockHostResponder) {
|
||||
const oldResponderInst = responderInst;
|
||||
responderInst = nextResponderInst;
|
||||
if (ResponderEventPlugin.GlobalResponderHandler !== null) {
|
||||
|
@ -54,7 +54,7 @@ const changeResponder = function (nextResponderInst, blockHostResponder) {
|
|||
blockHostResponder,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
const eventTypes = {
|
||||
/**
|
||||
|
|
|
@ -224,7 +224,7 @@ function FiberNode(
|
|||
// is faster.
|
||||
// 5) It should be easy to port this to a C struct and keep a C implementation
|
||||
// compatible.
|
||||
const createFiber = function (
|
||||
function createFiber(
|
||||
tag: WorkTag,
|
||||
pendingProps: mixed,
|
||||
key: null | string,
|
||||
|
@ -232,7 +232,7 @@ const createFiber = function (
|
|||
): Fiber {
|
||||
// $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
|
||||
return new FiberNode(tag, pendingProps, key, mode);
|
||||
};
|
||||
}
|
||||
|
||||
function shouldConstruct(Component: Function) {
|
||||
const prototype = Component.prototype;
|
||||
|
|
|
@ -85,11 +85,10 @@ let didWarnAboutUninitializedState;
|
|||
let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
|
||||
let didWarnAboutLegacyLifecyclesAndDerivedState;
|
||||
let didWarnAboutUndefinedDerivedState;
|
||||
let warnOnUndefinedDerivedState;
|
||||
let warnOnInvalidCallback;
|
||||
let didWarnAboutDirectlyAssigningPropsToState;
|
||||
let didWarnAboutContextTypeAndContextTypes;
|
||||
let didWarnAboutInvalidateContextType;
|
||||
let didWarnOnInvalidCallback;
|
||||
|
||||
if (__DEV__) {
|
||||
didWarnAboutStateAssignmentForComponent = new Set<string>();
|
||||
|
@ -100,38 +99,7 @@ if (__DEV__) {
|
|||
didWarnAboutUndefinedDerivedState = new Set<string>();
|
||||
didWarnAboutContextTypeAndContextTypes = new Set<string>();
|
||||
didWarnAboutInvalidateContextType = new Set<string>();
|
||||
|
||||
const didWarnOnInvalidCallback = new Set<string>();
|
||||
|
||||
warnOnInvalidCallback = function (callback: mixed, callerName: string) {
|
||||
if (callback === null || typeof callback === 'function') {
|
||||
return;
|
||||
}
|
||||
const key = callerName + '_' + (callback: any);
|
||||
if (!didWarnOnInvalidCallback.has(key)) {
|
||||
didWarnOnInvalidCallback.add(key);
|
||||
console.error(
|
||||
'%s(...): Expected the last optional `callback` argument to be a ' +
|
||||
'function. Instead received: %s.',
|
||||
callerName,
|
||||
callback,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
warnOnUndefinedDerivedState = function (type: any, partialState: any) {
|
||||
if (partialState === undefined) {
|
||||
const componentName = getComponentNameFromType(type) || 'Component';
|
||||
if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
|
||||
didWarnAboutUndefinedDerivedState.add(componentName);
|
||||
console.error(
|
||||
'%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
|
||||
'You have returned undefined.',
|
||||
componentName,
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
didWarnOnInvalidCallback = new Set<string>();
|
||||
|
||||
// This is so gross but it's at least non-critical and can be removed if
|
||||
// it causes problems. This is meant to give a nicer error message for
|
||||
|
@ -154,6 +122,40 @@ if (__DEV__) {
|
|||
Object.freeze(fakeInternalInstance);
|
||||
}
|
||||
|
||||
function warnOnInvalidCallback(callback: mixed, callerName: string) {
|
||||
if (__DEV__) {
|
||||
if (callback === null || typeof callback === 'function') {
|
||||
return;
|
||||
}
|
||||
const key = callerName + '_' + (callback: any);
|
||||
if (!didWarnOnInvalidCallback.has(key)) {
|
||||
didWarnOnInvalidCallback.add(key);
|
||||
console.error(
|
||||
'%s(...): Expected the last optional `callback` argument to be a ' +
|
||||
'function. Instead received: %s.',
|
||||
callerName,
|
||||
callback,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function warnOnUndefinedDerivedState(type: any, partialState: any) {
|
||||
if (__DEV__) {
|
||||
if (partialState === undefined) {
|
||||
const componentName = getComponentNameFromType(type) || 'Component';
|
||||
if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
|
||||
didWarnAboutUndefinedDerivedState.add(componentName);
|
||||
console.error(
|
||||
'%s.getDerivedStateFromProps(): A valid state object (or null) must be returned. ' +
|
||||
'You have returned undefined.',
|
||||
componentName,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function applyDerivedStateFromProps(
|
||||
workInProgress: Fiber,
|
||||
ctor: any,
|
||||
|
|
|
@ -253,10 +253,7 @@ export function reportUncaughtErrorInDEV(error: mixed) {
|
|||
}
|
||||
}
|
||||
|
||||
const callComponentWillUnmountWithTimer = function (
|
||||
current: Fiber,
|
||||
instance: any,
|
||||
) {
|
||||
function callComponentWillUnmountWithTimer(current: Fiber, instance: any) {
|
||||
instance.props = current.memoizedProps;
|
||||
instance.state = current.memoizedState;
|
||||
if (shouldProfile(current)) {
|
||||
|
@ -269,7 +266,7 @@ const callComponentWillUnmountWithTimer = function (
|
|||
} else {
|
||||
instance.componentWillUnmount();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Capture errors so they don't interrupt unmounting.
|
||||
function safelyCallComponentWillUnmount(
|
||||
|
|
|
@ -24,11 +24,10 @@ let didWarnAboutUninitializedState;
|
|||
let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
|
||||
let didWarnAboutLegacyLifecyclesAndDerivedState;
|
||||
let didWarnAboutUndefinedDerivedState;
|
||||
let warnOnUndefinedDerivedState;
|
||||
let warnOnInvalidCallback;
|
||||
let didWarnAboutDirectlyAssigningPropsToState;
|
||||
let didWarnAboutContextTypeAndContextTypes;
|
||||
let didWarnAboutInvalidateContextType;
|
||||
let didWarnOnInvalidCallback;
|
||||
|
||||
if (__DEV__) {
|
||||
didWarnAboutUninitializedState = new Set<string>();
|
||||
|
@ -38,10 +37,11 @@ if (__DEV__) {
|
|||
didWarnAboutUndefinedDerivedState = new Set<string>();
|
||||
didWarnAboutContextTypeAndContextTypes = new Set<mixed>();
|
||||
didWarnAboutInvalidateContextType = new Set<mixed>();
|
||||
didWarnOnInvalidCallback = new Set<string>();
|
||||
}
|
||||
|
||||
const didWarnOnInvalidCallback = new Set<string>();
|
||||
|
||||
warnOnInvalidCallback = function (callback: mixed, callerName: string) {
|
||||
function warnOnInvalidCallback(callback: mixed, callerName: string) {
|
||||
if (__DEV__) {
|
||||
if (callback === null || typeof callback === 'function') {
|
||||
return;
|
||||
}
|
||||
|
@ -55,9 +55,11 @@ if (__DEV__) {
|
|||
callback,
|
||||
);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
warnOnUndefinedDerivedState = function (type: any, partialState: any) {
|
||||
function warnOnUndefinedDerivedState(type: any, partialState: any) {
|
||||
if (__DEV__) {
|
||||
if (partialState === undefined) {
|
||||
const componentName = getComponentNameFromType(type) || 'Component';
|
||||
if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
|
||||
|
@ -69,7 +71,7 @@ if (__DEV__) {
|
|||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
function warnNoop(
|
||||
|
|
|
@ -145,7 +145,7 @@ function warnIfStringRefCannotBeAutoConverted(config) {
|
|||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
const ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
function ReactElement(type, key, ref, self, source, owner, props) {
|
||||
const element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
|
@ -199,7 +199,7 @@ const ReactElement = function (type, key, ref, self, source, owner, props) {
|
|||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
|
|
|
@ -145,7 +145,7 @@ function defineRefPropWarningGetter(props, displayName) {
|
|||
* indicating filename, line number, and/or other information.
|
||||
* @internal
|
||||
*/
|
||||
const ReactElement = function (type, key, ref, self, source, owner, props) {
|
||||
function ReactElement(type, key, ref, self, source, owner, props) {
|
||||
const element = {
|
||||
// This tag allows us to uniquely identify this as a React Element
|
||||
$$typeof: REACT_ELEMENT_TYPE,
|
||||
|
@ -199,7 +199,7 @@ const ReactElement = function (type, key, ref, self, source, owner, props) {
|
|||
}
|
||||
|
||||
return element;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* https://github.com/reactjs/rfcs/pull/107
|
||||
|
|
|
@ -16,7 +16,7 @@ if (typeof ReactFbErrorUtils.invokeGuardedCallback !== 'function') {
|
|||
);
|
||||
}
|
||||
|
||||
const invokeGuardedCallbackImpl = function <A, B, C, D, E, F, Context>(
|
||||
function invokeGuardedCallbackImpl<A, B, C, D, E, F, Context>(
|
||||
name: string | null,
|
||||
func: (a: A, b: B, c: C, d: D, e: E, f: F) => mixed,
|
||||
context: Context,
|
||||
|
@ -29,6 +29,6 @@ const invokeGuardedCallbackImpl = function <A, B, C, D, E, F, Context>(
|
|||
) {
|
||||
// This will call `this.onError(err)` if an error was caught.
|
||||
ReactFbErrorUtils.invokeGuardedCallback.apply(this, arguments);
|
||||
};
|
||||
}
|
||||
|
||||
export default invokeGuardedCallbackImpl;
|
||||
|
|
Loading…
Reference in New Issue