mirror of
				https://github.com/lingble/chatwoot.git
				synced 2025-11-04 04:57:51 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			71 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			71 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import { marked } from 'marked';
 | 
						|
import DOMPurify from 'dompurify';
 | 
						|
import { escapeHtml, afterSanitizeAttributes } from './HTMLSanitizer';
 | 
						|
 | 
						|
const TWITTER_USERNAME_REGEX = /(^|[^@\w])@(\w{1,15})\b/g;
 | 
						|
const TWITTER_USERNAME_REPLACEMENT =
 | 
						|
  '$1<a href="http://twitter.com/$2" target="_blank" rel="noreferrer nofollow noopener">@$2</a>';
 | 
						|
 | 
						|
const TWITTER_HASH_REGEX = /(^|\s)#(\w+)/g;
 | 
						|
const TWITTER_HASH_REPLACEMENT =
 | 
						|
  '$1<a href="https://twitter.com/hashtag/$2" target="_blank" rel="noreferrer nofollow noopener">#$2</a>';
 | 
						|
 | 
						|
const USER_MENTIONS_REGEX = /mention:\/\/(user|team)\/(\d+)\/(.+)/gm;
 | 
						|
 | 
						|
class MessageFormatter {
 | 
						|
  constructor(message, isATweet = false, isAPrivateNote = false) {
 | 
						|
    this.message = DOMPurify.sanitize(escapeHtml(message || ''));
 | 
						|
    this.isAPrivateNote = isAPrivateNote;
 | 
						|
    this.isATweet = isATweet;
 | 
						|
    this.marked = marked;
 | 
						|
 | 
						|
    const renderer = {
 | 
						|
      heading(text) {
 | 
						|
        return `<strong>${text}</strong>`;
 | 
						|
      },
 | 
						|
      link(url, title, text) {
 | 
						|
        const mentionRegex = new RegExp(USER_MENTIONS_REGEX);
 | 
						|
        if (url.match(mentionRegex)) {
 | 
						|
          return `<span class="prosemirror-mention-node">${text}</span>`;
 | 
						|
        }
 | 
						|
        return `<a rel="noreferrer noopener nofollow" href="${url}" class="link" title="${title ||
 | 
						|
          ''}" target="_blank">${text}</a>`;
 | 
						|
      },
 | 
						|
    };
 | 
						|
    this.marked.use({ renderer });
 | 
						|
  }
 | 
						|
 | 
						|
  formatMessage() {
 | 
						|
    if (this.isATweet && !this.isAPrivateNote) {
 | 
						|
      const withUserName = this.message.replace(
 | 
						|
        TWITTER_USERNAME_REGEX,
 | 
						|
        TWITTER_USERNAME_REPLACEMENT
 | 
						|
      );
 | 
						|
      const withHash = withUserName.replace(
 | 
						|
        TWITTER_HASH_REGEX,
 | 
						|
        TWITTER_HASH_REPLACEMENT
 | 
						|
      );
 | 
						|
      const markedDownOutput = marked(withHash);
 | 
						|
      return markedDownOutput;
 | 
						|
    }
 | 
						|
    DOMPurify.addHook('afterSanitizeAttributes', afterSanitizeAttributes);
 | 
						|
    return DOMPurify.sanitize(
 | 
						|
      marked(this.message, { breaks: true, gfm: true })
 | 
						|
    );
 | 
						|
  }
 | 
						|
 | 
						|
  get formattedMessage() {
 | 
						|
    return this.formatMessage();
 | 
						|
  }
 | 
						|
 | 
						|
  get plainText() {
 | 
						|
    const strippedOutHtml = new DOMParser().parseFromString(
 | 
						|
      this.formattedMessage,
 | 
						|
      'text/html'
 | 
						|
    );
 | 
						|
    return strippedOutHtml.body.textContent || '';
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
export default MessageFormatter;
 |