fediverse/fep
37
268
Fork
You've already forked fep
100

Proposed updates for FEP 9098 #657

Open
nikclayton wants to merge 1 commit from nikclayton/fep:fep-9098 into main
pull from: nikclayton/fep:fep-9098
merge into: fediverse:main
fediverse:main
fediverse:pages
Contributor
Copy link

Per my comment in the thread at https://socialhub.activitypub.rocks/t/fep-9098-custom-emojis/5408/5, this is some proposed changes to clarify the FEP and make some things more concrete for implementers.

It's entirely possible there are some mistakes in the new content if I've misunderstood something. Hopefully this provides a good opportunity to both clear up those misunderstandings, and provide clarity for future readers who may make the same mistakes.

Per my comment in the thread at https://socialhub.activitypub.rocks/t/fep-9098-custom-emojis/5408/5, this is some proposed changes to clarify the FEP and make some things more concrete for implementers. It's entirely possible there are some mistakes in the new content if I've misunderstood something. Hopefully this provides a good opportunity to both clear up those misunderstandings, and provide clarity for future readers who may make the same mistakes.
It's entirely possible there are some mistakes in the new content if I've misunderstood something. Hopefully this provides a good opportunity to both clear up those misunderstandings, and provide clarity for future readers who may make the same mistakes.
@ -37,0 +36,4 @@
| *updated* | OPTIONAL | [updated](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-updated) | |
| *icon* | REQUIRED | [Image](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-image) | *Note*: Despite the property name this is an **Image**, not an **Icon**. |
| *icon.type* | REQUIRED | [type](https://www.w3.org/TR/activitystreams-vocabulary/#dfn-type) | The literal string `Image`. |
| *icon.url* | REQUIRED | ``xsd:anyURI`` | The URL of the image to use as the emoji. |
Author
Contributor
Copy link

I thought that linking to the specific types here was useful, to make it easier for the reader to click through and see any specific constraints on the types.

I thought that linking to the specific types here was useful, to make it easier for the reader to click through and see any specific constraints on the types.
@ -80,1 +74,3 @@
Custom emojis can be inserted into textual representations of an object using [shortcodes][Shortcode] (shortcode is a name of an emoji enclosed in colons: `:emojiname:`). These textual representations are often specified with `name`, `summary` and `content` properties.
#### Representation
In text a custom emoji is represented by its *shortcode*, a literal colon (`:`), some number of characters, and another literal colon. E.g., `:blobcat:`.
Author
Contributor
Copy link

Best as I can tell, when talking about custom emojis the term shortcode should always refer to the text including the colons, i.e., the shortcode is :blobcat:, not blobcat.

Best as I can tell, when talking about custom emojis the term *shortcode* should always refer to the text **including** the colons, i.e., the shortcode is `:blobcat:`, not `blobcat`.
@ -104,2 +158,4 @@
### Rendering
#### General client considerations
Author
Contributor
Copy link

I've split this in to general client considerations and considerations that are specific to the web.

I appreciate there's an argument to be made that if this is strictly about ActivityPub, and most clients / user agents aren't using AP but they're using e.g., the Mastodon client API, this doesn't belong here. But I don't know of a better place to put it, and since the original document had a section for client concerns I thought it was worthwhile to expand.

I've split this in to general client considerations and considerations that are specific to the web. I appreciate there's an argument to be made that if this is strictly about ActivityPub, and most clients / user agents aren't using AP but they're using e.g., the Mastodon client API, this doesn't belong here. But I don't know of a better place to put it, and since the original document had a section for client concerns I thought it was worthwhile to expand.
@ -118,0 +195,4 @@
In order to be compatible with as many servers as possible implementations SHOULD comply with the following additional requirements:
- `name` property matches the regular expression `^:[a-zA-Z0-9_]{2,}:$` ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L30)).
Author
Contributor
Copy link

This was originally two points, but you can shrink it to one, as done here, by including the {2,} in the regex to make it clear there must be at least two characters within the : of the shortcode.

This was originally two points, but you can shrink it to one, as done here, by including the `{2,}` in the regex to make it clear there must be at least two characters within the `:` of the shortcode.
@ -118,0 +198,4 @@
- `name` property matches the regular expression `^:[a-zA-Z0-9_]{2,}:$` ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L30)).
- Image media type is `image/png`, `image/gif` or `image/webp` ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L37)).
- Image size is not greater than 256 KB ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L27)).
- Within a repeated run of emojis (e.g., `:blobcat: :blobcat: :blobcat:`) each shortcode SHOULD be separated by at least one character that is not in the case-insensitive set `a-z0-9:` ([Mastodon](https://github.com/mastodon/mastodon/blob/6f16011c5a46bfa131cc1d6be89347dcff1b0fc1/app/models/custom_emoji.rb#L32)). For example:
Author
Contributor
Copy link

This is new, and based on the Mastodon behaviour. I don't know what other servers do, but maybe it's worth explicitly looping in different server authors to get their feedback here.

This is the sort of thing that could cause real interoperability problems if it's not nailed down, and I suspect different servers do behave differently.

For example, hachyderm.io has a collection of emojis that are designed to be placed next to one another to draw a l-o-o-o-o-o-o-o-ng cat. The effect is greatly diminished if you need to have a space between each emoji.

This is new, and based on the Mastodon behaviour. I don't know what other servers do, but maybe it's worth explicitly looping in different server authors to get their feedback here. This is the sort of thing that could cause real interoperability problems if it's not nailed down, and I suspect different servers do behave differently. For example, hachyderm.io has a collection of emojis that are designed to be placed next to one another to draw a l-o-o-o-o-o-o-o-ng cat. The effect is greatly diminished if you need to have a space between each emoji.
nikclayton changed title from (削除) wip: Proposed updates for FEP 9098 (削除ここまで) to Proposed updates for FEP 9098 2025年07月18日 22:00:37 +02:00
silverpill referenced this pull request from a commit 2025年08月03日 00:32:54 +02:00
silverpill referenced this pull request from a commit 2025年08月03日 00:37:22 +02:00
silverpill referenced this pull request from a commit 2025年08月03日 00:42:13 +02:00
@ -104,0 +106,4 @@
#### Right-to-left text
Custom emoji shortcodes are always written left-to-right, even in right-to-left text.

Could you provide an example of an RTL post containing custom emojis?

Could you provide an example of an RTL post containing custom emojis?
Author
Contributor
Copy link
https://tooot.im/@admin/112551593711979761
@ -106,1 +181,4 @@
#### Web client considerations
Applications typically replace custom emoji shortcodes with `<img>` HTML tags and render the output as HTML.

How non-web (e.g. mobile) clients render custom emojis?

How non-web (e.g. mobile) clients render custom emojis?
Author
Contributor
Copy link

Depends on the client. Pachli (simplified):

  • Loads the remote image defined by the emoji
  • Determines the height of the text it will appear in.
  • If the emoji fits within that height it is left unchanged, otherwise it is scaled (preserving aspect ratio) to fit within the available height
  • Draws the emoji at the apropriate point, and advances the point where the next text will be inserted to the end of the emoji
Depends on the client. Pachli (simplified): - Loads the remote image defined by the emoji - Determines the height of the text it will appear in. - If the emoji fits within that height it is left unchanged, otherwise it is scaled (preserving aspect ratio) to fit within the available height - Draws the emoji at the apropriate point, and advances the point where the next text will be inserted to the end of the emoji

Interesting. So the post content is rendered as HTML, and then custom emojis are layered on top of it?
Or you just render post content as plain text?

Interesting. So the post content is rendered as HTML, and then custom emojis are layered on top of it? Or you just render post content as plain text?
@ -118,0 +200,4 @@
- Image size is not greater than 256 KB ([Mastodon](https://github.com/mastodon/mastodon/blob/v4.3.7/app/models/custom_emoji.rb#L27)).
- Within a repeated run of emojis (e.g., `:blobcat: :blobcat: :blobcat:`) each shortcode SHOULD be separated by at least one character that is not in the case-insensitive set `a-z0-9:` ([Mastodon](https://github.com/mastodon/mastodon/blob/6f16011c5a46bfa131cc1d6be89347dcff1b0fc1/app/models/custom_emoji.rb#L32)). For example:
- `:blobcat: :blobcat:` renders as two distinct custom emoji, there is a space separating them.
- `:blobcat::blobcat:` renders as the literal text, as there is no space separating them.

I can't reproduce this. The Mastodon instance where I perform interop tests displays series of custom emojis even if they are without spaces. It is not up to date, though.

I can't reproduce this. The Mastodon instance where I perform interop tests displays series of custom emojis even if they are without spaces. It is not up to date, though.
Author
Contributor
Copy link

As far as I can tell this depends on whether or not the same emoji has been used "standalone" in the same post (mastodon.social, v4.5.0-nightly.2025年07月31日).

Here's one that uses :blobcat: on its own and as :blobcat::blobcat: -- as you can see, it works.

image

Here's one that uses :blobcat::blobcat::

image

As I note in the text, the two emojis have to be separated by something that isn't valid in the text part of an emoji shortcode. That could be a space, but e.g., a _ also works, as this example shows.

image

This has been a bug in Mastodon since at least 2018 (https://github.com/mastodon/mastodon/issues/7364).

As far as I can tell this depends on whether or not the same emoji has been used "standalone" in the same post (mastodon.social, v4.5.0-nightly.2025年07月31日). Here's one that uses `:blobcat:` on its own and as `:blobcat::blobcat:` -- as you can see, it works. ![image](/attachments/ed2f2460-4c6b-468f-9d61-521b49928eb1) Here's one that uses `:blobcat::blobcat:`: ![image](/attachments/d4c1dc8a-bd87-4659-8445-32d3dd3ad924) As I note in the text, the two emojis have to be separated by something that isn't valid in the text part of an emoji shortcode. That could be a space, but e.g., a `_` also works, as this example shows. ![image](/attachments/288d3f49-5cde-47d1-958f-32474fb3445e) This has been a bug in Mastodon since at least 2018 (https://github.com/mastodon/mastodon/issues/7364).

Thanks, I was able to reproduce this problem.

Thanks, I was able to reproduce this problem.
@ -118,0 +210,4 @@
- Some implementations omit the `id` property, instead of setting it to `null`.
- The `name` property is `Emoji` and not `CustomEmoji`.
- The `icon` property is an `Image`, not an `Icon`.

There is no Icon type, the range of icon property is Image | Link: https://www.w3.org/TR/activitystreams-vocabulary/#dfn-icon

There is no `Icon` type, the range of `icon` property is `Image | Link`: https://www.w3.org/TR/activitystreams-vocabulary/#dfn-icon

Okay, I copied another batch of suggestions to #661 and merged it.

As I mentioned in SocialHub thread, the accessibility bits and examples will be added later. I also don't want to change the order of sections at the moment.

If you want to suggest other changes, please rebase or open a new PR.

Okay, I copied another batch of suggestions to https://codeberg.org/fediverse/fep/pulls/661 and merged it. As I mentioned in SocialHub thread, the accessibility bits and examples will be added later. I also don't want to change the order of sections at the moment. If you want to suggest other changes, please rebase or open a new PR.
All checks were successful
ci/woodpecker/pr/test Pipeline was successful
This pull request has changes conflicting with the target branch.
  • fep/9098/fep-9098.md
View command line instructions

Manual merge helper

Use this merge commit message when completing the merge manually.

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u fep-9098:nikclayton-fep-9098
git switch nikclayton-fep-9098

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff nikclayton-fep-9098
git switch nikclayton-fep-9098
git rebase main
git switch main
git merge --ff-only nikclayton-fep-9098
git switch nikclayton-fep-9098
git rebase main
git switch main
git merge --no-ff nikclayton-fep-9098
git switch main
git merge --squash nikclayton-fep-9098
git switch main
git merge --ff-only nikclayton-fep-9098
git switch main
git merge nikclayton-fep-9098
git push origin main
Sign in to join this conversation.
No reviewers
Milestone
Clear milestone
No items
No milestone
Projects
Clear projects
No items
No project
Assignees
Clear assignees
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
fediverse/fep!657
Reference in a new issue
fediverse/fep
No description provided.
Delete branch "nikclayton/fep:fep-9098"

Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?