7
7
* @flow
8
8
*/
9
9
10
- import type { ElementRef } from 'react' ;
11
- import type {
12
- HostComponent ,
13
- MeasureInWindowOnSuccessCallback ,
14
- MeasureLayoutOnSuccessCallback ,
15
- MeasureOnSuccessCallback ,
16
- INativeMethods ,
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' ;
22
15
import { create , diff } from './ReactNativeAttributePayload' ;
23
-
24
16
import { dispatchEvent } from './ReactFabricEventEmitter' ;
25
-
26
17
import {
27
18
DefaultEventPriority ,
28
19
DiscreteEventPriority ,
@@ -31,7 +22,6 @@ import {
31
22
// Modules provided by RN:
32
23
import {
33
24
ReactNativeViewConfigRegistry ,
34
- TextInputState ,
35
25
deepFreezeAndThrowOnMutationInDev ,
36
26
} from 'react-native/Libraries/ReactPrivate/ReactNativePrivateInterface' ;
37
27
@@ -46,14 +36,9 @@ const {
46
36
appendChildToSet : appendChildNodeToSet ,
47
37
completeRoot,
48
38
registerEventHandler,
49
- measure : fabricMeasure ,
50
- measureInWindow : fabricMeasureInWindow ,
51
- measureLayout : fabricMeasureLayout ,
52
39
unstable_DefaultEventPriority : FabricDefaultPriority ,
53
40
unstable_DiscreteEventPriority : FabricDiscretePriority ,
54
41
unstable_getCurrentEventPriority : fabricGetCurrentEventPriority ,
55
- setNativeProps,
56
- getBoundingClientRect : fabricGetBoundingClientRect ,
57
42
} = nativeFabricUIManager ;
58
43
59
44
const { get : getViewConfigForType } = ReactNativeViewConfigRegistry ;
@@ -68,9 +53,15 @@ type Node = Object;
68
53
export type Type = string ;
69
54
export type Props = Object ;
70
55
export type Instance = {
56
+ // Reference to the shadow node.
71
57
node : Node ,
72
- canonical : ReactFabricHostComponent ,
73
- ...
58
+ nativeTag : number ,
59
+ viewConfig : ViewConfig ,
60
+ currentProps : Props ,
61
+ // Reference to the React handle (the fiber)
62
+ internalInstanceHandle : Object ,
63
+ // Exposed through refs.
64
+ publicInstance : ReactFabricHostComponent ,
74
65
} ;
75
66
export type TextInstance = { node : Node , ...} ;
76
67
export type HydratableInstance = Instance | TextInstance ;
@@ -104,137 +95,6 @@ if (registerEventHandler) {
104
95
registerEventHandler ( dispatchEvent ) ;
105
96
}
106
97
107
- const noop = ( ) => { } ;
108
-
109
- /**
110
- * This is used for refs on host components.
111
- */
112
- class ReactFabricHostComponent implements INativeMethods {
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
-
238
98
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoMutation' ;
239
99
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoHydration' ;
240
100
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoScopes' ;
@@ -280,16 +140,19 @@ export function createInstance(
280
140
internalInstanceHandle , // internalInstanceHandle
281
141
) ;
282
142
283
- const component = new ReactFabricHostComponent (
143
+ const component = createPublicInstance (
284
144
tag ,
285
145
viewConfig ,
286
- props ,
287
146
internalInstanceHandle ,
288
147
) ;
289
148
290
149
return {
291
150
node : node ,
292
- canonical : component ,
151
+ nativeTag : tag ,
152
+ viewConfig,
153
+ currentProps : props ,
154
+ internalInstanceHandle,
155
+ publicInstance : component ,
293
156
} ;
294
157
}
295
158
@@ -359,12 +222,15 @@ export function getChildHostContext(
359
222
}
360
223
361
224
export function getPublicInstance ( instance : Instance ) : null | PublicInstance {
362
- if ( instance . canonical ) {
363
- return instance . canonical ;
225
+ if ( instance . publicInstance != null ) {
226
+ return instance . publicInstance ;
364
227
}
365
228
366
- // For compatibility with Paper
229
+ // For compatibility with the legacy renderer, in case it's used with Fabric
230
+ // in the same app.
231
+ // $FlowExpectedError[prop-missing]
367
232
if ( instance . _nativeTag != null ) {
233
+ // $FlowExpectedError[incompatible-return]
368
234
return instance ;
369
235
}
370
236
@@ -383,12 +249,12 @@ export function prepareUpdate(
383
249
newProps : Props ,
384
250
hostContext : HostContext ,
385
251
) : null | Object {
386
- const viewConfig = instance . canonical . viewConfig ;
252
+ const viewConfig = instance . viewConfig ;
387
253
const updatePayload = diff ( oldProps , newProps , viewConfig . validAttributes ) ;
388
254
// TODO: If the event handlers have changed, we need to update the current props
389
255
// in the commit phase but there is no host config hook to do it yet.
390
256
// So instead we hack it by updating it in the render phase.
391
- instance . canonical . currentProps = newProps ;
257
+ instance . currentProps = newProps ;
392
258
return updatePayload ;
393
259
}
394
260
@@ -467,7 +333,11 @@ export function cloneInstance(
467
333
}
468
334
return {
469
335
node : clone ,
470
- canonical : instance . canonical ,
336
+ nativeTag : instance . nativeTag ,
337
+ viewConfig : instance . viewConfig ,
338
+ currentProps : instance . currentProps ,
339
+ internalInstanceHandle : instance . internalInstanceHandle ,
340
+ publicInstance : instance . publicInstance ,
471
341
} ;
472
342
}
473
343
@@ -477,15 +347,19 @@ export function cloneHiddenInstance(
477
347
props : Props ,
478
348
internalInstanceHandle : Object ,
479
349
) : Instance {
480
- const viewConfig = instance . canonical . viewConfig ;
350
+ const viewConfig = instance . viewConfig ;
481
351
const node = instance . node ;
482
352
const updatePayload = create (
483
353
{ style : { display : 'none' } } ,
484
354
viewConfig . validAttributes ,
485
355
) ;
486
356
return {
487
357
node : cloneNodeWithNewProps ( node , updatePayload ) ,
488
- canonical : instance . canonical ,
358
+ nativeTag : instance . nativeTag ,
359
+ viewConfig : instance . viewConfig ,
360
+ currentProps : instance . currentProps ,
361
+ internalInstanceHandle : instance . internalInstanceHandle ,
362
+ publicInstance : instance . publicInstance ,
489
363
} ;
490
364
}
491
365
0 commit comments