@samitouri / QOS-React-2 / commits / 8210299437

Add SVG/MathML support for createElement mode

Ben Alpert committed Oct 8, 2015 at 15:51 UTC 8210299437d38af8c4b20f0c714511bd124e5b8a
3 files changed +59 -3
src/renderers/dom/shared/DOMNamespaces.js new
+20
@@ -0,0 +1,20 @@
1 +/**
2 + * Copyright 2013-2015, Facebook, Inc.
3 + * All rights reserved.
4 + *
5 + * This source code is licensed under the BSD-style license found in the
6 + * LICENSE file in the root directory of this source tree. An additional grant
7 + * of patent rights can be found in the PATENTS file in the same directory.
8 + *
9 + * @providesModule DOMNamespaces
10 + */
11 +
12 +'use strict';
13 +
14 +var DOMNamespaces = {
15 + html: 'http://www.w3.org/1999/xhtml',
16 + mathml: 'http://www.w3.org/1998/Math/MathML',
17 + svg: 'http://www.w3.org/2000/svg',
18 +};
19 +
20 +module.exports = DOMNamespaces;
src/renderers/dom/shared/ReactDOMComponent.js
+36 -1
@@ -16,6 +16,7 @@
16
17 var AutoFocusUtils = require('AutoFocusUtils');
18 var CSSPropertyOperations = require('CSSPropertyOperations');
19 +var DOMNamespaces = require('DOMNamespaces');
20 var DOMProperty = require('DOMProperty');
21 var DOMPropertyOperations = require('DOMPropertyOperations');
22 var EventConstants = require('EventConstants');
@@ -503,6 +504,7 @@ function getNode(inst) {
504 function ReactDOMComponent(tag) {
505 validateDangerousTag(tag);
506 this._tag = tag.toLowerCase();
507 + this._namespaceURI = null;
508 this._renderedChildren = null;
509 this._previousStyle = null;
510 this._previousStyleCopy = null;
@@ -582,6 +584,31 @@ ReactDOMComponent.Mixin = {
584 }
585
586 assertValidProps(this, props);
587 +
588 + // We create tags in the namespace of their parent container, except HTML
589 + // tags get no namespace.
590 + var namespaceURI;
591 + var parentTag;
592 + if (nativeParent != null) {
593 + namespaceURI = nativeParent._namespaceURI;
594 + parentTag = nativeParent._tag;
595 + } else if (nativeContainerInfo != null) {
596 + namespaceURI = nativeContainerInfo._namespaceURI;
597 + parentTag = nativeContainerInfo._tag;
598 + }
599 + if (namespaceURI == null ||
600 + namespaceURI === DOMNamespaces.svg && parentTag === 'foreignobject') {
601 + namespaceURI = DOMNamespaces.html;
602 + }
603 + if (namespaceURI === DOMNamespaces.html) {
604 + if (this._tag === 'svg') {
605 + namespaceURI = DOMNamespaces.svg;
606 + } else if (this._tag === 'math') {
607 + namespaceURI = DOMNamespaces.mathml;
608 + }
609 + }
610 + this._namespaceURI = namespaceURI;
611 +
612 if (__DEV__) {
613 var parentInfo;
614 if (nativeParent != null) {
@@ -601,7 +628,15 @@ ReactDOMComponent.Mixin = {
628 var mountImage;
629 if (transaction.useCreateElement) {
630 var ownerDocument = nativeContainerInfo._ownerDocument;
604 - var el = ownerDocument.createElement(this._currentElement.type);
631 + var el;
632 + if (namespaceURI === DOMNamespaces.html) {
633 + el = ownerDocument.createElement(this._currentElement.type);
634 + } else {
635 + el = ownerDocument.createElementNS(
636 + namespaceURI,
637 + this._currentElement.type
638 + );
639 + }
640 this._nativeNode = el;
641 DOMPropertyOperations.setAttributeForID(el, this._rootNodeID);
642 // Populate node cache
src/renderers/dom/shared/ReactDOMContainerInfo.js
+3 -2
@@ -18,11 +18,12 @@ var DOC_NODE_TYPE = 9;
18 function ReactDOMContainerInfo(node) {
19 var info = {
20 _ownerDocument: node.nodeType === DOC_NODE_TYPE ? node : node.ownerDocument,
21 + _tag: node.nodeName.toLowerCase(),
22 + _namespaceURI: node.namespaceURI,
23 };
24 if (__DEV__) {
23 - var tag = node.nodeName.toLowerCase();
25 info._ancestorInfo =
25 - validateDOMNesting.updatedAncestorInfo(null, tag, null);
26 + validateDOMNesting.updatedAncestorInfo(null, info._tag, null);
27 }
28 return info;
29 }