components/SVG/SVGProvider.js

/**
 * SVGProvider is used as container for aplication.
 * Purpose of this container is to load SVG-s from server.
 *
 * @module SVG/SVGProvider
 */
import React from 'react';
import PropTypes from 'prop-types';
import Constants from '../../constants';

/**
 * @typedef {object} props
 * @property {boolean} isAccountOpen
 * @property {boolean} isPMOpen
 * @property {boolean} isBetslipOpen
 * @property {string} cnt
 * @property {string} wrapperClass
 * @property {object} children
 */
class SVGProvider extends React.PureComponent {
  constructor() {
    super();
    /**
     * @member {object}
     * @description Reference on wrapper element
     */
    this.wrapper = undefined;
    /**
     * @member {Array}
     * @description Loaded SVG paths
     */
    this.loadedSVGs = [];
  }

  /**
   * Create context for child components
   *
   * @function
   * @returns {object} SVG object with all functions from container
   */
  getChildContext() {
    return {
      svg: {
        loadedSVGs: this.loadedSVGs,
        checkSvg: this.checkSvg,
        loadSvg: this.loadSvg,
        getIdFromSrc: this.getIdFromSrc,
        getNameFromSrc: this.getNameFromSrc,
      },
    };
  }

  /**
   * Get SVG id
   *
   * @function
   * @param {string} src
   * @returns {string}
   */
  getIdFromSrc = (src) => `#${src.split('#')[1]}`;

  /**
   * Get SVG name
   *
   * @function
   * @param {string} src
   * @returns {string}
   */
  getNameFromSrc = (src) => src.split(/([^/]+(.svg))/)[1];

  /**
   * Check if SVG already loaded from server
   *
   * @function
   * @param {string} src
   * @returns {boolean}
   */
  checkSvg = (src) => !!this.loadedSVGs.find((item) => item === this.getNameFromSrc(src));

  /**
   * Load SVG from server
   *
   * @function
   * @param {string} src
   * @returns {void}
   */
  loadSvg = (src) => {
    if (this.props.cnt) {
      const route = this.getNameFromSrc(src).replace(/\s/g, '');
      this.loadedSVGs.push(route);
      const ajax = new XMLHttpRequest();
      ajax.open('GET', `${this.props.cnt}/${route}?ver=${Constants.STATIC_VERSION}`, true);
      ajax.send();
      ajax.onload = () => {
        if (route) {
          const div = document.createElement('div');
          div.setAttribute('id', route);
          div.setAttribute('style', 'height:0px');
          div.innerHTML = ajax.responseText;
          this.wrapper.appendChild(div);
        }
      };
    }
  };

  /**
   * Render
   *
   * @see module:SVG/SVGComponent
   * @returns {view}
   */
  render() {
    return (
      <div
        id="app"
        className={`app${this.props.isPMOpen ? ' pml-open' : ''}${this.props.isAccountOpen ? ' app--scroll-disabled' : ''}${this.props.isBetslipOpen ? ' betslip-open' : ''}`}
      >
        <div id="wrapper" className={this.props.wrapperClass}>
          <div ref={(ref) => { this.wrapper = ref; }} id="svg-wrapper" style={{ height: '0px' }} />
          {this.props.children}
        </div>
      </div>
    );
  }
}

SVGProvider.childContextTypes = {
  svg: PropTypes.object,
};

export default SVGProvider;