mirror of
				https://github.com/owncast/owncast.git
				synced 2025-11-04 05:17:27 +08:00 
			
		
		
		
	* highlighting: make case-insensitive, support unicode * highlighting: also highlight simplified/normalized form * highlighting: use MDN-recommended escape pattern
		
			
				
	
	
		
			56 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
			
		
		
	
	
			56 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			TypeScript
		
	
	
	
	
	
/* eslint-disable class-methods-use-this */
 | 
						|
import { ChildrenNode, Matcher, MatchResponse, Node } from 'interweave';
 | 
						|
import React from 'react';
 | 
						|
 | 
						|
export interface CustomProps {
 | 
						|
  children: React.ReactNode;
 | 
						|
  key: string;
 | 
						|
}
 | 
						|
 | 
						|
interface options {
 | 
						|
  highlightString: string;
 | 
						|
}
 | 
						|
 | 
						|
export class ChatMessageHighlightMatcher extends Matcher {
 | 
						|
  match(str: string): MatchResponse<{}> | null {
 | 
						|
    const { highlightString } = this.options as options;
 | 
						|
 | 
						|
    if (!highlightString) {
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
 | 
						|
    const escapedString = highlightString
 | 
						|
      .replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
 | 
						|
      .replace(/\s/g, '\\s');
 | 
						|
 | 
						|
    const normalizedString = escapedString.normalize('NFD').replace(/[\u0300-\u036f]/g, '');
 | 
						|
 | 
						|
    let highlightRegex = escapedString;
 | 
						|
    if (escapedString !== normalizedString) {
 | 
						|
      highlightRegex = `(?:${escapedString})|(?:${normalizedString})`;
 | 
						|
    }
 | 
						|
 | 
						|
    const result = str.match(new RegExp(highlightRegex, 'ui'));
 | 
						|
 | 
						|
    if (!result) {
 | 
						|
      return null;
 | 
						|
    }
 | 
						|
 | 
						|
    return {
 | 
						|
      index: result.index!,
 | 
						|
      length: result[0].length,
 | 
						|
      match: result[0],
 | 
						|
      valid: true,
 | 
						|
    };
 | 
						|
  }
 | 
						|
 | 
						|
  replaceWith(children: ChildrenNode, props: CustomProps): Node {
 | 
						|
    const { key } = props;
 | 
						|
    return React.createElement('mark', { key }, children);
 | 
						|
  }
 | 
						|
 | 
						|
  asTag(): string {
 | 
						|
    return 'mark';
 | 
						|
  }
 | 
						|
}
 |