@samitouri / QOS-React-2 / commits / d310d654a7

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__) { ... } } ```

Sebastian Markbåge committed Mar 14, 2023 at 21:00 UTC d310d654a7c7aab6c8213da84ef36dfba82711b0
24 files changed +628 -652
packages/dom-event-testing-library/domEnvironment.js
+1 -1
@@ -13,7 +13,7 @@
13 * Change environment support for PointerEvent.
14 */
15
16 -const emptyFunction = function () {};
16 +function emptyFunction() {}
17
18 export function hasPointerEvent() {
19 return global != null && global.PointerEvent != null;
packages/react-dom-bindings/src/client/ReactDOMComponent.js
+33 -33
@@ -94,15 +94,8 @@ const HTML = '__html';
94 let warnedUnknownTags: {
95 [key: string]: boolean,
96 };
97 -
98 -let validatePropertiesInDevelopment;
99 -let warnForPropDifference;
100 -let warnForExtraAttributes;
101 -let warnForInvalidEventListener;
97 let canDiffStyleForHydrationWarning;
98
104 -let normalizeHTML;
105 -
99 if (__DEV__) {
100 warnedUnknownTags = {
101 // There are working polyfills for <dialog>. Let people use it.
@@ -115,15 +108,6 @@ if (__DEV__) {
108 webview: true,
109 };
110
118 - validatePropertiesInDevelopment = function (type: string, props: any) {
119 - validateARIAProperties(type, props);
120 - validateInputProperties(type, props);
121 - validateUnknownProperties(type, props, {
122 - registrationNameDependencies,
123 - possibleRegistrationNames,
124 - });
125 - };
126 -
111 // IE 11 parses & normalizes the style attribute as opposed to other
112 // browsers. It adds spaces and sorts the properties in some
113 // non-alphabetical order. Handling that would require sorting CSS
@@ -133,12 +117,25 @@ if (__DEV__) {
117 // in that browser completely in favor of doing all that work.
118 // See https://github.com/facebook/react/issues/11807
119 canDiffStyleForHydrationWarning = canUseDOM && !document.documentMode;
120 +}
121
137 - warnForPropDifference = function (
138 - propName: string,
139 - serverValue: mixed,
140 - clientValue: mixed,
141 - ) {
122 +function validatePropertiesInDevelopment(type: string, props: any) {
123 + if (__DEV__) {
124 + validateARIAProperties(type, props);
125 + validateInputProperties(type, props);
126 + validateUnknownProperties(type, props, {
127 + registrationNameDependencies,
128 + possibleRegistrationNames,
129 + });
130 + }
131 +}
132 +
133 +function warnForPropDifference(
134 + propName: string,
135 + serverValue: mixed,
136 + clientValue: mixed,
137 +) {
138 + if (__DEV__) {
139 if (didWarnInvalidHydration) {
140 return;
141 }
@@ -156,9 +153,11 @@ if (__DEV__) {
153 JSON.stringify(normalizedServerValue),
154 JSON.stringify(normalizedClientValue),
155 );
159 - };
156 + }
157 +}
158
161 - warnForExtraAttributes = function (attributeNames: Set<string>) {
159 +function warnForExtraAttributes(attributeNames: Set<string>) {
160 + if (__DEV__) {
161 if (didWarnInvalidHydration) {
162 return;
163 }
@@ -168,12 +167,11 @@ if (__DEV__) {
167 names.push(name);
168 });
169 console.error('Extra attributes from the server: %s', names);
171 - };
170 + }
171 +}
172
173 - warnForInvalidEventListener = function (
174 - registrationName: string,
175 - listener: any,
176 - ) {
173 +function warnForInvalidEventListener(registrationName: string, listener: any) {
174 + if (__DEV__) {
175 if (listener === false) {
176 console.error(
177 'Expected `%s` listener to be a function, instead got `false`.\n\n' +
@@ -190,11 +188,13 @@ if (__DEV__) {
188 typeof listener,
189 );
190 }
193 - };
191 + }
192 +}
193
195 - // Parse the HTML and read it back to normalize the HTML string so that it
196 - // can be used for comparison.
197 - normalizeHTML = function (parent: Element, html: string) {
194 +// Parse the HTML and read it back to normalize the HTML string so that it
195 +// can be used for comparison.
196 +function normalizeHTML(parent: Element, html: string) {
197 + if (__DEV__) {
198 // We could have created a separate document here to avoid
199 // re-initializing custom elements if they exist. But this breaks
200 // how <noscript> is being handled. So we use the same document.
@@ -208,7 +208,7 @@ if (__DEV__) {
208 );
209 testElement.innerHTML = html;
210 return testElement.innerHTML;
211 - };
211 + }
212 }
213
214 // HTML parsing normalizes CR and CRLF to LF.
packages/react-dom-bindings/src/client/createMicrosoftUnsafeLocalFunction.js deleted
-25
@@ -1,25 +0,0 @@
1 -/**
2 - * Copyright (c) Meta Platforms, Inc. and affiliates.
3 - *
4 - * This source code is licensed under the MIT license found in the
5 - * LICENSE file in the root directory of this source tree.
6 - */
7 -
8 -/* globals MSApp */
9 -
10 -/**
11 - * Create a function which has 'unsafe' privileges (required by windows8 apps)
12 - */
13 -const createMicrosoftUnsafeLocalFunction = function (func) {
14 - if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
15 - return function (arg0, arg1, arg2, arg3) {
16 - MSApp.execUnsafeLocalFunction(function () {
17 - return func(arg0, arg1, arg2, arg3);
18 - });
19 - };
20 - } else {
21 - return func;
22 - }
23 -};
24 -
25 -export default createMicrosoftUnsafeLocalFunction;
packages/react-dom-bindings/src/client/setInnerHTML.js
+24 -13
@@ -7,24 +7,15 @@
7 * @flow
8 */
9
10 +/* globals MSApp */
11 +
12 import {SVG_NAMESPACE} from './DOMNamespaces';
11 -import createMicrosoftUnsafeLocalFunction from './createMicrosoftUnsafeLocalFunction';
13 import {enableTrustedTypesIntegration} from 'shared/ReactFeatureFlags';
14
15 // SVG temp container for IE lacking innerHTML
16 let reusableSVGContainer: HTMLElement;
17
17 -/**
18 - * Set the innerHTML property of a node
19 - *
20 - * @param {DOMElement} node
21 - * @param {string} html
22 - * @internal
23 - */
24 -const setInnerHTML: (
25 - node: Element,
26 - html: {valueOf(): {toString(): string, ...}, ...},
27 -) => void = createMicrosoftUnsafeLocalFunction(function (
18 +function setInnerHTMLImpl(
19 node: Element,
20 html: {valueOf(): {toString(): string, ...}, ...},
21 ): void {
@@ -66,6 +57,26 @@ const setInnerHTML: (
57 }
58 }
59 node.innerHTML = (html: any);
69 -});
60 +}
61 +
62 +let setInnerHTML: (
63 + node: Element,
64 + html: {valueOf(): {toString(): string, ...}, ...},
65 +) => void = setInnerHTMLImpl;
66 +// $FlowFixMe[cannot-resolve-name]
67 +if (typeof MSApp !== 'undefined' && MSApp.execUnsafeLocalFunction) {
68 + /**
69 + * Create a function which has 'unsafe' privileges (required by windows8 apps)
70 + */
71 + setInnerHTML = function (
72 + node: Element,
73 + html: {valueOf(): {toString(): string, ...}, ...},
74 + ): void {
75 + // $FlowFixMe[cannot-resolve-name]
76 + return MSApp.execUnsafeLocalFunction(function () {
77 + return setInnerHTMLImpl(node, html);
78 + });
79 + };
80 +}
81
82 export default setInnerHTML;
packages/react-dom-bindings/src/client/setTextContent.js
+2 -2
@@ -18,7 +18,7 @@ import {TEXT_NODE} from './HTMLNodeType';
18 * @param {string} text
19 * @internal
20 */
21 -const setTextContent = function (node: Element, text: string): void {
21 +function setTextContent(node: Element, text: string): void {
22 if (text) {
23 const firstChild = node.firstChild;
24
@@ -32,6 +32,6 @@ const setTextContent = function (node: Element, text: string): void {
32 }
33 }
34 node.textContent = text;
35 -};
35 +}
36
37 export default setTextContent;
packages/react-dom-bindings/src/client/validateDOMNesting.js
+357 -359
@@ -7,12 +7,6 @@
7 * @flow
8 */
9
10 -type ValidateDOMNesting = (?string, ?string, AncestorInfoDev) => void;
11 -let validateDOMNesting: ValidateDOMNesting = (() => {}: any);
12 -
13 -type UpdatedAncestorInfoDev = (?AncestorInfoDev, string) => AncestorInfoDev;
14 -let updatedAncestorInfoDev: UpdatedAncestorInfoDev = (() => {}: any);
15 -
10 type Info = {tag: string};
11 export type AncestorInfoDev = {
12 current: ?Info,
@@ -30,156 +24,159 @@ export type AncestorInfoDev = {
24 containerTagInScope: ?Info,
25 };
26
33 -if (__DEV__) {
34 - // This validation code was written based on the HTML5 parsing spec:
35 - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
36 - //
37 - // Note: this does not catch all invalid nesting, nor does it try to (as it's
38 - // not clear what practical benefit doing so provides); instead, we warn only
39 - // for cases where the parser will give a parse tree differing from what React
40 - // intended. For example, <b><div></div></b> is invalid but we don't warn
41 - // because it still parses correctly; we do warn for other cases like nested
42 - // <p> tags where the beginning of the second element implicitly closes the
43 - // first, causing a confusing mess.
44 -
45 - // https://html.spec.whatwg.org/multipage/syntax.html#special
46 - const specialTags = [
47 - 'address',
48 - 'applet',
49 - 'area',
50 - 'article',
51 - 'aside',
52 - 'base',
53 - 'basefont',
54 - 'bgsound',
55 - 'blockquote',
56 - 'body',
57 - 'br',
58 - 'button',
59 - 'caption',
60 - 'center',
61 - 'col',
62 - 'colgroup',
63 - 'dd',
64 - 'details',
65 - 'dir',
66 - 'div',
67 - 'dl',
68 - 'dt',
69 - 'embed',
70 - 'fieldset',
71 - 'figcaption',
72 - 'figure',
73 - 'footer',
74 - 'form',
75 - 'frame',
76 - 'frameset',
77 - 'h1',
78 - 'h2',
79 - 'h3',
80 - 'h4',
81 - 'h5',
82 - 'h6',
83 - 'head',
84 - 'header',
85 - 'hgroup',
86 - 'hr',
87 - 'html',
88 - 'iframe',
89 - 'img',
90 - 'input',
91 - 'isindex',
92 - 'li',
93 - 'link',
94 - 'listing',
95 - 'main',
96 - 'marquee',
97 - 'menu',
98 - 'menuitem',
99 - 'meta',
100 - 'nav',
101 - 'noembed',
102 - 'noframes',
103 - 'noscript',
104 - 'object',
105 - 'ol',
106 - 'p',
107 - 'param',
108 - 'plaintext',
109 - 'pre',
110 - 'script',
111 - 'section',
112 - 'select',
113 - 'source',
114 - 'style',
115 - 'summary',
116 - 'table',
117 - 'tbody',
118 - 'td',
119 - 'template',
120 - 'textarea',
121 - 'tfoot',
122 - 'th',
123 - 'thead',
124 - 'title',
125 - 'tr',
126 - 'track',
127 - 'ul',
128 - 'wbr',
129 - 'xmp',
130 - ];
131 -
132 - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
133 - const inScopeTags = [
134 - 'applet',
135 - 'caption',
136 - 'html',
137 - 'table',
138 - 'td',
139 - 'th',
140 - 'marquee',
141 - 'object',
142 - 'template',
143 -
144 - // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
145 - // TODO: Distinguish by namespace here -- for <title>, including it here
146 - // errs on the side of fewer warnings
147 - 'foreignObject',
148 - 'desc',
149 - 'title',
150 - ];
151 -
152 - // https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
153 - const buttonScopeTags = inScopeTags.concat(['button']);
154 -
155 - // https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
156 - const impliedEndTags = [
157 - 'dd',
158 - 'dt',
159 - 'li',
160 - 'option',
161 - 'optgroup',
162 - 'p',
163 - 'rp',
164 - 'rt',
165 - ];
166 -
167 - const emptyAncestorInfoDev: AncestorInfoDev = {
168 - current: null,
169 -
170 - formTag: null,
171 - aTagInScope: null,
172 - buttonTagInScope: null,
173 - nobrTagInScope: null,
174 - pTagInButtonScope: null,
175 -
176 - listItemTagAutoclosing: null,
177 - dlItemTagAutoclosing: null,
178 -
179 - containerTagInScope: null,
180 - };
181 -
182 - updatedAncestorInfoDev = function (oldInfo: ?AncestorInfoDev, tag: string) {
27 +// This validation code was written based on the HTML5 parsing spec:
28 +// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
29 +//
30 +// Note: this does not catch all invalid nesting, nor does it try to (as it's
31 +// not clear what practical benefit doing so provides); instead, we warn only
32 +// for cases where the parser will give a parse tree differing from what React
33 +// intended. For example, <b><div></div></b> is invalid but we don't warn
34 +// because it still parses correctly; we do warn for other cases like nested
35 +// <p> tags where the beginning of the second element implicitly closes the
36 +// first, causing a confusing mess.
37 +
38 +// https://html.spec.whatwg.org/multipage/syntax.html#special
39 +const specialTags = [
40 + 'address',
41 + 'applet',
42 + 'area',
43 + 'article',
44 + 'aside',
45 + 'base',
46 + 'basefont',
47 + 'bgsound',
48 + 'blockquote',
49 + 'body',
50 + 'br',
51 + 'button',
52 + 'caption',
53 + 'center',
54 + 'col',
55 + 'colgroup',
56 + 'dd',
57 + 'details',
58 + 'dir',
59 + 'div',
60 + 'dl',
61 + 'dt',
62 + 'embed',
63 + 'fieldset',
64 + 'figcaption',
65 + 'figure',
66 + 'footer',
67 + 'form',
68 + 'frame',
69 + 'frameset',
70 + 'h1',
71 + 'h2',
72 + 'h3',
73 + 'h4',
74 + 'h5',
75 + 'h6',
76 + 'head',
77 + 'header',
78 + 'hgroup',
79 + 'hr',
80 + 'html',
81 + 'iframe',
82 + 'img',
83 + 'input',
84 + 'isindex',
85 + 'li',
86 + 'link',
87 + 'listing',
88 + 'main',
89 + 'marquee',
90 + 'menu',
91 + 'menuitem',
92 + 'meta',
93 + 'nav',
94 + 'noembed',
95 + 'noframes',
96 + 'noscript',
97 + 'object',
98 + 'ol',
99 + 'p',
100 + 'param',
101 + 'plaintext',
102 + 'pre',
103 + 'script',
104 + 'section',
105 + 'select',
106 + 'source',
107 + 'style',
108 + 'summary',
109 + 'table',
110 + 'tbody',
111 + 'td',
112 + 'template',
113 + 'textarea',
114 + 'tfoot',
115 + 'th',
116 + 'thead',
117 + 'title',
118 + 'tr',
119 + 'track',
120 + 'ul',
121 + 'wbr',
122 + 'xmp',
123 +];
124 +
125 +// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-scope
126 +const inScopeTags = [
127 + 'applet',
128 + 'caption',
129 + 'html',
130 + 'table',
131 + 'td',
132 + 'th',
133 + 'marquee',
134 + 'object',
135 + 'template',
136 +
137 + // https://html.spec.whatwg.org/multipage/syntax.html#html-integration-point
138 + // TODO: Distinguish by namespace here -- for <title>, including it here
139 + // errs on the side of fewer warnings
140 + 'foreignObject',
141 + 'desc',
142 + 'title',
143 +];
144 +
145 +// https://html.spec.whatwg.org/multipage/syntax.html#has-an-element-in-button-scope
146 +const buttonScopeTags = __DEV__ ? inScopeTags.concat(['button']) : [];
147 +
148 +// https://html.spec.whatwg.org/multipage/syntax.html#generate-implied-end-tags
149 +const impliedEndTags = [
150 + 'dd',
151 + 'dt',
152 + 'li',
153 + 'option',
154 + 'optgroup',
155 + 'p',
156 + 'rp',
157 + 'rt',
158 +];
159 +
160 +const emptyAncestorInfoDev: AncestorInfoDev = {
161 + current: null,
162 +
163 + formTag: null,
164 + aTagInScope: null,
165 + buttonTagInScope: null,
166 + nobrTagInScope: null,
167 + pTagInButtonScope: null,
168 +
169 + listItemTagAutoclosing: null,
170 + dlItemTagAutoclosing: null,
171 +
172 + containerTagInScope: null,
173 +};
174 +
175 +function updatedAncestorInfoDev(
176 + oldInfo: ?AncestorInfoDev,
177 + tag: string,
178 +): AncestorInfoDev {
179 + if (__DEV__) {
180 const ancestorInfo = {...(oldInfo || emptyAncestorInfoDev)};
181 const info = {tag};
182
@@ -234,213 +231,214 @@ if (__DEV__) {
231 }
232
233 return ancestorInfo;
237 - };
238 -
239 - /**
240 - * Returns whether
241 - */
242 - const isTagValidWithParent = function (
243 - tag: string,
244 - parentTag: ?string,
245 - ): boolean {
246 - // First, let's check if we're in an unusual parsing mode...
247 - switch (parentTag) {
248 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
249 - case 'select':
250 - return tag === 'option' || tag === 'optgroup' || tag === '#text';
251 - case 'optgroup':
252 - return tag === 'option' || tag === '#text';
253 - // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
254 - // but
255 - case 'option':
256 - return tag === '#text';
257 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
258 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
259 - // No special behavior since these rules fall back to "in body" mode for
260 - // all except special table nodes which cause bad parsing behavior anyway.
261 -
262 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
263 - case 'tr':
264 - return (
265 - tag === 'th' ||
266 - tag === 'td' ||
267 - tag === 'style' ||
268 - tag === 'script' ||
269 - tag === 'template'
270 - );
271 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
272 - case 'tbody':
273 - case 'thead':
274 - case 'tfoot':
275 - return (
276 - tag === 'tr' ||
277 - tag === 'style' ||
278 - tag === 'script' ||
279 - tag === 'template'
280 - );
281 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
282 - case 'colgroup':
283 - return tag === 'col' || tag === 'template';
284 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
285 - case 'table':
286 - return (
287 - tag === 'caption' ||
288 - tag === 'colgroup' ||
289 - tag === 'tbody' ||
290 - tag === 'tfoot' ||
291 - tag === 'thead' ||
292 - tag === 'style' ||
293 - tag === 'script' ||
294 - tag === 'template'
295 - );
296 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
297 - case 'head':
298 - return (
299 - tag === 'base' ||
300 - tag === 'basefont' ||
301 - tag === 'bgsound' ||
302 - tag === 'link' ||
303 - tag === 'meta' ||
304 - tag === 'title' ||
305 - tag === 'noscript' ||
306 - tag === 'noframes' ||
307 - tag === 'style' ||
308 - tag === 'script' ||
309 - tag === 'template'
310 - );
311 - // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
312 - case 'html':
313 - return tag === 'head' || tag === 'body' || tag === 'frameset';
314 - case 'frameset':
315 - return tag === 'frame';
316 - case '#document':
317 - return tag === 'html';
318 - }
319 -
320 - // Probably in the "in body" parsing mode, so we outlaw only tag combos
321 - // where the parsing rules cause implicit opens or closes to be added.
322 - // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
323 - switch (tag) {
324 - case 'h1':
325 - case 'h2':
326 - case 'h3':
327 - case 'h4':
328 - case 'h5':
329 - case 'h6':
330 - return (
331 - parentTag !== 'h1' &&
332 - parentTag !== 'h2' &&
333 - parentTag !== 'h3' &&
334 - parentTag !== 'h4' &&
335 - parentTag !== 'h5' &&
336 - parentTag !== 'h6'
337 - );
234 + } else {
235 + return (null: any);
236 + }
237 +}
238
339 - case 'rp':
340 - case 'rt':
341 - return impliedEndTags.indexOf(parentTag) === -1;
342 -
343 - case 'body':
344 - case 'caption':
345 - case 'col':
346 - case 'colgroup':
347 - case 'frameset':
348 - case 'frame':
349 - case 'head':
350 - case 'html':
351 - case 'tbody':
352 - case 'td':
353 - case 'tfoot':
354 - case 'th':
355 - case 'thead':
356 - case 'tr':
357 - // These tags are only valid with a few parents that have special child
358 - // parsing rules -- if we're down here, then none of those matched and
359 - // so we allow it only if we don't know what the parent is, as all other
360 - // cases are invalid.
361 - return parentTag == null;
362 - }
239 +/**
240 + * Returns whether
241 + */
242 +function isTagValidWithParent(tag: string, parentTag: ?string): boolean {
243 + // First, let's check if we're in an unusual parsing mode...
244 + switch (parentTag) {
245 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inselect
246 + case 'select':
247 + return tag === 'option' || tag === 'optgroup' || tag === '#text';
248 + case 'optgroup':
249 + return tag === 'option' || tag === '#text';
250 + // Strictly speaking, seeing an <option> doesn't mean we're in a <select>
251 + // but
252 + case 'option':
253 + return tag === '#text';
254 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intd
255 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incaption
256 + // No special behavior since these rules fall back to "in body" mode for
257 + // all except special table nodes which cause bad parsing behavior anyway.
258 +
259 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intr
260 + case 'tr':
261 + return (
262 + tag === 'th' ||
263 + tag === 'td' ||
264 + tag === 'style' ||
265 + tag === 'script' ||
266 + tag === 'template'
267 + );
268 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intbody
269 + case 'tbody':
270 + case 'thead':
271 + case 'tfoot':
272 + return (
273 + tag === 'tr' ||
274 + tag === 'style' ||
275 + tag === 'script' ||
276 + tag === 'template'
277 + );
278 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-incolgroup
279 + case 'colgroup':
280 + return tag === 'col' || tag === 'template';
281 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-intable
282 + case 'table':
283 + return (
284 + tag === 'caption' ||
285 + tag === 'colgroup' ||
286 + tag === 'tbody' ||
287 + tag === 'tfoot' ||
288 + tag === 'thead' ||
289 + tag === 'style' ||
290 + tag === 'script' ||
291 + tag === 'template'
292 + );
293 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inhead
294 + case 'head':
295 + return (
296 + tag === 'base' ||
297 + tag === 'basefont' ||
298 + tag === 'bgsound' ||
299 + tag === 'link' ||
300 + tag === 'meta' ||
301 + tag === 'title' ||
302 + tag === 'noscript' ||
303 + tag === 'noframes' ||
304 + tag === 'style' ||
305 + tag === 'script' ||
306 + tag === 'template'
307 + );
308 + // https://html.spec.whatwg.org/multipage/semantics.html#the-html-element
309 + case 'html':
310 + return tag === 'head' || tag === 'body' || tag === 'frameset';
311 + case 'frameset':
312 + return tag === 'frame';
313 + case '#document':
314 + return tag === 'html';
315 + }
316 +
317 + // Probably in the "in body" parsing mode, so we outlaw only tag combos
318 + // where the parsing rules cause implicit opens or closes to be added.
319 + // https://html.spec.whatwg.org/multipage/syntax.html#parsing-main-inbody
320 + switch (tag) {
321 + case 'h1':
322 + case 'h2':
323 + case 'h3':
324 + case 'h4':
325 + case 'h5':
326 + case 'h6':
327 + return (
328 + parentTag !== 'h1' &&
329 + parentTag !== 'h2' &&
330 + parentTag !== 'h3' &&
331 + parentTag !== 'h4' &&
332 + parentTag !== 'h5' &&
333 + parentTag !== 'h6'
334 + );
335
364 - return true;
365 - };
366 -
367 - /**
368 - * Returns whether
369 - */
370 - const findInvalidAncestorForTag = function (
371 - tag: string,
372 - ancestorInfo: AncestorInfoDev,
373 - ): ?Info {
374 - switch (tag) {
375 - case 'address':
376 - case 'article':
377 - case 'aside':
378 - case 'blockquote':
379 - case 'center':
380 - case 'details':
381 - case 'dialog':
382 - case 'dir':
383 - case 'div':
384 - case 'dl':
385 - case 'fieldset':
386 - case 'figcaption':
387 - case 'figure':
388 - case 'footer':
389 - case 'header':
390 - case 'hgroup':
391 - case 'main':
392 - case 'menu':
393 - case 'nav':
394 - case 'ol':
395 - case 'p':
396 - case 'section':
397 - case 'summary':
398 - case 'ul':
399 - case 'pre':
400 - case 'listing':
401 - case 'table':
402 - case 'hr':
403 - case 'xmp':
404 - case 'h1':
405 - case 'h2':
406 - case 'h3':
407 - case 'h4':
408 - case 'h5':
409 - case 'h6':
410 - return ancestorInfo.pTagInButtonScope;
411 -
412 - case 'form':
413 - return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
414 -
415 - case 'li':
416 - return ancestorInfo.listItemTagAutoclosing;
417 -
418 - case 'dd':
419 - case 'dt':
420 - return ancestorInfo.dlItemTagAutoclosing;
421 -
422 - case 'button':
423 - return ancestorInfo.buttonTagInScope;
424 -
425 - case 'a':
426 - // Spec says something about storing a list of markers, but it sounds
427 - // equivalent to this check.
428 - return ancestorInfo.aTagInScope;
429 -
430 - case 'nobr':
431 - return ancestorInfo.nobrTagInScope;
432 - }
336 + case 'rp':
337 + case 'rt':
338 + return impliedEndTags.indexOf(parentTag) === -1;
339 +
340 + case 'body':
341 + case 'caption':
342 + case 'col':
343 + case 'colgroup':
344 + case 'frameset':
345 + case 'frame':
346 + case 'head':
347 + case 'html':
348 + case 'tbody':
349 + case 'td':
350 + case 'tfoot':
351 + case 'th':
352 + case 'thead':
353 + case 'tr':
354 + // These tags are only valid with a few parents that have special child
355 + // parsing rules -- if we're down here, then none of those matched and
356 + // so we allow it only if we don't know what the parent is, as all other
357 + // cases are invalid.
358 + return parentTag == null;
359 + }
360 +
361 + return true;
362 +}
363
434 - return null;
435 - };
364 +/**
365 + * Returns whether
366 + */
367 +function findInvalidAncestorForTag(
368 + tag: string,
369 + ancestorInfo: AncestorInfoDev,
370 +): ?Info {
371 + switch (tag) {
372 + case 'address':
373 + case 'article':
374 + case 'aside':
375 + case 'blockquote':
376 + case 'center':
377 + case 'details':
378 + case 'dialog':
379 + case 'dir':
380 + case 'div':
381 + case 'dl':
382 + case 'fieldset':
383 + case 'figcaption':
384 + case 'figure':
385 + case 'footer':
386 + case 'header':
387 + case 'hgroup':
388 + case 'main':
389 + case 'menu':
390 + case 'nav':
391 + case 'ol':
392 + case 'p':
393 + case 'section':
394 + case 'summary':
395 + case 'ul':
396 + case 'pre':
397 + case 'listing':
398 + case 'table':
399 + case 'hr':
400 + case 'xmp':
401 + case 'h1':
402 + case 'h2':
403 + case 'h3':
404 + case 'h4':
405 + case 'h5':
406 + case 'h6':
407 + return ancestorInfo.pTagInButtonScope;
408 +
409 + case 'form':
410 + return ancestorInfo.formTag || ancestorInfo.pTagInButtonScope;
411 +
412 + case 'li':
413 + return ancestorInfo.listItemTagAutoclosing;
414 +
415 + case 'dd':
416 + case 'dt':
417 + return ancestorInfo.dlItemTagAutoclosing;
418 +
419 + case 'button':
420 + return ancestorInfo.buttonTagInScope;
421 +
422 + case 'a':
423 + // Spec says something about storing a list of markers, but it sounds
424 + // equivalent to this check.
425 + return ancestorInfo.aTagInScope;
426 +
427 + case 'nobr':
428 + return ancestorInfo.nobrTagInScope;
429 + }
430 +
431 + return null;
432 +}
433
437 - const didWarn: {[string]: boolean} = {};
434 +const didWarn: {[string]: boolean} = {};
435
439 - validateDOMNesting = function (
440 - childTag: ?string,
441 - childText: ?string,
442 - ancestorInfo: AncestorInfoDev,
443 - ) {
436 +function validateDOMNesting(
437 + childTag: ?string,
438 + childText: ?string,
439 + ancestorInfo: AncestorInfoDev,
440 +): void {
441 + if (__DEV__) {
442 ancestorInfo = ancestorInfo || emptyAncestorInfoDev;
443 const parentInfo = ancestorInfo.current;
444 const parentTag = parentInfo && parentInfo.tag;
@@ -517,7 +515,7 @@ if (__DEV__) {
515 ancestorTag,
516 );
517 }
520 - };
518 + }
519 }
520
521 export {updatedAncestorInfoDev, validateDOMNesting};
packages/react-dom-bindings/src/shared/ReactDOMUnknownPropertyHook.js
+14 -12
@@ -16,16 +16,18 @@ import isCustomComponent from './isCustomComponent';
16 import possibleStandardNames from './possibleStandardNames';
17 import hasOwnProperty from 'shared/hasOwnProperty';
18
19 -let validateProperty = () => {};
19 +const warnedProperties = {};
20 +const EVENT_NAME_REGEX = /^on./;
21 +const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
22 +const rARIA = __DEV__
23 + ? new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$')
24 + : null;
25 +const rARIACamel = __DEV__
26 + ? new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$')
27 + : null;
28
21 -if (__DEV__) {
22 - const warnedProperties = {};
23 - const EVENT_NAME_REGEX = /^on./;
24 - const INVALID_EVENT_NAME_REGEX = /^on[^A-Z]/;
25 - const rARIA = new RegExp('^(aria)-[' + ATTRIBUTE_NAME_CHAR + ']*$');
26 - const rARIACamel = new RegExp('^(aria)[A-Z][' + ATTRIBUTE_NAME_CHAR + ']*$');
27 -
28 - validateProperty = function (tagName, name, value, eventRegistry) {
29 +function validateProperty(tagName, name, value, eventRegistry) {
30 + if (__DEV__) {
31 if (hasOwnProperty.call(warnedProperties, name) && warnedProperties[name]) {
32 return true;
33 }
@@ -234,10 +236,10 @@ if (__DEV__) {
236 }
237
238 return true;
237 - };
239 + }
240 }
241
240 -const warnUnknownProperties = function (type, props, eventRegistry) {
242 +function warnUnknownProperties(type, props, eventRegistry) {
243 if (__DEV__) {
244 const unknownProps = [];
245 for (const key in props) {
@@ -268,7 +270,7 @@ const warnUnknownProperties = function (type, props, eventRegistry) {
270 );
271 }
272 }
271 -};
273 +}
274
275 export function validateProperties(type, props, eventRegistry) {
276 if (isCustomComponent(type, props)) {
packages/react-dom-bindings/src/shared/warnValidStyle.js
+41 -33
@@ -5,29 +5,27 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -let warnValidStyle = () => {};
9 -
10 -if (__DEV__) {
11 - // 'msTransform' is correct, but the other prefixes should be capitalized
12 - const badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
13 - const msPattern = /^-ms-/;
14 - const hyphenPattern = /-(.)/g;
15 -
16 - // style values shouldn't contain a semicolon
17 - const badStyleValueWithSemicolonPattern = /;\s*$/;
18 -
19 - const warnedStyleNames = {};
20 - const warnedStyleValues = {};
21 - let warnedForNaNValue = false;
22 - let warnedForInfinityValue = false;
23 -
24 - const camelize = function (string) {
25 - return string.replace(hyphenPattern, function (_, character) {
26 - return character.toUpperCase();
27 - });
28 - };
8 +// 'msTransform' is correct, but the other prefixes should be capitalized
9 +const badVendoredStyleNamePattern = /^(?:webkit|moz|o)[A-Z]/;
10 +const msPattern = /^-ms-/;
11 +const hyphenPattern = /-(.)/g;
12 +
13 +// style values shouldn't contain a semicolon
14 +const badStyleValueWithSemicolonPattern = /;\s*$/;
15 +
16 +const warnedStyleNames = {};
17 +const warnedStyleValues = {};
18 +let warnedForNaNValue = false;
19 +let warnedForInfinityValue = false;
20 +
21 +function camelize(string) {
22 + return string.replace(hyphenPattern, function (_, character) {
23 + return character.toUpperCase();
24 + });
25 +}
26
30 - const warnHyphenatedStyleName = function (name) {
27 +function warnHyphenatedStyleName(name) {
28 + if (__DEV__) {
29 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
30 return;
31 }
@@ -41,9 +39,11 @@ if (__DEV__) {
39 // is converted to lowercase `ms`.
40 camelize(name.replace(msPattern, 'ms-')),
41 );
44 - };
42 + }
43 +}
44
46 - const warnBadVendoredStyleName = function (name) {
45 +function warnBadVendoredStyleName(name) {
46 + if (__DEV__) {
47 if (warnedStyleNames.hasOwnProperty(name) && warnedStyleNames[name]) {
48 return;
49 }
@@ -54,9 +54,11 @@ if (__DEV__) {
54 name,
55 name.charAt(0).toUpperCase() + name.slice(1),
56 );
57 - };
57 + }
58 +}
59
59 - const warnStyleValueWithSemicolon = function (name, value) {
60 +function warnStyleValueWithSemicolon(name, value) {
61 + if (__DEV__) {
62 if (warnedStyleValues.hasOwnProperty(value) && warnedStyleValues[value]) {
63 return;
64 }
@@ -68,9 +70,11 @@ if (__DEV__) {
70 name,
71 value.replace(badStyleValueWithSemicolonPattern, ''),
72 );
71 - };
73 + }
74 +}
75
73 - const warnStyleValueIsNaN = function (name, value) {
76 +function warnStyleValueIsNaN(name, value) {
77 + if (__DEV__) {
78 if (warnedForNaNValue) {
79 return;
80 }
@@ -80,9 +84,11 @@ if (__DEV__) {
84 '`NaN` is an invalid value for the `%s` css style property.',
85 name,
86 );
83 - };
87 + }
88 +}
89
85 - const warnStyleValueIsInfinity = function (name, value) {
90 +function warnStyleValueIsInfinity(name, value) {
91 + if (__DEV__) {
92 if (warnedForInfinityValue) {
93 return;
94 }
@@ -92,9 +98,11 @@ if (__DEV__) {
98 '`Infinity` is an invalid value for the `%s` css style property.',
99 name,
100 );
95 - };
101 + }
102 +}
103
97 - warnValidStyle = function (name, value) {
104 +function warnValidStyle(name, value) {
105 + if (__DEV__) {
106 if (name.indexOf('-') > -1) {
107 warnHyphenatedStyleName(name);
108 } else if (badVendoredStyleNamePattern.test(name)) {
@@ -110,7 +118,7 @@ if (__DEV__) {
118 warnStyleValueIsInfinity(name, value);
119 }
120 }
113 - };
121 + }
122 }
123
124 export default warnValidStyle;
packages/react-dom/src/test-utils/ReactTestUtils.js
+2 -2
@@ -392,7 +392,7 @@ function executeDispatchesInOrder(event) {
392 * @param {?object} event Synthetic event to be dispatched.
393 * @private
394 */
395 -const executeDispatchesAndRelease = function (event /* ReactSyntheticEvent */) {
395 +function executeDispatchesAndRelease(event /* ReactSyntheticEvent */) {
396 if (event) {
397 executeDispatchesInOrder(event);
398
@@ -400,7 +400,7 @@ const executeDispatchesAndRelease = function (event /* ReactSyntheticEvent */) {
400 event.constructor.release(event);
401 }
402 }
403 -};
403 +}
404
405 function isInteractive(tag) {
406 return (
packages/react-native-renderer/src/ReactNativeEventEmitter.js
+4 -4
@@ -44,13 +44,13 @@ const EMPTY_NATIVE_EVENT = (({}: any): AnyNativeEvent);
44 * @return {Array<Touch>} Subsequence of touch objects.
45 */
46 // $FlowFixMe[missing-local-annot]
47 -const touchSubsequence = function (touches, indices) {
47 +function touchSubsequence(touches, indices) {
48 const ret = [];
49 for (let i = 0; i < indices.length; i++) {
50 ret.push(touches[indices[i]]);
51 }
52 return ret;
53 -};
53 +}
54
55 /**
56 * TODO: Pool all of this.
@@ -63,7 +63,7 @@ const touchSubsequence = function (touches, indices) {
63 * @param {Array<number>} indices Indices to remove from `touches`.
64 * @return {Array<Touch>} Subsequence of removed touch objects.
65 */
66 -const removeTouchesAtIndices = function (
66 +function removeTouchesAtIndices(
67 touches: Array<Object>,
68 indices: Array<number>,
69 ): Array<Object> {
@@ -85,7 +85,7 @@ const removeTouchesAtIndices = function (
85 }
86 temp.length = fillAt;
87 return rippedOut;
88 -};
88 +}
89
90 /**
91 * Internal version of `receiveEvent` in terms of normalized (non-tag)
packages/react-native-renderer/src/ReactNativeFiberInspector.js
+88 -106
@@ -28,49 +28,39 @@ if (__DEV__) {
28 Object.freeze(emptyObject);
29 }
30
31 -let createHierarchy;
32 -let getHostNode;
33 -let getHostProps;
34 -let lastNonHostInstance;
35 -let getInspectorDataForInstance: (
36 - closestInstance: Fiber | null,
37 -) => InspectorData;
38 -let getOwnerHierarchy;
39 -let traverseOwnerTreeUp: (hierarchy: Array<$FlowFixMe>, instance: any) => void;
40 -
41 -if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
42 - // $FlowFixMe[missing-local-annot]
43 - createHierarchy = function (fiberHierarchy) {
44 - return fiberHierarchy.map(fiber => ({
45 - name: getComponentNameFromType(fiber.type),
46 - getInspectorData: findNodeHandle => {
47 - return {
48 - props: getHostProps(fiber),
49 - source: fiber._debugSource,
50 - measure: callback => {
51 - // If this is Fabric, we'll find a shadow node and use that to measure.
52 - const hostFiber = findCurrentHostFiber(fiber);
53 - const node =
54 - hostFiber != null &&
55 - hostFiber.stateNode !== null &&
56 - hostFiber.stateNode.node;
31 +// $FlowFixMe[missing-local-annot]
32 +function createHierarchy(fiberHierarchy) {
33 + return fiberHierarchy.map(fiber => ({
34 + name: getComponentNameFromType(fiber.type),
35 + getInspectorData: findNodeHandle => {
36 + return {
37 + props: getHostProps(fiber),
38 + source: fiber._debugSource,
39 + measure: callback => {
40 + // If this is Fabric, we'll find a shadow node and use that to measure.
41 + const hostFiber = findCurrentHostFiber(fiber);
42 + const node =
43 + hostFiber != null &&
44 + hostFiber.stateNode !== null &&
45 + hostFiber.stateNode.node;
46
58 - if (node) {
59 - nativeFabricUIManager.measure(node, callback);
60 - } else {
61 - return UIManager.measure(
62 - getHostNode(fiber, findNodeHandle),
63 - callback,
64 - );
65 - }
66 - },
67 - };
68 - },
69 - }));
70 - };
47 + if (node) {
48 + nativeFabricUIManager.measure(node, callback);
49 + } else {
50 + return UIManager.measure(
51 + getHostNode(fiber, findNodeHandle),
52 + callback,
53 + );
54 + }
55 + },
56 + };
57 + },
58 + }));
59 +}
60
72 - // $FlowFixMe[missing-local-annot]
73 - getHostNode = function (fiber: Fiber | null, findNodeHandle) {
61 +// $FlowFixMe[missing-local-annot]
62 +function getHostNode(fiber: Fiber | null, findNodeHandle) {
63 + if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
64 let hostNode;
65 // look for children first for the hostNode
66 // as composite fibers do not have a hostNode
@@ -84,20 +74,22 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
74 fiber = fiber.child;
75 }
76 return null;
87 - };
77 + }
78 +}
79
89 - // $FlowFixMe[missing-local-annot]
90 - getHostProps = function (fiber) {
91 - const host = findCurrentHostFiber(fiber);
92 - if (host) {
93 - return host.memoizedProps || emptyObject;
94 - }
95 - return emptyObject;
96 - };
80 +// $FlowFixMe[missing-local-annot]
81 +function getHostProps(fiber) {
82 + const host = findCurrentHostFiber(fiber);
83 + if (host) {
84 + return host.memoizedProps || emptyObject;
85 + }
86 + return emptyObject;
87 +}
88
98 - getInspectorDataForInstance = function (
99 - closestInstance: Fiber | null,
100 - ): InspectorData {
89 +function getInspectorDataForInstance(
90 + closestInstance: Fiber | null,
91 +): InspectorData {
92 + if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
93 // Handle case where user clicks outside of ReactNative
94 if (!closestInstance) {
95 return {
@@ -123,46 +115,44 @@ if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
115 selectedIndex,
116 source,
117 };
126 - };
118 + } else {
119 + return (null: any);
120 + }
121 +}
122
128 - getOwnerHierarchy = function (instance: any) {
129 - const hierarchy: Array<$FlowFixMe> = [];
130 - traverseOwnerTreeUp(hierarchy, instance);
131 - return hierarchy;
132 - };
123 +function getOwnerHierarchy(instance: any) {
124 + const hierarchy: Array<$FlowFixMe> = [];
125 + traverseOwnerTreeUp(hierarchy, instance);
126 + return hierarchy;
127 +}
128
134 - // $FlowFixMe[missing-local-annot]
135 - lastNonHostInstance = function (hierarchy) {
136 - for (let i = hierarchy.length - 1; i > 1; i--) {
137 - const instance = hierarchy[i];
129 +// $FlowFixMe[missing-local-annot]
130 +function lastNonHostInstance(hierarchy) {
131 + for (let i = hierarchy.length - 1; i > 1; i--) {
132 + const instance = hierarchy[i];
133
139 - if (instance.tag !== HostComponent) {
140 - return instance;
141 - }
134 + if (instance.tag !== HostComponent) {
135 + return instance;
136 }
143 - return hierarchy[0];
144 - };
137 + }
138 + return hierarchy[0];
139 +}
140
146 - // $FlowFixMe[missing-local-annot]
147 - traverseOwnerTreeUp = function (hierarchy, instance: any): void {
141 +// $FlowFixMe[missing-local-annot]
142 +function traverseOwnerTreeUp(
143 + hierarchy: Array<$FlowFixMe>,
144 + instance: any,
145 +): void {
146 + if (__DEV__ || enableGetInspectorDataForInstanceInProduction) {
147 if (instance) {
148 hierarchy.unshift(instance);
149 traverseOwnerTreeUp(hierarchy, instance._debugOwner);
150 }
152 - };
151 + }
152 }
153
155 -let getInspectorDataForViewTag: (viewTag: number) => Object;
156 -let getInspectorDataForViewAtPoint: (
157 - findNodeHandle: (componentOrHandle: any) => ?number,
158 - inspectedView: Object,
159 - locationX: number,
160 - locationY: number,
161 - callback: (viewData: TouchedViewDataAtPoint) => mixed,
162 -) => void;
163 -
164 -if (__DEV__) {
165 - getInspectorDataForViewTag = function (viewTag: number): Object {
154 +function getInspectorDataForViewTag(viewTag: number): Object {
155 + if (__DEV__) {
156 const closestInstance = getClosestInstanceFromNode(viewTag);
157
158 // Handle case where user clicks outside of ReactNative
@@ -189,15 +179,21 @@ if (__DEV__) {
179 selectedIndex,
180 source,
181 };
192 - };
182 + } else {
183 + throw new Error(
184 + 'getInspectorDataForViewTag() is not available in production',
185 + );
186 + }
187 +}
188
194 - getInspectorDataForViewAtPoint = function (
195 - findNodeHandle: (componentOrHandle: any) => ?number,
196 - inspectedView: Object,
197 - locationX: number,
198 - locationY: number,
199 - callback: (viewData: TouchedViewDataAtPoint) => mixed,
200 - ): void {
189 +function getInspectorDataForViewAtPoint(
190 + findNodeHandle: (componentOrHandle: any) => ?number,
191 + inspectedView: Object,
192 + locationX: number,
193 + locationY: number,
194 + callback: (viewData: TouchedViewDataAtPoint) => mixed,
195 +): void {
196 + if (__DEV__) {
197 let closestInstance = null;
198
199 const fabricInstanceHandle =
@@ -271,25 +267,11 @@ if (__DEV__) {
267
268 return;
269 }
274 - };
275 -} else {
276 - getInspectorDataForViewTag = () => {
277 - throw new Error(
278 - 'getInspectorDataForViewTag() is not available in production',
279 - );
280 - };
281 -
282 - getInspectorDataForViewAtPoint = (
283 - findNodeHandle: (componentOrHandle: any) => ?number,
284 - inspectedView: Object,
285 - locationX: number,
286 - locationY: number,
287 - callback: (viewData: TouchedViewDataAtPoint) => mixed,
288 - ): void => {
270 + } else {
271 throw new Error(
272 'getInspectorDataForViewAtPoint() is not available in production.',
273 );
292 - };
274 + }
275 }
276
277 export {
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/deepDiffer.js
+2 -2
@@ -15,7 +15,7 @@ type Options = {+unsafelyIgnoreFunctions?: boolean};
15 /*
16 * @returns {bool} true if different, false if equal
17 */
18 -const deepDiffer = function (
18 +function deepDiffer(
19 one: any,
20 two: any,
21 maxDepthOrOptions: Options | number = -1,
@@ -79,6 +79,6 @@ const deepDiffer = function (
79 }
80 }
81 return false;
82 -};
82 +}
83
84 module.exports = deepDiffer;
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/deepFreezeAndThrowOnMutationInDev.js
+1 -1
@@ -9,6 +9,6 @@
9
10 // TODO: move into react or fbjs
11
12 -const deepFreezeAndThrowOnMutationInDev = function () {};
12 +function deepFreezeAndThrowOnMutationInDev() {}
13
14 module.exports = deepFreezeAndThrowOnMutationInDev;
packages/react-native-renderer/src/__mocks__/react-native/Libraries/ReactPrivate/flattenStyle.js
+1 -1
@@ -9,6 +9,6 @@
9
10 // TODO: Move flattenStyle into react
11
12 -const flattenStyle = function () {};
12 +function flattenStyle() {}
13
14 module.exports = flattenStyle;
packages/react-native-renderer/src/legacy-events/EventBatching.js
+4 -4
@@ -25,7 +25,7 @@ let eventQueue: ?(Array<ReactSyntheticEvent> | ReactSyntheticEvent) = null;
25 * @param {?object} event Synthetic event to be dispatched.
26 * @private
27 */
28 -const executeDispatchesAndRelease = function (event: ReactSyntheticEvent) {
28 +function executeDispatchesAndRelease(event: ReactSyntheticEvent) {
29 if (event) {
30 executeDispatchesInOrder(event);
31
@@ -33,11 +33,11 @@ const executeDispatchesAndRelease = function (event: ReactSyntheticEvent) {
33 event.constructor.release(event);
34 }
35 }
36 -};
36 +}
37 // $FlowFixMe[missing-local-annot]
38 -const executeDispatchesAndReleaseTopLevel = function (e) {
38 +function executeDispatchesAndReleaseTopLevel(e) {
39 return executeDispatchesAndRelease(e);
40 -};
40 +}
41
42 export function runEventsInBatch(
43 events: Array<ReactSyntheticEvent> | ReactSyntheticEvent | null,
packages/react-native-renderer/src/legacy-events/EventPluginUtils.js
+3 -4
@@ -30,9 +30,8 @@ export function setComponentTree(
30 }
31 }
32
33 -let validateEventDispatches;
34 -if (__DEV__) {
35 - validateEventDispatches = function (event) {
33 +function validateEventDispatches(event) {
34 + if (__DEV__) {
35 const dispatchListeners = event._dispatchListeners;
36 const dispatchInstances = event._dispatchInstances;
37
@@ -53,7 +52,7 @@ if (__DEV__) {
52 if (instancesIsArr !== listenersIsArr || instancesLen !== listenersLen) {
53 console.error('EventPluginUtils: Invalid `event`.');
54 }
56 - };
55 + }
56 }
57
58 /**
packages/react-native-renderer/src/legacy-events/ResponderEventPlugin.js
+2 -2
@@ -44,7 +44,7 @@ let responderInst = null;
44 */
45 let trackedTouchCount = 0;
46
47 -const changeResponder = function (nextResponderInst, blockHostResponder) {
47 +function changeResponder(nextResponderInst, blockHostResponder) {
48 const oldResponderInst = responderInst;
49 responderInst = nextResponderInst;
50 if (ResponderEventPlugin.GlobalResponderHandler !== null) {
@@ -54,7 +54,7 @@ const changeResponder = function (nextResponderInst, blockHostResponder) {
54 blockHostResponder,
55 );
56 }
57 -};
57 +}
58
59 const eventTypes = {
60 /**
packages/react-reconciler/src/ReactFiber.js
+2 -2
@@ -224,7 +224,7 @@ function FiberNode(
224 // is faster.
225 // 5) It should be easy to port this to a C struct and keep a C implementation
226 // compatible.
227 -const createFiber = function (
227 +function createFiber(
228 tag: WorkTag,
229 pendingProps: mixed,
230 key: null | string,
@@ -232,7 +232,7 @@ const createFiber = function (
232 ): Fiber {
233 // $FlowFixMe: the shapes are exact here but Flow doesn't like constructors
234 return new FiberNode(tag, pendingProps, key, mode);
235 -};
235 +}
236
237 function shouldConstruct(Component: Function) {
238 const prototype = Component.prototype;
packages/react-reconciler/src/ReactFiberClassComponent.js
+29 -27
@@ -85,11 +85,10 @@ let didWarnAboutUninitializedState;
85 let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
86 let didWarnAboutLegacyLifecyclesAndDerivedState;
87 let didWarnAboutUndefinedDerivedState;
88 -let warnOnUndefinedDerivedState;
89 -let warnOnInvalidCallback;
88 let didWarnAboutDirectlyAssigningPropsToState;
89 let didWarnAboutContextTypeAndContextTypes;
90 let didWarnAboutInvalidateContextType;
91 +let didWarnOnInvalidCallback;
92
93 if (__DEV__) {
94 didWarnAboutStateAssignmentForComponent = new Set<string>();
@@ -100,10 +99,31 @@ if (__DEV__) {
99 didWarnAboutUndefinedDerivedState = new Set<string>();
100 didWarnAboutContextTypeAndContextTypes = new Set<string>();
101 didWarnAboutInvalidateContextType = new Set<string>();
102 + didWarnOnInvalidCallback = new Set<string>();
103
104 - const didWarnOnInvalidCallback = new Set<string>();
104 + // This is so gross but it's at least non-critical and can be removed if
105 + // it causes problems. This is meant to give a nicer error message for
106 + // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
107 + // ...)) which otherwise throws a "_processChildContext is not a function"
108 + // exception.
109 + Object.defineProperty(fakeInternalInstance, '_processChildContext', {
110 + enumerable: false,
111 + value: function (): empty {
112 + throw new Error(
113 + '_processChildContext is not available in React 16+. This likely ' +
114 + 'means you have multiple copies of React and are attempting to nest ' +
115 + 'a React 15 tree inside a React 16 tree using ' +
116 + "unstable_renderSubtreeIntoContainer, which isn't supported. Try " +
117 + 'to make sure you have only one copy of React (and ideally, switch ' +
118 + 'to ReactDOM.createPortal).',
119 + );
120 + },
121 + });
122 + Object.freeze(fakeInternalInstance);
123 +}
124
106 - warnOnInvalidCallback = function (callback: mixed, callerName: string) {
125 +function warnOnInvalidCallback(callback: mixed, callerName: string) {
126 + if (__DEV__) {
127 if (callback === null || typeof callback === 'function') {
128 return;
129 }
@@ -117,9 +137,11 @@ if (__DEV__) {
137 callback,
138 );
139 }
120 - };
140 + }
141 +}
142
122 - warnOnUndefinedDerivedState = function (type: any, partialState: any) {
143 +function warnOnUndefinedDerivedState(type: any, partialState: any) {
144 + if (__DEV__) {
145 if (partialState === undefined) {
146 const componentName = getComponentNameFromType(type) || 'Component';
147 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
@@ -131,27 +153,7 @@ if (__DEV__) {
153 );
154 }
155 }
134 - };
135 -
136 - // This is so gross but it's at least non-critical and can be removed if
137 - // it causes problems. This is meant to give a nicer error message for
138 - // ReactDOM15.unstable_renderSubtreeIntoContainer(reactDOM16Component,
139 - // ...)) which otherwise throws a "_processChildContext is not a function"
140 - // exception.
141 - Object.defineProperty(fakeInternalInstance, '_processChildContext', {
142 - enumerable: false,
143 - value: function (): empty {
144 - throw new Error(
145 - '_processChildContext is not available in React 16+. This likely ' +
146 - 'means you have multiple copies of React and are attempting to nest ' +
147 - 'a React 15 tree inside a React 16 tree using ' +
148 - "unstable_renderSubtreeIntoContainer, which isn't supported. Try " +
149 - 'to make sure you have only one copy of React (and ideally, switch ' +
150 - 'to ReactDOM.createPortal).',
151 - );
152 - },
153 - });
154 - Object.freeze(fakeInternalInstance);
156 + }
157 }
158
159 function applyDerivedStateFromProps(
packages/react-reconciler/src/ReactFiberCommitWork.js
+2 -5
@@ -253,10 +253,7 @@ export function reportUncaughtErrorInDEV(error: mixed) {
253 }
254 }
255
256 -const callComponentWillUnmountWithTimer = function (
257 - current: Fiber,
258 - instance: any,
259 -) {
256 +function callComponentWillUnmountWithTimer(current: Fiber, instance: any) {
257 instance.props = current.memoizedProps;
258 instance.state = current.memoizedState;
259 if (shouldProfile(current)) {
@@ -269,7 +266,7 @@ const callComponentWillUnmountWithTimer = function (
266 } else {
267 instance.componentWillUnmount();
268 }
272 -};
269 +}
270
271 // Capture errors so they don't interrupt unmounting.
272 function safelyCallComponentWillUnmount(
packages/react-server/src/ReactFizzClassComponent.js
+10 -8
@@ -24,11 +24,10 @@ let didWarnAboutUninitializedState;
24 let didWarnAboutGetSnapshotBeforeUpdateWithoutDidUpdate;
25 let didWarnAboutLegacyLifecyclesAndDerivedState;
26 let didWarnAboutUndefinedDerivedState;
27 -let warnOnUndefinedDerivedState;
28 -let warnOnInvalidCallback;
27 let didWarnAboutDirectlyAssigningPropsToState;
28 let didWarnAboutContextTypeAndContextTypes;
29 let didWarnAboutInvalidateContextType;
30 +let didWarnOnInvalidCallback;
31
32 if (__DEV__) {
33 didWarnAboutUninitializedState = new Set<string>();
@@ -38,10 +37,11 @@ if (__DEV__) {
37 didWarnAboutUndefinedDerivedState = new Set<string>();
38 didWarnAboutContextTypeAndContextTypes = new Set<mixed>();
39 didWarnAboutInvalidateContextType = new Set<mixed>();
40 + didWarnOnInvalidCallback = new Set<string>();
41 +}
42
42 - const didWarnOnInvalidCallback = new Set<string>();
43 -
44 - warnOnInvalidCallback = function (callback: mixed, callerName: string) {
43 +function warnOnInvalidCallback(callback: mixed, callerName: string) {
44 + if (__DEV__) {
45 if (callback === null || typeof callback === 'function') {
46 return;
47 }
@@ -55,9 +55,11 @@ if (__DEV__) {
55 callback,
56 );
57 }
58 - };
58 + }
59 +}
60
60 - warnOnUndefinedDerivedState = function (type: any, partialState: any) {
61 +function warnOnUndefinedDerivedState(type: any, partialState: any) {
62 + if (__DEV__) {
63 if (partialState === undefined) {
64 const componentName = getComponentNameFromType(type) || 'Component';
65 if (!didWarnAboutUndefinedDerivedState.has(componentName)) {
@@ -69,7 +71,7 @@ if (__DEV__) {
71 );
72 }
73 }
72 - };
74 + }
75 }
76
77 function warnNoop(
packages/react/src/ReactElement.js
+2 -2
@@ -145,7 +145,7 @@ function warnIfStringRefCannotBeAutoConverted(config) {
145 * indicating filename, line number, and/or other information.
146 * @internal
147 */
148 -const ReactElement = function (type, key, ref, self, source, owner, props) {
148 +function ReactElement(type, key, ref, self, source, owner, props) {
149 const element = {
150 // This tag allows us to uniquely identify this as a React Element
151 $$typeof: REACT_ELEMENT_TYPE,
@@ -199,7 +199,7 @@ const ReactElement = function (type, key, ref, self, source, owner, props) {
199 }
200
201 return element;
202 -};
202 +}
203
204 /**
205 * https://github.com/reactjs/rfcs/pull/107
packages/react/src/jsx/ReactJSXElement.js
+2 -2
@@ -145,7 +145,7 @@ function defineRefPropWarningGetter(props, displayName) {
145 * indicating filename, line number, and/or other information.
146 * @internal
147 */
148 -const ReactElement = function (type, key, ref, self, source, owner, props) {
148 +function ReactElement(type, key, ref, self, source, owner, props) {
149 const element = {
150 // This tag allows us to uniquely identify this as a React Element
151 $$typeof: REACT_ELEMENT_TYPE,
@@ -199,7 +199,7 @@ const ReactElement = function (type, key, ref, self, source, owner, props) {
199 }
200
201 return element;
202 -};
202 +}
203
204 /**
205 * https://github.com/reactjs/rfcs/pull/107
packages/shared/forks/invokeGuardedCallbackImpl.www.js
+2 -2
@@ -16,7 +16,7 @@ if (typeof ReactFbErrorUtils.invokeGuardedCallback !== 'function') {
16 );
17 }
18
19 -const invokeGuardedCallbackImpl = function <A, B, C, D, E, F, Context>(
19 +function invokeGuardedCallbackImpl<A, B, C, D, E, F, Context>(
20 name: string | null,
21 func: (a: A, b: B, c: C, d: D, e: E, f: F) => mixed,
22 context: Context,
@@ -29,6 +29,6 @@ const invokeGuardedCallbackImpl = function <A, B, C, D, E, F, Context>(
29 ) {
30 // This will call `this.onError(err)` if an error was caught.
31 ReactFbErrorUtils.invokeGuardedCallback.apply(this, arguments);
32 -};
32 +}
33
34 export default invokeGuardedCallbackImpl;