# All files / components/MessageBox MarkdownIt.js

88.46% Statements 23/26
70% Branches 7/10
85.71% Functions 6/7
88.46% Lines 23/26

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99

    19x
    19x
    19x

    19x
    1x

    19x
    1x

    1x

    19x

    19x
    19x

    19x

    19x
    19x
    2x

    19x

    23x

    23x

    23x
    19x

    4x

    4x

    4x

     /* eslint-disable no-underscore-dangle */
    import React, { Component } from 'react';
    import PropTypes from 'prop-types';
    import Markdown from 'markdown-it';
    import truncate from 'truncate-html';
    import applyLetsTalkPlugins from '@lets-talk/markdownit-plugins';

    class MarkdownIt extends Component {
      componentWillUpdate(nextProps, /* nextState */) {
        const { options } = this.props;
        if (nextProps.options !== options) {
          this.md = new Markdown(nextProps.options);
        }
      }

      _generateInstance() {
        const { options } = this.props;
        this.md = new Markdown(options);
        this._setCustomPlugin();
      }

      _setCustomPlugin() {
        // Save the defaultRender
        const defaultRender = this.md.renderer.rules.link_open || function renderToken(tokens, idx, options, env, self) {
          return self.renderToken(tokens, idx, options);
        };

        this.md.renderer.rules.link_open = (tokens, idx, options, env, self) => {
          const newTokens = applyLetsTalkPlugins(tokens, idx);
          // Pass token to default renderer.
          return defaultRender(newTokens, idx, options, env, self);
        };
      }

      renderMarkdown(source) {
        const { linkOptions } = this.props;

        Eif (!this.md) {
          this._generateInstance();
        }
        const { needsTruncate, truncateOffset } = linkOptions;

        let markdownContent = this.md.render(source);
        if (needsTruncate) {
          markdownContent = truncate(markdownContent, { length: truncateOffset });
        }

        return markdownContent;
      }

      render() {
        const {
          source, tagName, options, linkOptions, ...other
        } = this.props;

        const Container = tagName;

        if (source) {
          return (
            <Container className="markdown-it-container" dangerouslySetInnerHTML={{ __html: this.renderMarkdown(source) }} {...other} />
          );
        }

        return (
          <Container className="markdown-it-container" {...other} />
        );
      }
    }

    MarkdownIt.propTypes = {
      /** the tagName of the container element */
      tagName: PropTypes.string,
      /** option to turn on string indent removal */
      stripIndent: PropTypes.bool,
      /** option to pass into the markdown-it constructor */
      options: PropTypes.object,
      /** option to pass into the markdown-it iterator plugin */
      linkOptions: PropTypes.object,
    };

    MarkdownIt.defaultProps = {
      /** the tagName should be <article> if it is the top-level  */
      tagName: 'span',
      stripIndent: false,
      options: {
        html: false,
        linkify: true,
        breaks: true,
      },
      linkOptions: {
        target: '_blank',
        needsTruncate: false,
        truncateOffset: 100,
      },
    };

    export default MarkdownIt;