<commit_before>import React, { Component } from 'react';
import styled from '@emotion/styled';
import { document, window } from 'global';
import memoize from 'memoizerific';
import jsx from 'react-syntax-highlighter/languages/prism/jsx';
import bash from 'react-syntax-highlighter/languages/prism/bash';
import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light';
import prettier from 'prettier/standalone';
import parser from 'prettier/parser-babylon';
import { ActionBar, ActionButton } from '../panel_actionbar/panel_actionbar';

registerLanguage('jsx', jsx);
registerLanguage('bash', bash);

const themedSyntax = memoize(2)(theme =>
  Object.entries(theme.code).reduce((acc, [key, val]) => ({ ...acc, [`* .${key}`]: val }), {})
);

const Wrapper = styled.div(
  {
    position: 'relative',
    overflow: 'hidden',
  },
  ({ theme, bordered }) =>
    bordered
      ? {
          border: theme.mainBorder,
          borderRadius: theme.mainBorderRadius,
          background: theme.barFill,
        }
      : {}
);
const Scroller = styled.div(
  {
    position: 'relative',
    overflow: 'auto',
  },
  ({ theme }) => ({
    '& code': {
      paddingRight: theme.layoutMargin,
      opacity: 0.7,
    },
  }),
  ({ theme }) => themedSyntax(theme)
);
const Pre = styled.pre(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));
const Code = styled.code({
  flex: 1,
  paddingRight: 0,
  opacity: 1,
});

export default class Copyable extends Component {
  state = { copied: false };

  constructor(props) {
    super(props);

    const { language, children } = props;
    let formattedCode = children.trim();
    if (language === 'jsx') {
      formattedCode = prettier.format(formattedCode, {
        parser: 'babylon',
        plugins: [parser],
      });
    }
    this.state = { formattedCode };
  }

  onClick = e => {
    const { children } = this.props;

    e.preventDefault();
    const tmp = document.createElement('TEXTAREA');
    const focus = document.activeElement;

    tmp.value = children;

    document.body.appendChild(tmp);
    tmp.select();
    document.execCommand('copy');
    document.body.removeChild(tmp);
    focus.focus();

    this.setState({ copied: true }, () => {
      window.setTimeout(() => this.setState({ copied: false }), 1500);
    });
  };

  render() {
    const { children, language = 'jsx', copyable = true, bordered, padded, ...rest } = this.props;
    const { copied, formattedCode } = this.state;

    return children ? (
      <Wrapper bordered={bordered} padded={padded}>
        <Scroller>
          <SyntaxHighlighter
            padded={padded || bordered}
            language={language}
            useInlineStyles={false}
            PreTag={Pre}
            CodeTag={Code}
            lineNumberContainerStyle={{}}
            {...rest}
          >
            {formattedCode}
          </SyntaxHighlighter>
        </Scroller>
        {copyable ? (
          <ActionBar>
            <ActionButton onClick={this.onClick}>{copied ? 'copied' : 'copy'}</ActionButton>
          </ActionBar><commit_msg>Fix issue with previous commit<commit_after>import React, { Component } from 'react';
import styled from '@emotion/styled';
import { document, window } from 'global';
import memoize from 'memoizerific';
import jsx from 'react-syntax-highlighter/languages/prism/jsx';
import bash from 'react-syntax-highlighter/languages/prism/bash';
import SyntaxHighlighter, { registerLanguage } from 'react-syntax-highlighter/prism-light';
import prettier from 'prettier/standalone';
import parser from 'prettier/parser-babylon';
import { ActionBar, ActionButton } from '../panel_actionbar/panel_actionbar';

registerLanguage('jsx', jsx);
registerLanguage('bash', bash);

const themedSyntax = memoize(2)(theme =>
  Object.entries(theme.code).reduce((acc, [key, val]) => ({ ...acc, [`* .${key}`]: val }), {})
);

const Wrapper = styled.div(
  {
    position: 'relative',
    overflow: 'hidden',
  },
  ({ theme, bordered }) =>
    bordered
      ? {
          border: theme.mainBorder,
          borderRadius: theme.mainBorderRadius,
          background: theme.barFill,
        }
      : {}
);
const Scroller = styled.div(
  {
    position: 'relative',
    overflow: 'auto',
  },
  ({ theme }) => ({
    '& code': {
      paddingRight: theme.layoutMargin,
      opacity: 0.7,
    },
  }),
  ({ theme }) => themedSyntax(theme)
);
const Pre = styled.pre(({ theme, padded }) => ({
  display: 'flex',
  justifyContent: 'flex-start',
  margin: 0,
  padding: padded ? theme.layoutMargin : 0,
}));
const Code = styled.code({
  flex: 1,
  paddingRight: 0,
  opacity: 1,
});

export default class Copyable extends Component {
  state = { copied: false };

  formatCode = memoize(2)((language, code) => {
    let formattedCode = code;
    if (language === 'jsx') {
      try {
        formattedCode = prettier.format(code, {
          parser: 'babylon',
          plugins: [parser],
        });
      } catch (error) {
        console.warn("Couldn't format code", formattedCode); // eslint-disable-line no-console
      }
    }
    return formattedCode;
  });

  onClick = e => {
    const { children } = this.props;

    e.preventDefault();
    const tmp = document.createElement('TEXTAREA');
    const focus = document.activeElement;

    tmp.value = children;

    document.body.appendChild(tmp);
    tmp.select();
    document.execCommand('copy');
    document.body.removeChild(tmp);
    focus.focus();

    this.setState({ copied: true }, () => {
      window.setTimeout(() => this.setState({ copied: false }), 1500);
    });
  };

  render() {
    const { children, language = 'jsx', copyable = true, bordered, padded, ...rest } = this.props;
    const { copied } = this.state;

    return children ? (
      <Wrapper bordered={bordered} padded={padded}>
        <Scroller>
          <SyntaxHighlighter
            padded={padded || bordered}
            language={language}
            useInlineStyles={false}
            PreTag={Pre}
            CodeTag={Code}
            lineNumberContainerStyle={{}}
            {...rest}
          >
            {this.formatCode(language, children.trim())}
          </SyntaxHighlighter>
        </Scroller>
        {copyable ? (
          <ActionBar>
            <ActionButton onClick={this.onClick}>{copied ? 'copied' : 'copy'}</ActionButton>
          </ActionBar>
{'fraction_non_alphanumeric': 0.1543343653250774, 'fraction_numerical': 0.003869969040247678, 'mean_word_length': 2.76734693877551, 'pattern_counts': {'":': 0, '<': 21, '<?xml version=': 0, '>': 40, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '2493202', 'n_tokens_mistral': 1993, 'n_tokens_neox': 1955, 'n_words': 425}