matrix-doc/drafts/m-room-message-html.rst

90 lines
3.8 KiB
ReStructuredText

Abstract
========
Matrix does not define how to send rich text messages. This proposal defines a
format for ``m.room.message`` which allows it to send rich text messages.
This proposal is not designed to replace the existing system for sending images,
audio, files, etc though there is some overlap which would allow it to do so.
Current State
=============
The current unofficial way to send HTML messages uses the format::
"type": "m.room.message",
"content": {
"body": "[matrix-org/matrix-ios-sdk] giomfo pushed to master: Handle new events notification - https://github.com/matrix-org/matrix-ios-sdk/commit/c21e91a3",
"format": "org.matrix.custom.html",
"formatted_body": "[matrix-org/matrix-ios-sdk] giomfo pushed to <b>master</b>: Handle new events notification - https://github.com/matrix-org/matrix-ios-sdk/commit/c21e91a3",
"msgtype": "m.text"
}
This works but has several problems with it:
- It assumes the client can display HTML. If they cannot, there is no
alternative representation other than plain text.
- It doesn't provide support for textual representations of things which HTML
isn't great at (e.g. formatting for math equations).
- It doesn't account for HTML sanitizers very well. What you put in
``formatted_body`` may look *vastly different* depending on the strictness of
the HTML sanitizer used.
Proposal
========
A new ``msgtype`` to ``m.room.message`` is added: ``m.rich_text``. Messages with
this type MUST include an ``html`` key which is a string. Messages MAY include a
``formats`` key which is an array of objects. Each object in ``formats`` MUST
have a ``mimetype`` key whose value is a valid mimetype. Mimetypes which start
with ``text/`` MUST have a ``body`` key. Mimetypes which do not start
with ``text/`` can have type-specific keys. The ``formats`` array is ordered so
that the preferred format appears first and the least preferred format appears
last. Clients will loop through this array and display the first format they
recognise. The ``html`` key MUST have an HTML representation of the message as
the value.
Example::
content: {
msgtype: "m.rich_text",
formats: [
{
mimetype: "text/x-rst",
body: "A **big** :green:`green` boat"
},
{
mimetype: "text/markdown",
body: "A **big** green boat"
}
],
html: "A <b>big</b> <font color=\"green\">green</font> boat"
body: "A big green boat"
}
Rationale
=========
There are many different ways of marking up some text. Not all clients can use
the same representation when marking up. HTML was chosen as the fallback rich
text format because it is the most commonly supported markup language for
devices / languages. This means that many libraries already exist for
converting from HTML to some UI display. In addition, HTML is
one of the most expressive markup languages: allowing pixel-perfect layouts, a
wide range of styling options, etc. This means that information loss can be
minimised in this representation. If we do not specify ``html`` as a required
key (and instead rely on clients setting it as an object in ``formats``) we
cannot ensure the largest amount of clients seeing the most accurate form of the
message. This can fragment the UX depending on the client being used.
The ``formats`` array was chosen to allow senders to specify a variety of
alternative representations for the text in question. This may be preferable
if the client cannot (or is unwilling to) display untrusted HTML. An array was
chosen over say ``"mime/type": "text"`` mappings because the sender may wish to
have several alternative representations using the same mimetype. As the
elements in this array are ordered, subsequent elements are effectively the
"fallback" for the previous element.