mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-29 04:22:24 -05:00
[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
This commit is contained in:
parent
97a1fd9a29
commit
0ff52b71f2
77 changed files with 3262 additions and 1736 deletions
|
|
@ -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 `<img>` 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(`<img src="`)
|
||||
buf.WriteString(url)
|
||||
buf.WriteString(`" title=":`)
|
||||
buf.WriteString(code)
|
||||
buf.WriteString(`:" alt=":`)
|
||||
buf.WriteString(code)
|
||||
buf.WriteString(`:" class="emoji" `)
|
||||
// Lazy load emojis when
|
||||
// they scroll into view.
|
||||
buf.WriteString(`loading="lazy" `)
|
||||
// Limit size to avoid showing
|
||||
// huge emojis when unstyled.
|
||||
buf.WriteString(`width="25" height="25"/>`)
|
||||
},
|
||||
)
|
||||
|
||||
// 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 `<img>` 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(`<img src="`)
|
||||
buf.WriteString(url)
|
||||
buf.WriteString(`" title=":`)
|
||||
buf.WriteString(code)
|
||||
buf.WriteString(`:" alt=":`)
|
||||
buf.WriteString(code)
|
||||
buf.WriteString(`:" `)
|
||||
// Limit size to avoid showing
|
||||
// huge emojis in RSS readers.
|
||||
buf.WriteString(`width="25" height="25"/>`)
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// 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(`<img src="`)
|
||||
buf.WriteString(safeURL)
|
||||
buf.WriteString(`" title=":`)
|
||||
buf.WriteString(safeCode)
|
||||
buf.WriteString(`:" alt=":`)
|
||||
buf.WriteString(safeCode)
|
||||
buf.WriteString(`:" class="emoji"/>`)
|
||||
// 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()
|
||||
},
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue