All files / src/matchers Emoji.js

100% Statements 26/26
93.1% Branches 27/29
100% Functions 6/6
100% Lines 24/24
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 100                                    2x 2x           1811x 46x     1765x           665x       5200x     5200x 511x       511x 447x     447x 1x       446x           5200x 1106x       1106x                 5200x         10x 2x   2x 1x   1x                 9x      
/**
 * @copyright   2016, Miles Johnson
 * @license     https://opensource.org/licenses/MIT
 * @flow
 */
 
import React from 'react';
import Matcher from '../Matcher';
import Emoji from '../components/Emoji';
import {
  EMOJI_PATTERN,
  EMOJI_SHORTNAME_PATTERN,
  SHORTNAME_TO_UNICODE,
  UNICODE_TO_SHORTNAME,
} from '../data/emoji';
 
import type { MatchResponse, EmojiProps, EmojiOptions, ParsedNodes } from '../types';
 
const EMOJI_REGEX = new RegExp(EMOJI_PATTERN);
const EMOJI_SHORTNAME_REGEX = new RegExp(EMOJI_SHORTNAME_PATTERN, 'i');
 
export default class EmojiMatcher extends Matcher<EmojiOptions> {
  options: EmojiOptions;
 
  replaceWith(match: string, props: Object = {}): React.Element<EmojiProps> {
    if (this.options.renderUnicode) {
      return props.unicode;
    }
 
    return (
      <Emoji {...props} />
    );
  }
 
  asTag(): string {
    return 'span';
  }
 
  match(string: string): ?MatchResponse {
    let response = null;
 
    // Should we convert shortnames to unicode?
    if (this.options.convertShortName && string.indexOf(':') >= 0) {
      response = this.doMatch(string, EMOJI_SHORTNAME_REGEX, matches => ({
        shortName: matches[0].toLowerCase(),
      }));
 
      if (response && response.shortName) {
        const unicode = SHORTNAME_TO_UNICODE[response.shortName];
 
        // Invalid shortname
        if (!unicode) {
          response = null;
 
        // We want to render using the unicode value
        } else {
          response.unicode = unicode;
        }
      }
    }
 
    // Should we convert unicode to SVG/PNG?
    if (this.options.convertUnicode && !response) {
      response = this.doMatch(string, EMOJI_REGEX, matches => ({
        unicode: matches[0],
      }));
 
      Iif (
        response && response.unicode &&
        !UNICODE_TO_SHORTNAME[response.unicode]
      ) {
        /* istanbul ignore next Hard to test */
        return null;
      }
    }
 
    return response;
  }
 
  onAfterParse(content: ParsedNodes): ParsedNodes {
    // When a single `Emoji` is the only content, enlarge it!
    if (content.length === 1) {
      let item = content[0];
 
      if (typeof item !== 'string' && React.isValidElement(item) && item.type === Emoji) {
        item = (item: React.Element<*>);
 
        return [
          React.cloneElement(item, {
            ...item.props,
            enlargeEmoji: true,
          }),
        ];
      }
    }
 
    return content;
  }
}