Refactor how message content highlighting works + change to safe HTML rendering component. Closes #2669

This commit is contained in:
Gabe Kangas
2023-02-04 17:21:06 -08:00
parent 388e4d3d78
commit e6d3da4f9c
7 changed files with 148 additions and 67 deletions

View File

@@ -1,38 +1,8 @@
import { convertToText } from '../chat';
import { getDiffInDaysFromNow } from '../../../utils/helpers';
const stripTags = (str: string) => str && str.replace(/<\/?[^>]+(>|$)/g, '');
const convertToMarkup = (str = '') => convertToText(str).replace(/\n/g, '<p></p>');
function getInstagramEmbedFromURL(url: string) {
const urlObject = new URL(url.replace(/\/$/, ''));
urlObject.pathname += '/embed';
return `<iframe class="chat-embed instagram-embed" src="${urlObject.href}" frameborder="0" allowfullscreen></iframe>`;
}
function isMessageJustAnchor(embedText: string, message: string, anchors: HTMLAnchorElement[]) {
if (embedText !== '' && anchors.length === 1) return false;
return stripTags(message) === stripTags(anchors[0]?.innerHTML);
}
function getMessageWithEmbeds(message: string) {
let embedText = '';
// Make a temporary element so we can actually parse the html and pull anchor tags from it.
// This is a better approach than regex.
const container = document.createElement('p');
container.innerHTML = message;
const anchors = Array.from(container.querySelectorAll('a'));
anchors.forEach(({ href }) => {
if (href.includes('instagram.com/p/')) embedText += getInstagramEmbedFromURL(href);
});
// If this message only consists of a single embeddable link
// then only return the embed and strip the link url from the text.
if (isMessageJustAnchor(embedText, message, anchors)) return embedText;
return message + embedText;
}
export function formatTimestamp(sentAt: Date) {
const now = new Date(sentAt);
if (Number.isNaN(now)) return '';
@@ -56,8 +26,6 @@ export function formatTimestamp(sentAt: Date) {
*/
export function formatMessageText(message: string) {
let formattedText = getMessageWithEmbeds(message);
formattedText = convertToMarkup(formattedText);
const formattedText = convertToMarkup(message);
return formattedText;
// return await highlightUsername(formattedText, username);
}