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,137 +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
- 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
101
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoMutation' ;
239
102
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoHydration' ;
240
103
export * from 'react-reconciler/src/ReactFiberHostConfigWithNoScopes' ;
@@ -280,16 +143,21 @@ export function createInstance(
280
143
internalInstanceHandle , // internalInstanceHandle
281
144
) ;
282
145
283
- const component = new ReactFabricHostComponent (
146
+ const component = createPublicInstance (
284
147
tag ,
285
148
viewConfig ,
286
- props ,
287
149
internalInstanceHandle ,
288
150
) ;
289
151
290
152
return {
291
153
node : node ,
292
- canonical : component ,
154
+ publicInstance : component ,
155
+ internals : {
156
+ nativeTag : tag ,
157
+ viewConfig,
158
+ currentProps : props ,
159
+ internalInstanceHandle,
160
+ } ,
293
161
} ;
294
162
}
295
163
@@ -359,12 +227,15 @@ export function getChildHostContext(
359
227
}
360
228
361
229
export function getPublicInstance ( instance : Instance ) : null | PublicInstance {
362
- if ( instance . canonical ) {
363
- return instance . canonical ;
230
+ if ( instance . publicInstance != null ) {
231
+ return instance . publicInstance ;
364
232
}
365
233
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]
367
237
if ( instance . _nativeTag != null ) {
238
+ // $FlowExpectedError[incompatible-return]
368
239
return instance ;
369
240
}
370
241
@@ -383,12 +254,12 @@ export function prepareUpdate(
383
254
newProps : Props ,
384
255
hostContext : HostContext ,
385
256
) : null | Object {
386
- const viewConfig = instance . canonical . viewConfig ;
257
+ const viewConfig = instance . internals . viewConfig ;
387
258
const updatePayload = diff ( oldProps , newProps , viewConfig . validAttributes ) ;
388
259
// TODO: If the event handlers have changed, we need to update the current props
389
260
// in the commit phase but there is no host config hook to do it yet.
390
261
// So instead we hack it by updating it in the render phase.
391
- instance . canonical . currentProps = newProps ;
262
+ instance . internals . currentProps = newProps ;
392
263
return updatePayload ;
393
264
}
394
265
@@ -467,7 +338,8 @@ export function cloneInstance(
467
338
}
468
339
return {
469
340
node : clone ,
470
- canonical : instance . canonical ,
341
+ publicInstance : instance . publicInstance ,
342
+ internals : instance . internals ,
471
343
} ;
472
344
}
473
345
@@ -477,15 +349,16 @@ export function cloneHiddenInstance(
477
349
props : Props ,
478
350
internalInstanceHandle : Object ,
479
351
) : Instance {
480
- const viewConfig = instance . canonical . viewConfig ;
352
+ const viewConfig = instance . internals . viewConfig ;
481
353
const node = instance . node ;
482
354
const updatePayload = create (
483
355
{ style : { display : 'none' } } ,
484
356
viewConfig . validAttributes ,
485
357
) ;
486
358
return {
487
359
node : cloneNodeWithNewProps ( node , updatePayload ) ,
488
- canonical : instance . canonical ,
360
+ publicInstance : instance . publicInstance ,
361
+ internals : instance . internals ,
489
362
} ;
490
363
}
491
364
0 commit comments