67
setEnabled as ReactBrowserEventEmitterSetEnabled,
68
getEventPriority,
69
} from '../events/ReactDOMEventListener';
70
-import {
71
- getChildNamespace,
72
- SVG_NAMESPACE,
73
- MATH_NAMESPACE,
74
-} from './DOMNamespaces';
70
+import {SVG_NAMESPACE, MATH_NAMESPACE} from './DOMNamespaces';
71
import {
72
ELEMENT_NODE,
73
TEXT_NODE,
150
}
151
export type HydratableInstance = Instance | TextInstance | SuspenseInstance;
152
export type PublicInstance = Element | Text;
157
-type HostContextDev = {
158
- namespace: HostContextProd,
153
+export type HostContextDev = {
154
+ context: HostContextProd,
155
ancestorInfo: AncestorInfoDev,
156
};
161
-type HostContextProd = string;
157
+type HostContextProd = HostContextNamespace;
158
export type HostContext = HostContextDev | HostContextProd;
159
export type UpdatePayload = Array<mixed>;
160
export type ChildSet = void; // Unused
176
177
const STYLE = 'style';
178
179
+opaque type HostContextNamespace = 0 | 1 | 2;
180
+export const HostContextNamespaceNone: HostContextNamespace = 0;
181
+const HostContextNamespaceSvg: HostContextNamespace = 1;
182
+const HostContextNamespaceMath: HostContextNamespace = 2;
183
+
184
let eventsEnabled: ?boolean = null;
185
let selectionInformation: null | SelectionInformation = null;
186
198
rootContainerInstance: Container,
199
): HostContext {
200
let type;
200
- let namespace: HostContextProd;
201
+ let context: HostContextProd;
202
const nodeType = rootContainerInstance.nodeType;
203
switch (nodeType) {
204
case DOCUMENT_NODE:
205
case DOCUMENT_FRAGMENT_NODE: {
206
type = nodeType === DOCUMENT_NODE ? '#document' : '#fragment';
207
const root = (rootContainerInstance: any).documentElement;
207
- namespace = root ? root.namespaceURI : getChildNamespace(null, '');
208
+ if (root) {
209
+ const namespaceURI = root.namespaceURI;
210
+ context = namespaceURI
211
+ ? getOwnHostContext(namespaceURI)
212
+ : HostContextNamespaceNone;
213
+ } else {
214
+ context = HostContextNamespaceNone;
215
+ }
216
break;
217
}
218
default: {
220
nodeType === COMMENT_NODE
221
? rootContainerInstance.parentNode
222
: rootContainerInstance;
215
- const ownNamespace = container.namespaceURI || null;
223
type = container.tagName;
217
- namespace = getChildNamespace(ownNamespace, type);
224
+ const namespaceURI = container.namespaceURI;
225
+ if (!namespaceURI) {
226
+ switch (type) {
227
+ case 'svg':
228
+ context = HostContextNamespaceSvg;
229
+ break;
230
+ case 'math':
231
+ context = HostContextNamespaceMath;
232
+ break;
233
+ default:
234
+ context = HostContextNamespaceNone;
235
+ break;
236
+ }
237
+ } else {
238
+ const ownContext = getOwnHostContext(namespaceURI);
239
+ context = getChildHostContextProd(ownContext, type);
240
+ }
241
break;
242
}
243
}
244
if (__DEV__) {
245
const validatedTag = type.toLowerCase();
246
const ancestorInfo = updatedAncestorInfoDev(null, validatedTag);
224
- return {namespace, ancestorInfo};
247
+ return {context, ancestorInfo};
248
+ }
249
+ return context;
250
+}
251
+
252
+function getOwnHostContext(namespaceURI: string): HostContextNamespace {
253
+ switch (namespaceURI) {
254
+ case SVG_NAMESPACE:
255
+ return HostContextNamespaceSvg;
256
+ case MATH_NAMESPACE:
257
+ return HostContextNamespaceMath;
258
+ default:
259
+ return HostContextNamespaceNone;
260
+ }
261
+}
262
+
263
+function getChildHostContextProd(
264
+ parentNamespace: HostContextNamespace,
265
+ type: string,
266
+): HostContextNamespace {
267
+ if (parentNamespace === HostContextNamespaceNone) {
268
+ // No (or default) parent namespace: potential entry point.
269
+ switch (type) {
270
+ case 'svg':
271
+ return HostContextNamespaceSvg;
272
+ case 'math':
273
+ return HostContextNamespaceMath;
274
+ default:
275
+ return HostContextNamespaceNone;
276
+ }
277
+ }
278
+ if (parentNamespace === HostContextNamespaceSvg && type === 'foreignObject') {
279
+ // We're leaving SVG.
280
+ return HostContextNamespaceNone;
281
}
226
- return namespace;
282
+ // By default, pass namespace below.
283
+ return parentNamespace;
284
}
285
286
export function getChildHostContext(
289
): HostContext {
290
if (__DEV__) {
291
const parentHostContextDev = ((parentHostContext: any): HostContextDev);
235
- const namespace = getChildNamespace(parentHostContextDev.namespace, type);
292
+ const context = getChildHostContextProd(parentHostContextDev.context, type);
293
const ancestorInfo = updatedAncestorInfoDev(
294
parentHostContextDev.ancestorInfo,
295
type,
296
);
240
- return {namespace, ancestorInfo};
297
+ return {context, ancestorInfo};
298
}
299
const parentNamespace = ((parentHostContext: any): HostContextProd);
243
- return getChildNamespace(parentNamespace, type);
300
+ return getChildHostContextProd(parentNamespace, type);
301
}
302
303
export function getPublicInstance(instance: Instance): Instance {
383
hostContext: HostContext,
384
internalInstanceHandle: Object,
385
): Instance {
329
- let namespace;
386
+ let hostContextProd: HostContextProd;
387
if (__DEV__) {
388
// TODO: take namespace into account when validating.
389
const hostContextDev: HostContextDev = (hostContext: any);
390
validateDOMNesting(type, hostContextDev.ancestorInfo);
334
- namespace = hostContextDev.namespace;
391
+ hostContextProd = hostContextDev.context;
392
} else {
336
- const hostContextProd: HostContextProd = (hostContext: any);
337
- namespace = hostContextProd;
393
+ hostContextProd = (hostContext: any);
394
}
395
396
const ownerDocument = getOwnerDocumentFromRootContainer(
398
);
399
400
let domElement: Instance;
345
- switch (namespace) {
346
- case SVG_NAMESPACE:
347
- case MATH_NAMESPACE:
348
- domElement = ownerDocument.createElementNS(namespace, type);
401
+ switch (hostContextProd) {
402
+ case HostContextNamespaceSvg:
403
+ domElement = ownerDocument.createElementNS(SVG_NAMESPACE, type);
404
+ break;
405
+ case HostContextNamespaceMath:
406
+ domElement = ownerDocument.createElementNS(MATH_NAMESPACE, type);
407
break;
408
default:
409
switch (type) {
1301
const isConcurrentMode =
1302
((internalInstanceHandle: Fiber).mode & ConcurrentMode) !== NoMode;
1303
1246
- let parentNamespace;
1247
- if (__DEV__) {
1248
- const hostContextDev = ((hostContext: any): HostContextDev);
1249
- parentNamespace = hostContextDev.namespace;
1250
- } else {
1251
- const hostContextProd = ((hostContext: any): HostContextProd);
1252
- parentNamespace = hostContextProd;
1253
- }
1254
-
1304
return diffHydratedProperties(
1305
instance,
1306
type,
1307
props,
1308
isConcurrentMode,
1309
shouldWarnDev,
1261
- parentNamespace,
1310
+ hostContext,
1311
);
1312
}
1313
2973
hostContext: HostContext,
2974
): boolean {
2975
let outsideHostContainerContext: boolean;
2927
- let namespace: HostContextProd;
2976
+ let hostContextProd: HostContextProd;
2977
if (__DEV__) {
2978
const hostContextDev: HostContextDev = (hostContext: any);
2979
// We can only render resources when we are not within the host container context
2980
outsideHostContainerContext =
2981
!hostContextDev.ancestorInfo.containerTagInScope;
2933
- namespace = hostContextDev.namespace;
2982
+ hostContextProd = hostContextDev.context;
2983
} else {
2935
- const hostContextProd: HostContextProd = (hostContext: any);
2936
- namespace = hostContextProd;
2984
+ hostContextProd = (hostContext: any);
2985
}
2986
2987
// Global opt out of hoisting for anything in SVG Namespace or anything with an itemProp inside an itemScope
2940
- if (namespace === SVG_NAMESPACE || props.itemProp != null) {
2988
+ if (hostContextProd === HostContextNamespaceSvg || props.itemProp != null) {
2989
if (__DEV__) {
2990
if (
2991
outsideHostContainerContext &&