<commit_before>import { SVGInjector } from '@tanem/svg-injector'
import * as PropTypes from 'prop-types'
import * as React from 'react'

import shallowDiffers from './shallow-differs'
import { Props, State, WrapperType } from './types'

const svgNamespace = 'http://www.w3.org/2000/svg'
const xlinkNamespace = 'http://www.w3.org/1999/xlink'

export class ReactSVG extends React.Component<Props, State> {
  static defaultProps = {
    afterInjection: () => undefined,
    beforeInjection: () => undefined,
    evalScripts: 'never',
    fallback: null,
    loading: null,
    renumerateIRIElements: true,
    useRequestCache: true,
    wrapper: 'div',
  }

  static propTypes = {
    afterInjection: PropTypes.func,
    beforeInjection: PropTypes.func,
    evalScripts: PropTypes.oneOf(['always', 'once', 'never']),
    fallback: PropTypes.oneOfType([
      PropTypes.func,
      PropTypes.object,
      PropTypes.string,
    ]),
    loading: PropTypes.oneOfType([
      PropTypes.func,
      PropTypes.object,
      PropTypes.string,
    ]),
    renumerateIRIElements: PropTypes.bool,
    src: PropTypes.string.isRequired,
    useRequestCache: PropTypes.bool,
    wrapper: PropTypes.oneOf(['div', 'span', 'svg']),
  }

  initialState = {
    hasError: false,
    isLoading: true,
  }

  state = this.initialState

  _isMounted = false

  container?: WrapperType | null

  nonReactElement?: WrapperType | null

  refCallback = (container: WrapperType | null) => {
    this.container = container
  }

  renderSVG() {
    /* istanbul ignore else */
    if (this.container instanceof Node) {
      const {
        beforeInjection,
        evalScripts,
        renumerateIRIElements,
        src,
        useRequestCache,
      } = this.props

      /* eslint-disable @typescript-eslint/no-non-null-assertion */
      const afterInjection = this.props.afterInjection!
      const wrapper = this.props.wrapper!
      /* eslint-enable @typescript-eslint/no-non-null-assertion */

      const nonReactElement =
        wrapper === 'svg'
          ? document.createElementNS(svgNamespace, wrapper)
          : document.createElement(wrapper)

      nonReactElement.dataset.src = src

      this.nonReactElement = this.container.appendChild(nonReactElement)

      const afterEach = (error: Error | null, svg?: SVGSVGElement) => {
        if (error) {
          this.removeSVG()

          if (!this._isMounted) {
            afterInjection(error)
            return
          }
        }

        this.nonReactElement = svg

        // TODO (Tane): It'd be better to cleanly unsubscribe from SVGInjector
        // callbacks instead of tracking a property like this.
        if (this._isMounted) {
          this.setState(
            () => ({<commit_msg>Set required attributes on non react element<commit_after>import { SVGInjector } from '@tanem/svg-injector'
import * as PropTypes from 'prop-types'
import * as React from 'react'

import shallowDiffers from './shallow-differs'
import { Props, State, WrapperType } from './types'

const svgNamespace = 'http://www.w3.org/2000/svg'
const xlinkNamespace = 'http://www.w3.org/1999/xlink'

export class ReactSVG extends React.Component<Props, State> {
  static defaultProps = {
    afterInjection: () => undefined,
    beforeInjection: () => undefined,
    evalScripts: 'never',
    fallback: null,
    loading: null,
    renumerateIRIElements: true,
    useRequestCache: true,
    wrapper: 'div',
  }

  static propTypes = {
    afterInjection: PropTypes.func,
    beforeInjection: PropTypes.func,
    evalScripts: PropTypes.oneOf(['always', 'once', 'never']),
    fallback: PropTypes.oneOfType([
      PropTypes.func,
      PropTypes.object,
      PropTypes.string,
    ]),
    loading: PropTypes.oneOfType([
      PropTypes.func,
      PropTypes.object,
      PropTypes.string,
    ]),
    renumerateIRIElements: PropTypes.bool,
    src: PropTypes.string.isRequired,
    useRequestCache: PropTypes.bool,
    wrapper: PropTypes.oneOf(['div', 'span', 'svg']),
  }

  initialState = {
    hasError: false,
    isLoading: true,
  }

  state = this.initialState

  _isMounted = false

  container?: WrapperType | null

  nonReactElement?: WrapperType | null

  refCallback = (container: WrapperType | null) => {
    this.container = container
  }

  renderSVG() {
    /* istanbul ignore else */
    if (this.container instanceof Node) {
      const {
        beforeInjection,
        evalScripts,
        renumerateIRIElements,
        src,
        useRequestCache,
      } = this.props

      /* eslint-disable @typescript-eslint/no-non-null-assertion */
      const afterInjection = this.props.afterInjection!
      const wrapper = this.props.wrapper!
      /* eslint-enable @typescript-eslint/no-non-null-assertion */

      let nonReactElement

      if (wrapper === 'svg') {
        nonReactElement = document.createElementNS(svgNamespace, wrapper)
        nonReactElement.setAttribute('xmlns', svgNamespace)
        nonReactElement.setAttribute('xmlns:xlink', xlinkNamespace)
      } else {
        nonReactElement = document.createElement(wrapper)
      }

      nonReactElement.dataset.src = src

      this.nonReactElement = this.container.appendChild(nonReactElement)

      const afterEach = (error: Error | null, svg?: SVGSVGElement) => {
        if (error) {
          this.removeSVG()

          if (!this._isMounted) {
            afterInjection(error)
            return
          }
        }

        this.nonReactElement = svg

        // TODO (Tane): It'd be better to cleanly unsubscribe from SVGInjector
        // callbacks instead of tracking a property like this.
        if (this._isMounted) {
          this.setState(
            () => ({
{'fraction_non_alphanumeric': 0.11224131883549632, 'fraction_numerical': 0.00350754121360926, 'mean_word_length': 2.6769825918762087, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 4, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4963552', 'n_tokens_mistral': 1711, 'n_tokens_neox': 1715, 'n_words': 370}