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
- 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' ;
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,18 @@ 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
+ // 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
+ } ,
74
68
} ;
75
69
export type TextInstance = { node : Node , ...} ;
76
70
export type HydratableInstance = Instance | TextInstance ;
@@ -104,131 +98,6 @@ if (registerEventHandler) {
104
98
registerEventHandler ( dispatchEvent ) ;
105
99
}
106
100
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
-
232
101
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoMutation' ;
233
102
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoHydration' ;
234
103
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoScopes' ;
@@ -274,16 +143,21 @@ export function createInstance(
274
143
internalInstanceHandle , // internalInstanceHandle
275
144
) ;
276
145
277
- const component = new ReactFabricHostComponent (
146
+ const component = createPublicInstance (
278
147
tag ,
279
148
viewConfig ,
280
- props ,
281
149
internalInstanceHandle ,
282
150
) ;
283
151
284
152
return {
285
153
node : node ,
286
- canonical : component ,
154
+ publicInstance : component ,
155
+ internals : {
156
+ nativeTag : tag ,
157
+ viewConfig,
158
+ currentProps : props ,
159
+ internalInstanceHandle,
160
+ } ,
287
161
} ;
288
162
}
289
163
@@ -353,12 +227,15 @@ export function getChildHostContext(
353
227
}
354
228
355
229
export function getPublicInstance ( instance : Instance ) : null | PublicInstance {
356
- if ( instance . canonical ) {
357
- return instance . canonical ;
230
+ if ( instance . publicInstance != null ) {
231
+ return instance . publicInstance ;
358
232
}
359
233
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]
361
237
if ( instance . _nativeTag != null ) {
238
+ // $FlowExpectedError[incompatible-return]
362
239
return instance ;
363
240
}
364
241
@@ -377,12 +254,12 @@ export function prepareUpdate(
377
254
newProps : Props ,
378
255
hostContext : HostContext ,
379
256
) : null | Object {
380
- const viewConfig = instance . canonical . viewConfig ;
257
+ const viewConfig = instance . internals . viewConfig ;
381
258
const updatePayload = diff ( oldProps , newProps , viewConfig . validAttributes ) ;
382
259
// TODO: If the event handlers have changed, we need to update the current props
383
260
// in the commit phase but there is no host config hook to do it yet.
384
261
// So instead we hack it by updating it in the render phase.
385
- instance . canonical . currentProps = newProps ;
262
+ instance . internals . currentProps = newProps ;
386
263
return updatePayload ;
387
264
}
388
265
@@ -461,7 +338,8 @@ export function cloneInstance(
461
338
}
462
339
return {
463
340
node : clone ,
464
- canonical : instance . canonical ,
341
+ publicInstance : instance . publicInstance ,
342
+ internals : instance . internals ,
465
343
} ;
466
344
}
467
345
@@ -471,15 +349,16 @@ export function cloneHiddenInstance(
471
349
props : Props ,
472
350
internalInstanceHandle : Object ,
473
351
) : Instance {
474
- const viewConfig = instance . canonical . viewConfig ;
352
+ const viewConfig = instance . internals . viewConfig ;
475
353
const node = instance . node ;
476
354
const updatePayload = create (
477
355
{ style : { display : 'none' } } ,
478
356
viewConfig . validAttributes ,
479
357
) ;
480
358
return {
481
359
node : cloneNodeWithNewProps ( node , updatePayload ) ,
482
- canonical : instance . canonical ,
360
+ publicInstance : instance . publicInstance ,
361
+ internals : instance . internals ,
483
362
} ;
484
363
}
485
364
0 commit comments