text.ts 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. import { TextMatch } from 'app/types/explore';
  2. import xss from 'xss';
  3. /**
  4. * Adapt findMatchesInText for react-highlight-words findChunks handler.
  5. * See https://github.com/bvaughn/react-highlight-words#props
  6. */
  7. export function findHighlightChunksInText({ searchWords, textToHighlight }) {
  8. return findMatchesInText(textToHighlight, searchWords.join(' '));
  9. }
  10. const cleanNeedle = (needle: string): string => {
  11. return needle.replace(/[[{(][\w,.-?:*+]+$/, '');
  12. };
  13. /**
  14. * Returns a list of substring regexp matches.
  15. */
  16. export function findMatchesInText(haystack: string, needle: string): TextMatch[] {
  17. // Empty search can send re.exec() into infinite loop, exit early
  18. if (!haystack || !needle) {
  19. return [];
  20. }
  21. const matches = [];
  22. const cleaned = cleanNeedle(needle);
  23. let regexp: RegExp;
  24. try {
  25. regexp = new RegExp(`(?:${cleaned})`, 'g');
  26. } catch (error) {
  27. return matches;
  28. }
  29. haystack.replace(regexp, (substring, ...rest) => {
  30. if (substring) {
  31. const offset = rest[rest.length - 2];
  32. matches.push({
  33. text: substring,
  34. start: offset,
  35. length: substring.length,
  36. end: offset + substring.length,
  37. });
  38. }
  39. return '';
  40. });
  41. return matches;
  42. }
  43. export function sanitize (unsanitizedString: string): string {
  44. try {
  45. return xss(unsanitizedString);
  46. } catch (error) {
  47. console.log('String could not be sanitized', unsanitizedString);
  48. return unsanitizedString;
  49. }
  50. }