/
githubmr
/
facebook-react
Обзор
Документация
Войти
/
githubmr
/
facebook-react
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
status
packages/react-reconciler/src/ReactFiberScope.js
227 строк
6 KB
Dominic Gannaway
[react-interactions] Modify Scope query mechanism (#17095)
15 окт 2019, 16:57
Не верифицирован
15 окт 2019, 16:57
4cb399a
Код
Авторство
О чём код?
/** * Copyright (c) Facebook, Inc. and its affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * * @flow */ import type {Fiber} from './ReactFiber'; import type { ReactScope, ReactScopeInstance, ReactScopeMethods, } from 'shared/ReactTypes'; import {getPublicInstance, getInstanceFromNode} from './ReactFiberHostConfig'; import { HostComponent, SuspenseComponent, ScopeComponent, } from 'shared/ReactWorkTags'; import {enableScopeAPI} from 'shared/ReactFeatureFlags'; function isFiberSuspenseAndTimedOut(fiber: Fiber): boolean { return fiber.tag === SuspenseComponent && fiber.memoizedState !== null; } function getSuspenseFallbackChild(fiber: Fiber): Fiber | null { return ((((fiber.child: any): Fiber).sibling: any): Fiber).child; } function collectScopedNodes( node: Fiber, fn: (type: string | Object, props: Object) => boolean, scopedNodes: Array<any>, ): void { if (enableScopeAPI) { if (node.tag === HostComponent) { const {type, memoizedProps} = node; if (fn(type, memoizedProps) === true) { scopedNodes.push(getPublicInstance(node.stateNode)); } } let child = node.child; if (isFiberSuspenseAndTimedOut(node)) { child = getSuspenseFallbackChild(node); } if (child !== null) { collectScopedNodesFromChildren(child, fn, scopedNodes); } } } function collectFirstScopedNode( node: Fiber, fn: (type: string | Object, props: Object) => boolean, ): null | Object { if (enableScopeAPI) { if (node.tag === HostComponent) { const {type, memoizedProps} = node; if (fn(type, memoizedProps) === true) { return getPublicInstance(node.stateNode); } } let child = node.child; if (isFiberSuspenseAndTimedOut(node)) { child = getSuspenseFallbackChild(node); } if (child !== null) { return collectFirstScopedNodeFromChildren(child, fn); } } return null; } function collectScopedNodesFromChildren( startingChild: Fiber, fn: (type: string | Object, props: Object) => boolean, scopedNodes: Array<any>, ): void { let child = startingChild; while (child !== null) { collectScopedNodes(child, fn, scopedNodes); child = child.sibling; } } function collectFirstScopedNodeFromChildren( startingChild: Fiber, fn: (type: string | Object, props: Object) => boolean, ): Object | null { let child = startingChild; while (child !== null) { const scopedNode = collectFirstScopedNode(child, fn); if (scopedNode !== null) { return scopedNode; } child = child.sibling; } return null; } function collectNearestScopeMethods( node: Fiber, scope: ReactScope, childrenScopes: Array<ReactScopeMethods>, ): void { if (isValidScopeNode(node, scope)) { childrenScopes.push(node.stateNode.methods); } else { let child = node.child; if (isFiberSuspenseAndTimedOut(node)) { child = getSuspenseFallbackChild(node); } if (child !== null) { collectNearestChildScopeMethods(child, scope, childrenScopes); } } } function collectNearestChildScopeMethods( startingChild: Fiber | null, scope: ReactScope, childrenScopes: Array<ReactScopeMethods>, ): void { let child = startingChild; while (child !== null) { collectNearestScopeMethods(child, scope, childrenScopes); child = child.sibling; } } function isValidScopeNode(node, scope) { return ( node.tag === ScopeComponent && node.type === scope && node.stateNode !== null ); } export function createScopeMethods( scope: ReactScope, instance: ReactScopeInstance, ): ReactScopeMethods { return { getChildren(): null | Array<ReactScopeMethods> { const currentFiber = ((instance.fiber: any): Fiber); const child = currentFiber.child; const childrenScopes = []; if (child !== null) { collectNearestChildScopeMethods(child, scope, childrenScopes); } return childrenScopes.length === 0 ? null : childrenScopes; }, getChildrenFromRoot(): null | Array<ReactScopeMethods> { const currentFiber = ((instance.fiber: any): Fiber); let node = currentFiber; while (node !== null) { const parent = node.return; if (parent === null) { break; } node = parent; if (node.tag === ScopeComponent && node.type === scope) { break; } } const childrenScopes = []; collectNearestChildScopeMethods(node.child, scope, childrenScopes); return childrenScopes.length === 0 ? null : childrenScopes; }, getParent(): null | ReactScopeMethods { let node = ((instance.fiber: any): Fiber).return; while (node !== null) { if (node.tag === ScopeComponent && node.type === scope) { return node.stateNode.methods; } node = node.return; } return null; }, getProps(): Object { const currentFiber = ((instance.fiber: any): Fiber); return currentFiber.memoizedProps; }, queryAllNodes( fn: (type: string | Object, props: Object) => boolean, ): null | Array<Object> { const currentFiber = ((instance.fiber: any): Fiber); const child = currentFiber.child; const scopedNodes = []; if (child !== null) { collectScopedNodesFromChildren(child, fn, scopedNodes); } return scopedNodes.length === 0 ? null : scopedNodes; }, queryFirstNode( fn: (type: string | Object, props: Object) => boolean, ): null | Object { const currentFiber = ((instance.fiber: any): Fiber); const child = currentFiber.child; if (child !== null) { return collectFirstScopedNodeFromChildren(child, fn); } return null; }, containsNode(node: Object): boolean { let fiber = getInstanceFromNode(node); while (fiber !== null) { if ( fiber.tag === ScopeComponent && fiber.type === scope && fiber.stateNode === instance ) { return true; } fiber = fiber.return; } return false; }, }; }