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,131 +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- // $FlowExpectedError[incompatible-use] internalInstanceHandle is opaque but we need to make an exception here.
229- return internalInstanceHandle ?. stateNode ?. node ;
230- }
231-
232101export * from 'react-reconciler/src/ReactFiberHostConfigWithNoMutation' ;
233102export * from 'react-reconciler/src/ReactFiberHostConfigWithNoHydration' ;
234103export * from 'react-reconciler/src/ReactFiberHostConfigWithNoScopes' ;
@@ -274,16 +143,21 @@ export function createInstance(
274143 internalInstanceHandle , // internalInstanceHandle
275144 ) ;
276145
277- const component = new ReactFabricHostComponent (
146+ const component = createPublicInstance (
278147 tag ,
279148 viewConfig ,
280- props ,
281149 internalInstanceHandle ,
282150 ) ;
283151
284152 return {
285153 node : node ,
286- canonical : component ,
154+ publicInstance : component ,
155+ internals : {
156+ nativeTag : tag ,
157+ viewConfig,
158+ currentProps : props ,
159+ internalInstanceHandle,
160+ } ,
287161 } ;
288162}
289163
@@ -353,12 +227,15 @@ export function getChildHostContext(
353227}
354228
355229export function getPublicInstance ( instance : Instance ) : null | PublicInstance {
356- if ( instance . canonical ) {
357- return instance . canonical ;
230+ if ( instance . publicInstance != null ) {
231+ return instance . publicInstance ;
358232 }
359233
360- // 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]
361237 if ( instance . _nativeTag != null ) {
238+ // $FlowExpectedError[incompatible-return]
362239 return instance ;
363240 }
364241
@@ -377,12 +254,12 @@ export function prepareUpdate(
377254 newProps : Props ,
378255 hostContext : HostContext ,
379256) : null | Object {
380- const viewConfig = instance . canonical . viewConfig ;
257+ const viewConfig = instance . internals . viewConfig ;
381258 const updatePayload = diff ( oldProps , newProps , viewConfig . validAttributes ) ;
382259 // TODO: If the event handlers have changed, we need to update the current props
383260 // in the commit phase but there is no host config hook to do it yet.
384261 // So instead we hack it by updating it in the render phase.
385- instance . canonical . currentProps = newProps ;
262+ instance . internals . currentProps = newProps ;
386263 return updatePayload ;
387264}
388265
@@ -461,7 +338,8 @@ export function cloneInstance(
461338 }
462339 return {
463340 node : clone ,
464- canonical : instance . canonical ,
341+ publicInstance : instance . publicInstance ,
342+ internals : instance . internals ,
465343 } ;
466344}
467345
@@ -471,15 +349,16 @@ export function cloneHiddenInstance(
471349 props : Props ,
472350 internalInstanceHandle : Object ,
473351) : Instance {
474- const viewConfig = instance . canonical . viewConfig ;
352+ const viewConfig = instance . internals . viewConfig ;
475353 const node = instance . node ;
476354 const updatePayload = create (
477355 { style : { display : 'none' } } ,
478356 viewConfig . validAttributes ,
479357 ) ;
480358 return {
481359 node : cloneNodeWithNewProps ( node , updatePayload ) ,
482- canonical : instance . canonical ,
360+ publicInstance : instance . publicInstance ,
361+ internals : instance . internals ,
483362 } ;
484363}
485364
0 commit comments