Skip to content

Status HTML parsing - better emoji and mentions rendering

HJ requested to merge better-still-emoji into develop

This is WIP but I like this much more than previous attempt (replacing in runtime)

User-facing changes:

  • Adds new instance-default (pleroma default: false) setting to move mentions in the beginning of post into separate line
  • Posts from instances that don't put mentions in posts will have mentions in said separate line regardless of setting
  • Mentions now have user-highlights
  • Add new instance-default (pleroma default: false) setting to use new style of mentions that displays them as buttons instead of links which makes user-highlights more visible
  • Fixed #935 (closed), greentext now ignores <code> and <blockquote>. It actually now detects level properly (was broken)
  • Greentext now accompanied by cyantext (when line begins with <), uses blue color instead of cyan tho.
  • GIF Emoji now follow same suit as rest of GIF images - obeying the "play-on-hover GIFs" setting. Still no solution for APNGs tho.

Technical details

  • Refactors old tiny_html_processor
    • Now part of html_converter folder.
    • Now called html_line_converter - It converts HTML text into an array of "visual lines", as it did before.
    • No longer processes things as it goes, instead returns an array you can .map() over to process it.
  • Adds new html_tree_converter - It converts HTML text into a tree structure representing tags and text nodes, intended to be used in rendering process.
    • in addition, these new helper functions:
      • getTagName - relatively simple RegExp that extracts name from tag, i.e. <span class="bbbb"> -> span, updated version from tiny post html processor, TODO update original one to use this.
      • getAttrs - similar to previous one except it extracts attributes into a map, i.e. <a class="a" href="b"> -> { class: 'a', href: 'b' }
      • processTextForEmoji - optimized function allowing you to convert string with emoji to an array with chunks of string + whatever you want replacing the emoji.
  • Adds new RichContent component - the main star of the show. It's purpose is to enhance post body/emoji-containing HTML and give us control over it. Currently it does:
    • Collects and counts mentions and tags - all, in the beginning, in the end.
    • Change all mentions (detected via .mentions class) into MentionLink
    • If last line only contains mentions - wraps them in a
      • If there are no mentions in the beginning we consider it a hellthread-style and remove those last mentions.
    • Update all links to have `target="_blank"
    • Update all images to use StillImage component
    • Add emoji by replacing :shortcode: with StillImage component.
      • This finally relieves entity_normalizer from duty of adding emojis, now they are added at component level where they belong, not on data level.
      • For this purpose entity_normalizer now also returns raw_html
    • Emits parseReady event when it's done rendering, event contains information about first, last, all mentions and also tags. (used in StatusBody and Status)
    • Only used within Status component for user name display and for post subject and text
  • Adds new MentionLink component
    • Represents mention link
    • Uses button and opens profile on click, no need to catch clicks and prevent them.
    • Has option for new style where link looks more like a button
    • Adds a "tooltip" that contains full handle (also used for copying)
  • Adds new MentionsLine component
    • Limits the amount of mentions displayed, show the "+X more"
  • Adds new StatusBody component
    • Separates handling of post subject/text into a separate component.
      • Structure now is like this: Status -> StatusContent -> StatusBody
      • StatusBody is useful when you want to render post content but don't want to render attachments
      • Also does small improvements to how things are displayed (or not displayed) for future enhancements (compact notifications)
  • Improves Status component: (parts of what's described also implemented in StatusBody where applicable)
    • Adds new "show mentions on separate line" option. This removes mentions from post body and puts them on separate line (see below). This option is forcefully switched off in notifications since it's hard to tell whether post someone liked is an OP or a reply.
    • Moves "Replies" line at the very bottom, below the attachments:
    • Adds "Mentions" next to "Reply to"
      • When using "Show mentions on separate line" it shows all non-duplicate mentions (i.e. status.attentions) mentions
      • Otherwise it only shows mentions that weren't present in post body to begin with (i.e. coming from servers/clients that do not put mentions in post body)
    • When not using "Show mentions on separate line" it leaves mentions where they were in same order and amount (i.e. including duplicates) as they were and wraps them in a MentionsLine:

All of this is live on while i'm testing it

Curent bugs:

  • Some links don't open in _blank, should probably change target in processor instead of catching clicks like we do now
  • "Mentions" row has underline on hover and hand cursor even though it doesn't do anything
  • "Mentions" row is different than reply row in sttus popover
  • "Old place" mentions are somewhat forced, if post didn't have mentions in the beginning it will add them. Need to make html processor stateful and able to return more than just changed tree.
  • This post doesn't have proper spacing between tags for some reason. Probably reverse-processor trimming the strings when it shouldn't.


  • Clicking tags would open them on another instance, need to implement TagLink, most of the stuff for it is already there.
  • If post has an image with width=... height=... those would be ignored as StillImage doesn't understand them. Still, it's a rarity and can be fixed if we ever encounter it. Not like everyone is happy with our current article rendering.
  • Current "tooltip" implementation is very dumb and causes horizontal scroll in notifications column in some cases (chrome + autoscroll extension), worst case scenario we'll make it 0x0px so that it doesn't take space but you still can copy from it when selecting the mention.
Edited by HJ

Merge request reports