<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import style from './SVG.pcss';

const parseXML = (text, options = null) => {
  const defaultOptions = {
    wrapper: 'div',
    safeIds: [],
    padding: 0,
    aspect: {
      x: null,
      y: null,
    },
    max: {
      width: 0,
      height: 0,
    },
  };
  const opts = { ...defaultOptions, ...options };
  const oDOM = new DOMParser().parseFromString(text, 'image/svg+xml');
  if (oDOM.documentElement.nodeName === 'parsererror' || oDOM.documentElement.nodeName !== 'svg') {
    return false;
  }

  // check if there are width or height attributes.
  // if true, keep their values stripping our units and remove them as attributes.
  let width = oDOM.documentElement.getAttribute('width');
  let height = oDOM.documentElement.getAttribute('height');
  if (width !== null) {
    width = width.replace(/[^0-9.,]/g, '');
    oDOM.documentElement.removeAttribute('width');
  }
  if (height !== null) {
    height = height.replace(/[^0-9.,]/g, '');
    oDOM.documentElement.removeAttribute('height');
  }

  // get the viewBox and get its individual values
  let viewBox = oDOM.documentElement.getAttribute('viewBox');
  if (viewBox !== null) {
    viewBox = viewBox.split(' ');
    if (viewBox.length !== 4) {
      viewBox = viewBox.split(',');
    }
    if (viewBox.length === 4) {
      viewBox = {
        minX: viewBox[0],
        minY: viewBox[1],
        width: viewBox[2],
        height: viewBox[3],
      };
    } else {
      // if we couldn't retrieve the viewBox values, reset it
      viewBox = null;
    }
  }
  if (opts.aspect.x === null) {
    // if no width attribute was found but we have the viewBox
    if (width === null && viewBox !== null) {
      ({ width } = viewBox);
    }
    opts.aspect.x = Math.round(width);
  }
  if (opts.aspect.y === null) {
    if (height === null && viewBox !== null) {
      ({ height } = viewBox);
    }
    opts.aspect.y = Math.round(height);
  }

  // in case no aspect width and height was found or given
  if (opts.aspect.x === null || opts.aspect.y === null) {
    throw new Error('No aspect.x and aspect.y for the SVG was found or given');
  }

  // if max dimensions are set to null, use the aspect
  if (opts.max.width === null) {
    opts.max.width = `${opts.aspect.x}px`;
  }
  if (opts.max.height === null) {
    opts.max.height = `${opts.aspect.y}px`;
  }

  // do some clean-up
  oDOM.querySelectorAll('metadata').forEach(el => el.remove());

  // in case no viewBox was found
  if (viewBox === null) {
    viewBox = {
      minX: 0,
      minY: 0,
      width: opts.aspect.x,
      height: opts.aspect.y,
    };
  }

  // in case padding is needed
  if (opts.padding) {
    // adjust viewBox for padding
    viewBox.minX -= opts.padding;
    viewBox.minY -= opts.padding;
    viewBox.width += opts.padding;
    viewBox.height += opts.padding;
  }

  // set the new viewBox
  oDOM.documentElement.setAttribute(
    'viewBox',
    `${viewBox.minX} ${viewBox.minY} ${viewBox.width} ${viewBox.height}`,
  );
  // set the class
  oDOM.documentElement.setAttribute('class', style.svgInlinerSVG);

  const serializer = new XMLSerializer();
  let htmlAsString = '';

  // only if the aspect is not explicitly set to zero (disables placeholder)
  if (opts.aspect.x > 0 && opts.aspect.y > 0) {
    // create the canvas and context for our aspect holder
    const canvas = document.createElement('canvas');
    canvas.width = opts.aspect.x;
    canvas.height = opts.aspect.y;

    // create the aspect holder
    const aspectHolder = document.createElement('img');
    aspectHolder.setAttribute('class', style.svgInlinerAspect);
    aspectHolder.setAttribute('src', canvas.toDataURL('image/png', 0));
    if (opts.max.width) {
      aspectHolder.style.maxWidth = opts.max.width;
    }
    if (opts.max.height) {
      aspectHolder.style.maxHeight = opts.max.height;
    }
<commit_msg>feat(src/components/SVG.jsx): add alt attr on placeholders<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import style from './SVG.pcss';

const parseXML = (text, options = null) => {
  const defaultOptions = {
    wrapper: 'div',
    safeIds: [],
    padding: 0,
    aspect: {
      x: null,
      y: null,
    },
    max: {
      width: 0,
      height: 0,
    },
  };
  const opts = { ...defaultOptions, ...options };
  const oDOM = new DOMParser().parseFromString(text, 'image/svg+xml');
  if (oDOM.documentElement.nodeName === 'parsererror' || oDOM.documentElement.nodeName !== 'svg') {
    return false;
  }

  // check if there are width or height attributes.
  // if true, keep their values stripping our units and remove them as attributes.
  let width = oDOM.documentElement.getAttribute('width');
  let height = oDOM.documentElement.getAttribute('height');
  if (width !== null) {
    width = width.replace(/[^0-9.,]/g, '');
    oDOM.documentElement.removeAttribute('width');
  }
  if (height !== null) {
    height = height.replace(/[^0-9.,]/g, '');
    oDOM.documentElement.removeAttribute('height');
  }

  // get the viewBox and get its individual values
  let viewBox = oDOM.documentElement.getAttribute('viewBox');
  if (viewBox !== null) {
    viewBox = viewBox.split(' ');
    if (viewBox.length !== 4) {
      viewBox = viewBox.split(',');
    }
    if (viewBox.length === 4) {
      viewBox = {
        minX: viewBox[0],
        minY: viewBox[1],
        width: viewBox[2],
        height: viewBox[3],
      };
    } else {
      // if we couldn't retrieve the viewBox values, reset it
      viewBox = null;
    }
  }
  if (opts.aspect.x === null) {
    // if no width attribute was found but we have the viewBox
    if (width === null && viewBox !== null) {
      ({ width } = viewBox);
    }
    opts.aspect.x = Math.round(width);
  }
  if (opts.aspect.y === null) {
    if (height === null && viewBox !== null) {
      ({ height } = viewBox);
    }
    opts.aspect.y = Math.round(height);
  }

  // in case no aspect width and height was found or given
  if (opts.aspect.x === null || opts.aspect.y === null) {
    throw new Error('No aspect.x and aspect.y for the SVG was found or given');
  }

  // if max dimensions are set to null, use the aspect
  if (opts.max.width === null) {
    opts.max.width = `${opts.aspect.x}px`;
  }
  if (opts.max.height === null) {
    opts.max.height = `${opts.aspect.y}px`;
  }

  // do some clean-up
  oDOM.querySelectorAll('metadata').forEach(el => el.remove());

  // in case no viewBox was found
  if (viewBox === null) {
    viewBox = {
      minX: 0,
      minY: 0,
      width: opts.aspect.x,
      height: opts.aspect.y,
    };
  }

  // in case padding is needed
  if (opts.padding) {
    // adjust viewBox for padding
    viewBox.minX -= opts.padding;
    viewBox.minY -= opts.padding;
    viewBox.width += opts.padding;
    viewBox.height += opts.padding;
  }

  // set the new viewBox
  oDOM.documentElement.setAttribute(
    'viewBox',
    `${viewBox.minX} ${viewBox.minY} ${viewBox.width} ${viewBox.height}`,
  );
  // set the class
  oDOM.documentElement.setAttribute('class', style.svgInlinerSVG);

  const serializer = new XMLSerializer();
  let htmlAsString = '';

  // only if the aspect is not explicitly set to zero (disables placeholder)
  if (opts.aspect.x > 0 && opts.aspect.y > 0) {
    // create the canvas and context for our aspect holder
    const canvas = document.createElement('canvas');
    canvas.width = opts.aspect.x;
    canvas.height = opts.aspect.y;

    // create the aspect holder
    const aspectHolder = document.createElement('img');
    aspectHolder.setAttribute('class', style.svgInlinerAspect);
    aspectHolder.setAttribute('src', canvas.toDataURL('image/png', 0));
    aspectHolder.setAttribute('alt', 'placeholder');
    if (opts.max.width) {
      aspectHolder.style.maxWidth = opts.max.width;
    }
    if (opts.max.height) {
      aspectHolder.style.maxHeight = opts.max.height;
    }

{'fraction_non_alphanumeric': 0.15350766909730953, 'fraction_numerical': 0.004526024641689716, 'mean_word_length': 2.706896551724138, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '477162', 'n_tokens_mistral': 2614, 'n_tokens_neox': 2591, 'n_words': 675}