1. /**
    
  2.  * Copyright (c) Meta Platforms, Inc. and affiliates.
    
  3.  *
    
  4.  * This source code is licensed under the MIT license found in the
    
  5.  * LICENSE file in the root directory of this source tree.
    
  6.  *
    
  7.  * @emails react-core
    
  8.  */
    
  9. 
    
  10. 'use strict';
    
  11. 
    
  12. let React;
    
  13. let ReactDOM;
    
  14. let ReactDOMServer;
    
  15. 
    
  16. describe('ReactDOMSVG', () => {
    
  17.   beforeEach(() => {
    
  18.     React = require('react');
    
  19.     ReactDOM = require('react-dom');
    
  20.     ReactDOMServer = require('react-dom/server');
    
  21.   });
    
  22. 
    
  23.   it('creates initial namespaced markup', () => {
    
  24.     const markup = ReactDOMServer.renderToString(
    
  25.       <svg>
    
  26.         <image xlinkHref="http://i.imgur.com/w7GCRPb.png" />
    
  27.       </svg>,
    
  28.     );
    
  29.     expect(markup).toContain('xlink:href="http://i.imgur.com/w7GCRPb.png"');
    
  30.   });
    
  31. 
    
  32.   it('creates elements with SVG namespace inside SVG tag during mount', () => {
    
  33.     const node = document.createElement('div');
    
  34.     let div,
    
  35.       div2,
    
  36.       div3,
    
  37.       foreignObject,
    
  38.       foreignObject2,
    
  39.       g,
    
  40.       image,
    
  41.       image2,
    
  42.       image3,
    
  43.       p,
    
  44.       svg,
    
  45.       svg2,
    
  46.       svg3,
    
  47.       svg4;
    
  48.     ReactDOM.render(
    
  49.       <div>
    
  50.         <svg ref={el => (svg = el)}>
    
  51.           <g ref={el => (g = el)} strokeWidth="5">
    
  52.             <svg ref={el => (svg2 = el)}>
    
  53.               <foreignObject ref={el => (foreignObject = el)}>
    
  54.                 <svg ref={el => (svg3 = el)}>
    
  55.                   <svg ref={el => (svg4 = el)} />
    
  56.                   <image
    
  57.                     ref={el => (image = el)}
    
  58.                     xlinkHref="http://i.imgur.com/w7GCRPb.png"
    
  59.                   />
    
  60.                 </svg>
    
  61.                 <div ref={el => (div = el)} />
    
  62.               </foreignObject>
    
  63.             </svg>
    
  64.             <image
    
  65.               ref={el => (image2 = el)}
    
  66.               xlinkHref="http://i.imgur.com/w7GCRPb.png"
    
  67.             />
    
  68.             <foreignObject ref={el => (foreignObject2 = el)}>
    
  69.               <div ref={el => (div2 = el)} />
    
  70.             </foreignObject>
    
  71.           </g>
    
  72.         </svg>
    
  73.         <p ref={el => (p = el)}>
    
  74.           <svg>
    
  75.             <image
    
  76.               ref={el => (image3 = el)}
    
  77.               xlinkHref="http://i.imgur.com/w7GCRPb.png"
    
  78.             />
    
  79.           </svg>
    
  80.         </p>
    
  81.         <div ref={el => (div3 = el)} />
    
  82.       </div>,
    
  83.       node,
    
  84.     );
    
  85.     [svg, svg2, svg3, svg4].forEach(el => {
    
  86.       expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  87.       // SVG tagName is case sensitive.
    
  88.       expect(el.tagName).toBe('svg');
    
  89.     });
    
  90.     expect(g.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  91.     expect(g.tagName).toBe('g');
    
  92.     expect(g.getAttribute('stroke-width')).toBe('5');
    
  93.     expect(p.namespaceURI).toBe('http://www.w3.org/1999/xhtml');
    
  94.     // DOM tagName is capitalized by browsers.
    
  95.     expect(p.tagName).toBe('P');
    
  96.     [image, image2, image3].forEach(el => {
    
  97.       expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  98.       expect(el.tagName).toBe('image');
    
  99.       expect(el.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).toBe(
    
  100.         'http://i.imgur.com/w7GCRPb.png',
    
  101.       );
    
  102.     });
    
  103.     [foreignObject, foreignObject2].forEach(el => {
    
  104.       expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  105.       expect(el.tagName).toBe('foreignObject');
    
  106.     });
    
  107.     [div, div2, div3].forEach(el => {
    
  108.       expect(el.namespaceURI).toBe('http://www.w3.org/1999/xhtml');
    
  109.       expect(el.tagName).toBe('DIV');
    
  110.     });
    
  111.   });
    
  112. 
    
  113.   it('creates elements with SVG namespace inside SVG tag during update', () => {
    
  114.     let inst,
    
  115.       div,
    
  116.       div2,
    
  117.       foreignObject,
    
  118.       foreignObject2,
    
  119.       g,
    
  120.       image,
    
  121.       image2,
    
  122.       svg,
    
  123.       svg2,
    
  124.       svg3,
    
  125.       svg4;
    
  126. 
    
  127.     class App extends React.Component {
    
  128.       state = {step: 0};
    
  129.       render() {
    
  130.         inst = this;
    
  131.         const {step} = this.state;
    
  132.         if (step === 0) {
    
  133.           return null;
    
  134.         }
    
  135.         return (
    
  136.           <g ref={el => (g = el)} strokeWidth="5">
    
  137.             <svg ref={el => (svg2 = el)}>
    
  138.               <foreignObject ref={el => (foreignObject = el)}>
    
  139.                 <svg ref={el => (svg3 = el)}>
    
  140.                   <svg ref={el => (svg4 = el)} />
    
  141.                   <image
    
  142.                     ref={el => (image = el)}
    
  143.                     xlinkHref="http://i.imgur.com/w7GCRPb.png"
    
  144.                   />
    
  145.                 </svg>
    
  146.                 <div ref={el => (div = el)} />
    
  147.               </foreignObject>
    
  148.             </svg>
    
  149.             <image
    
  150.               ref={el => (image2 = el)}
    
  151.               xlinkHref="http://i.imgur.com/w7GCRPb.png"
    
  152.             />
    
  153.             <foreignObject ref={el => (foreignObject2 = el)}>
    
  154.               <div ref={el => (div2 = el)} />
    
  155.             </foreignObject>
    
  156.           </g>
    
  157.         );
    
  158.       }
    
  159.     }
    
  160. 
    
  161.     const node = document.createElement('div');
    
  162.     ReactDOM.render(
    
  163.       <svg ref={el => (svg = el)}>
    
  164.         <App />
    
  165.       </svg>,
    
  166.       node,
    
  167.     );
    
  168.     inst.setState({step: 1});
    
  169. 
    
  170.     [svg, svg2, svg3, svg4].forEach(el => {
    
  171.       expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  172.       // SVG tagName is case sensitive.
    
  173.       expect(el.tagName).toBe('svg');
    
  174.     });
    
  175.     expect(g.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  176.     expect(g.tagName).toBe('g');
    
  177.     expect(g.getAttribute('stroke-width')).toBe('5');
    
  178.     [image, image2].forEach(el => {
    
  179.       expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  180.       expect(el.tagName).toBe('image');
    
  181.       expect(el.getAttributeNS('http://www.w3.org/1999/xlink', 'href')).toBe(
    
  182.         'http://i.imgur.com/w7GCRPb.png',
    
  183.       );
    
  184.     });
    
  185.     [foreignObject, foreignObject2].forEach(el => {
    
  186.       expect(el.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  187.       expect(el.tagName).toBe('foreignObject');
    
  188.     });
    
  189.     [div, div2].forEach(el => {
    
  190.       expect(el.namespaceURI).toBe('http://www.w3.org/1999/xhtml');
    
  191.       // DOM tagName is capitalized by browsers.
    
  192.       expect(el.tagName).toBe('DIV');
    
  193.     });
    
  194.   });
    
  195. 
    
  196.   it('can render SVG into a non-React SVG tree', () => {
    
  197.     const outerSVGRoot = document.createElementNS(
    
  198.       'http://www.w3.org/2000/svg',
    
  199.       'svg',
    
  200.     );
    
  201.     const container = document.createElementNS(
    
  202.       'http://www.w3.org/2000/svg',
    
  203.       'g',
    
  204.     );
    
  205.     outerSVGRoot.appendChild(container);
    
  206.     let image;
    
  207.     ReactDOM.render(<image ref={el => (image = el)} />, container);
    
  208.     expect(image.namespaceURI).toBe('http://www.w3.org/2000/svg');
    
  209.     expect(image.tagName).toBe('image');
    
  210.   });
    
  211. 
    
  212.   it('can render HTML into a foreignObject in non-React SVG tree', () => {
    
  213.     const outerSVGRoot = document.createElementNS(
    
  214.       'http://www.w3.org/2000/svg',
    
  215.       'svg',
    
  216.     );
    
  217.     const container = document.createElementNS(
    
  218.       'http://www.w3.org/2000/svg',
    
  219.       'foreignObject',
    
  220.     );
    
  221.     outerSVGRoot.appendChild(container);
    
  222.     let div;
    
  223.     ReactDOM.render(<div ref={el => (div = el)} />, container);
    
  224.     expect(div.namespaceURI).toBe('http://www.w3.org/1999/xhtml');
    
  225.     expect(div.tagName).toBe('DIV');
    
  226.   });
    
  227. });