From 0ff52b71f2c0e970b1f0d43793c019bbed93e112 Mon Sep 17 00:00:00 2001 From: tobi <31960611+tsmethurst@users.noreply.github.com> Date: Wed, 27 Dec 2023 11:23:52 +0100 Subject: [chore] Refactor HTML templates and CSS (#2480) * [chore] Refactor HTML templates and CSS * eslint * ignore "Local" * rss tests * fiddle with OG just a tiny bit * dick around with polls a bit more so SR stops saying "clickable" * remove break * oh lord * don't lazy load avatar * fix ogmeta tests * clean up some cruft * catch remaining calls to c.HTML * fix error rendering + stack overflow in tag * allow templating attributes * fix indent * set aria-hidden on status complementary content, since it's already present in the label anyway * tidy up templating calls a little * try to make styling a bit more consistent + readable * fix up some remaining CSS issues * fix up reports --- internal/text/emojify.go | 91 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 71 insertions(+), 20 deletions(-) (limited to 'internal/text/emojify.go') diff --git a/internal/text/emojify.go b/internal/text/emojify.go index 2100d5e81..23730eaf9 100644 --- a/internal/text/emojify.go +++ b/internal/text/emojify.go @@ -20,18 +20,76 @@ package text import ( "bytes" "html" + "html/template" apimodel "github.com/superseriousbusiness/gotosocial/internal/api/model" "github.com/superseriousbusiness/gotosocial/internal/regexes" ) -// Emojify replaces shortcodes in `inputText` with the emoji in `emojis`. -// -// Callers should ensure that inputText and resulting text are escaped -// appropriately depending on what they're used for. -func Emojify(emojis []apimodel.Emoji, inputText string) string { - emojisMap := make(map[string]apimodel.Emoji, len(emojis)) +// EmojifyWeb replaces emoji shortcodes like `:example:` in the given HTML +// fragment with `` tags suitable for rendering on the web frontend. +func EmojifyWeb(emojis []apimodel.Emoji, html template.HTML) template.HTML { + out := emojify( + emojis, + string(html), + func(url, code string, buf *bytes.Buffer) { + buf.WriteString(`:`)
+			buf.WriteString(code)
+			buf.WriteString(`:`) + }, + ) + + // If input was safe, + // we can trust output. + return template.HTML(out) // #nosec G203 +} +// EmojifyRSS replaces emoji shortcodes like `:example:` in the given text +// fragment with `` tags suitable for rendering as RSS content. +func EmojifyRSS(emojis []apimodel.Emoji, text string) string { + return emojify( + emojis, + text, + func(url, code string, buf *bytes.Buffer) { + buf.WriteString(`:`)
+			buf.WriteString(code)
+			buf.WriteString(`:`) + }, + ) +} + +// Demojify replaces emoji shortcodes like `:example:` in the given text +// fragment with empty strings, essentially stripping them from the text. +// This is useful for text used in OG Meta headers. +func Demojify(text string) string { + return regexes.EmojiFinder.ReplaceAllString(text, "") +} + +func emojify( + emojis []apimodel.Emoji, + input string, + write func(url, code string, buf *bytes.Buffer), +) string { + // Build map of shortcodes. Normalize each + // shortcode by readding closing colons. + emojisMap := make(map[string]apimodel.Emoji, len(emojis)) for _, emoji := range emojis { shortcode := ":" + emoji.Shortcode + ":" emojisMap[shortcode] = emoji @@ -39,27 +97,20 @@ func Emojify(emojis []apimodel.Emoji, inputText string) string { return regexes.ReplaceAllStringFunc( regexes.EmojiFinder, - inputText, + input, func(shortcode string, buf *bytes.Buffer) string { - // Look for emoji according to this shortcode + // Look for emoji with this shortcode. emoji, ok := emojisMap[shortcode] if !ok { return shortcode } - // Escape raw emoji content - safeURL := html.EscapeString(emoji.URL) - safeCode := html.EscapeString(emoji.Shortcode) - - // Write HTML emoji repr to buffer - buf.WriteString(`:`)
-			buf.WriteString(safeCode)
-			buf.WriteString(`:`) + // Escape raw emoji content. + url := html.EscapeString(emoji.URL) + code := html.EscapeString(emoji.Shortcode) + // Write emoji repr to buffer. + write(url, code, buf) return buf.String() }, ) -- cgit v1.2.3