77 * @flow
88 */
99
10- import type { ElementRef } from 'react' ;
11- import type {
12- HostComponent ,
13- MeasureInWindowOnSuccessCallback ,
14- MeasureLayoutOnSuccessCallback ,
15- MeasureOnSuccessCallback ,
16- NativeMethods ,
17- ViewConfig ,
18- TouchedViewDataAtPoint ,
19- } from './ReactNativeTypes' ;
20-
21- import { warnForStyleProps } from './NativeMethodsMixinUtils' ;
10+ import type { TouchedViewDataAtPoint , ViewConfig } from './ReactNativeTypes' ;
11+ import {
12+ createPublicInstance ,
13+ type ReactFabricHostComponent ,
14+ } from './ReactFabricPublicInstance' ;
2215import { create , diff } from './ReactNativeAttributePayload' ;
23-
2416import { dispatchEvent } from './ReactFabricEventEmitter' ;
25-
2617import {
2718 DefaultEventPriority ,
2819 DiscreteEventPriority ,
@@ -31,7 +22,6 @@ import {
3122// Modules provided by RN:
3223import {
3324 ReactNativeViewConfigRegistry ,
34- TextInputState ,
3525 deepFreezeAndThrowOnMutationInDev ,
3626} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface' ;
3727
@@ -46,14 +36,9 @@ const {
4636 appendChildToSet : appendChildNodeToSet ,
4737 completeRoot,
4838 registerEventHandler,
49- measure : fabricMeasure ,
50- measureInWindow : fabricMeasureInWindow ,
51- measureLayout : fabricMeasureLayout ,
5239 unstable_DefaultEventPriority : FabricDefaultPriority ,
5340 unstable_DiscreteEventPriority : FabricDiscretePriority ,
5441 unstable_getCurrentEventPriority : fabricGetCurrentEventPriority ,
55- setNativeProps,
56- getBoundingClientRect : fabricGetBoundingClientRect ,
5742} = nativeFabricUIManager ;
5843
5944const { get : getViewConfigForType } = ReactNativeViewConfigRegistry ;
@@ -68,9 +53,18 @@ type Node = Object;
6853export type Type = string ;
6954export type Props = Object ;
7055export type Instance = {
56+ // Reference to the shadow node.
7157 node : Node ,
72- canonical : ReactFabricHostComponent ,
73- ...
58+ // Exposed through refs.
59+ publicInstance : ReactFabricHostComponent ,
60+ // We define this as an object instead of as separate fields to simplify
61+ // making copies of instance where `internals` don't change.
62+ internals : {
63+ nativeTag : number ,
64+ viewConfig : ViewConfig ,
65+ currentProps : Props ,
66+ internalInstanceHandle : Object ,
67+ } ,
7468} ;
7569export type TextInstance = { node : Node , ...} ;
7670export type HydratableInstance = Instance | TextInstance ;
@@ -104,137 +98,6 @@ if (registerEventHandler) {
10498 registerEventHandler ( dispatchEvent ) ;
10599}
106100
107- const noop = ( ) => { } ;
108-
109- /**
110- * This is used for refs on host components.
111- */
112- class ReactFabricHostComponent implements NativeMethods {
113- _nativeTag : number ;
114- viewConfig : ViewConfig ;
115- currentProps : Props ;
116- _internalInstanceHandle : Object ;
117-
118- constructor (
119- tag : number ,
120- viewConfig : ViewConfig ,
121- props : Props ,
122- internalInstanceHandle : Object ,
123- ) {
124- this . _nativeTag = tag ;
125- this . viewConfig = viewConfig ;
126- this . currentProps = props ;
127- this . _internalInstanceHandle = internalInstanceHandle ;
128- }
129-
130- blur ( ) {
131- TextInputState . blurTextInput ( this ) ;
132- }
133-
134- focus ( ) {
135- TextInputState . focusTextInput ( this ) ;
136- }
137-
138- measure ( callback : MeasureOnSuccessCallback ) {
139- const node = getShadowNodeFromInternalInstanceHandle (
140- this . _internalInstanceHandle ,
141- ) ;
142- if ( node != null ) {
143- fabricMeasure ( node , callback ) ;
144- }
145- }
146-
147- measureInWindow ( callback : MeasureInWindowOnSuccessCallback ) {
148- const node = getShadowNodeFromInternalInstanceHandle (
149- this . _internalInstanceHandle ,
150- ) ;
151- if ( node != null ) {
152- fabricMeasureInWindow ( node , callback ) ;
153- }
154- }
155-
156- measureLayout (
157- relativeToNativeNode : number | ElementRef < HostComponent < mixed >> ,
158- onSuccess : MeasureLayoutOnSuccessCallback ,
159- onFail ?: ( ) => void /* currently unused */ ,
160- ) {
161- if (
162- typeof relativeToNativeNode === 'number' ||
163- ! ( relativeToNativeNode instanceof ReactFabricHostComponent )
164- ) {
165- if ( __DEV__ ) {
166- console . error (
167- 'Warning: ref.measureLayout must be called with a ref to a native component.' ,
168- ) ;
169- }
170-
171- return ;
172- }
173-
174- const toStateNode = getShadowNodeFromInternalInstanceHandle (
175- this . _internalInstanceHandle ,
176- ) ;
177- const fromStateNode = getShadowNodeFromInternalInstanceHandle (
178- relativeToNativeNode . _internalInstanceHandle ,
179- ) ;
180-
181- if ( toStateNode != null && fromStateNode != null ) {
182- fabricMeasureLayout (
183- toStateNode ,
184- fromStateNode ,
185- onFail != null ? onFail : noop ,
186- onSuccess != null ? onSuccess : noop ,
187- ) ;
188- }
189- }
190-
191- unstable_getBoundingClientRect ( ) : DOMRect {
192- const node = getShadowNodeFromInternalInstanceHandle (
193- this . _internalInstanceHandle ,
194- ) ;
195- if ( node != null ) {
196- const rect = fabricGetBoundingClientRect ( node ) ;
197-
198- if ( rect ) {
199- return new DOMRect ( rect [ 0 ] , rect [ 1 ] , rect [ 2 ] , rect [ 3 ] ) ;
200- }
201- }
202-
203- // Empty rect if any of the above failed
204- return new DOMRect ( 0 , 0 , 0 , 0 ) ;
205- }
206-
207- setNativeProps ( nativeProps : Object ) {
208- if ( __DEV__ ) {
209- warnForStyleProps ( nativeProps , this . viewConfig . validAttributes ) ;
210- }
211- const updatePayload = create ( nativeProps , this . viewConfig . validAttributes ) ;
212-
213- const node = getShadowNodeFromInternalInstanceHandle (
214- this . _internalInstanceHandle ,
215- ) ;
216- if ( node != null && updatePayload != null ) {
217- setNativeProps ( node , updatePayload ) ;
218- }
219- }
220- }
221-
222- type ParamOf < Fn > = $Call << T > ( ( arg : T ) => mixed ) => T , Fn > ;
223- type ShadowNode = ParamOf < ( typeof nativeFabricUIManager ) [ 'measure' ] > ;
224-
225- export function getShadowNodeFromInternalInstanceHandle (
226- internalInstanceHandle : mixed ,
227- ) : ?ShadowNode {
228- return (
229- // $FlowExpectedError[incompatible-return] internalInstanceHandle is opaque but we need to make an exception here.
230- internalInstanceHandle &&
231- // $FlowExpectedError[incompatible-return]
232- internalInstanceHandle . stateNode &&
233- // $FlowExpectedError[incompatible-use]
234- internalInstanceHandle . stateNode . node
235- ) ;
236- }
237-
238101export * from 'react-reconciler/src/ReactFiberHostConfigWithNoMutation' ;
239102export * from 'react-reconciler/src/ReactFiberHostConfigWithNoHydration' ;
240103export * from 'react-reconciler/src/ReactFiberHostConfigWithNoScopes' ;
@@ -280,16 +143,21 @@ export function createInstance(
280143 internalInstanceHandle , // internalInstanceHandle
281144 ) ;
282145
283- const component = new ReactFabricHostComponent (
146+ const component = createPublicInstance (
284147 tag ,
285148 viewConfig ,
286- props ,
287149 internalInstanceHandle ,
288150 ) ;
289151
290152 return {
291153 node : node ,
292- canonical : component ,
154+ publicInstance : component ,
155+ internals : {
156+ nativeTag : tag ,
157+ viewConfig,
158+ currentProps : props ,
159+ internalInstanceHandle,
160+ } ,
293161 } ;
294162}
295163
@@ -359,12 +227,15 @@ export function getChildHostContext(
359227}
360228
361229export function getPublicInstance ( instance : Instance ) : null | PublicInstance {
362- if ( instance . canonical ) {
363- return instance . canonical ;
230+ if ( instance . publicInstance != null ) {
231+ return instance . publicInstance ;
364232 }
365233
366- // For compatibility with Paper
234+ // For compatibility with the legacy renderer, in case it's used with Fabric
235+ // in the same app.
236+ // $FlowExpectedError[prop-missing]
367237 if ( instance . _nativeTag != null ) {
238+ // $FlowExpectedError[incompatible-return]
368239 return instance ;
369240 }
370241
@@ -383,12 +254,12 @@ export function prepareUpdate(
383254 newProps : Props ,
384255 hostContext : HostContext ,
385256) : null | Object {
386- const viewConfig = instance . canonical . viewConfig ;
257+ const viewConfig = instance . internals . viewConfig ;
387258 const updatePayload = diff ( oldProps , newProps , viewConfig . validAttributes ) ;
388259 // TODO: If the event handlers have changed, we need to update the current props
389260 // in the commit phase but there is no host config hook to do it yet.
390261 // So instead we hack it by updating it in the render phase.
391- instance . canonical . currentProps = newProps ;
262+ instance . internals . currentProps = newProps ;
392263 return updatePayload ;
393264}
394265
@@ -467,7 +338,8 @@ export function cloneInstance(
467338 }
468339 return {
469340 node : clone ,
470- canonical : instance . canonical ,
341+ publicInstance : instance . publicInstance ,
342+ internals : instance . internals ,
471343 } ;
472344}
473345
@@ -477,15 +349,16 @@ export function cloneHiddenInstance(
477349 props : Props ,
478350 internalInstanceHandle : Object ,
479351) : Instance {
480- const viewConfig = instance . canonical . viewConfig ;
352+ const viewConfig = instance . internals . viewConfig ;
481353 const node = instance . node ;
482354 const updatePayload = create (
483355 { style : { display : 'none' } } ,
484356 viewConfig . validAttributes ,
485357 ) ;
486358 return {
487359 node : cloneNodeWithNewProps ( node , updatePayload ) ,
488- canonical : instance . canonical ,
360+ publicInstance : instance . publicInstance ,
361+ internals : instance . internals ,
489362 } ;
490363}
491364
0 commit comments