RE: ...
const update = { $set: { quote } }; const parentItem = await collections.ap_timeline.findOne({ uid }); if (parentItem?.content?.html) { const cleaned = stripQuoteReferenceHtml(parentItem.content.html, quoteUrl); if (cleaned !== parentItem.content.html) { update.$set["content.html"] = cleaned; } } await collections.ap_timeline.updateOne({ uid }, update); } catch (error) { console.error(`[og-unfurl] Failed to fetch quote for ${uid}: ${error.message}`); } } /** * Strip the "RE: " paragraph that Mastodon adds for quoted posts. * Removeselements containing "RE:" followed by a link to the quote URL. * @param {string} html - Content HTML * @param {string} quoteUrl - URL of the quoted post * @returns {string} Cleaned HTML */ export function stripQuoteReferenceHtml(html, quoteUrl) { if (!html || !quoteUrl) return html; // Match
containing "RE:" and a link whose href contains the quote domain+path // Mastodon uses both /users/X/statuses/Y and /@X/Y URL formats try { const quoteUrlObj = new URL(quoteUrl); const quoteDomain = quoteUrlObj.hostname; // Escape special regex chars in domain const domainEscaped = quoteDomain.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // Match
RE: ...
(with optional whitespace) const re = new RegExp( `\\s*RE:\\s*]*href="[^"]*${domainEscaped}[^"]*"[^>]*>.*?\\s*
`, "i", ); return html.replace(re, "").trim(); } catch { return html; } }