From a20ff4a09ae5f349df1b19fea92b1c93e122c6d4 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 14 Mar 2025 10:02:47 +0100 Subject: [PATCH 1/6] MSC3765: Rich text in room topics Signed-off-by: Johannes Marbach --- content/client-server-api/modules/search.md | 7 +++-- data/api/client-server/create_room.yaml | 14 ++++++---- .../definitions/public_rooms_chunk.yaml | 4 ++- data/event-schemas/examples/m.room.topic.yaml | 10 ++++++- .../components/m_text_content_block.yaml | 28 +++++++++++++++++++ data/event-schemas/schema/m.room.topic.yaml | 24 ++++++++++++++-- 6 files changed, 74 insertions(+), 13 deletions(-) create mode 100644 data/event-schemas/schema/components/m_text_content_block.yaml diff --git a/content/client-server-api/modules/search.md b/content/client-server-api/modules/search.md index 8115d5be..591e871c 100644 --- a/content/client-server-api/modules/search.md +++ b/content/client-server-api/modules/search.md @@ -26,9 +26,10 @@ on certain keys of certain event types. The supported keys to search over are: -- `content.body` in `m.room.message` -- `content.name` in `m.room.name` -- `content.topic` in `m.room.topic` +- `content.body` in [`m.room.message`](#mroommessage) +- `content.name` in [`m.room.name`](#mroomname) +- `content.topic` as well as the `body` of the `text/plain` representation + in [`m.room.topic`](#mroomtopic) The search will *not* include rooms that are end to end encrypted. diff --git a/data/api/client-server/create_room.yaml b/data/api/client-server/create_room.yaml index 3992fdfe..8fa022b2 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -109,15 +109,17 @@ paths: name: type: string description: |- - If this is included, an `m.room.name` event will be sent - into the room to indicate the name of the room. See Room - Events for more information on `m.room.name`. + If this is included, an [`m.room.name`](#mroomname) event + will be sent into the room to indicate the name for the room. + This overwrites any [`m.room.name`](#mroomname) event in + `initial_state`. topic: type: string description: |- - If this is included, an `m.room.topic` event will be sent - into the room to indicate the topic for the room. See Room - Events for more information on `m.room.topic`. + If this is included, an [`m.room.topic`](#mroomtopic) event + with a `text/plain` mimetype will be sent into the room to + indicate the topic for the room. This overwrites any + [`m.room.topic`](#mroomtopic) event in `initial_state`. invite: type: array description: |- diff --git a/data/api/client-server/definitions/public_rooms_chunk.yaml b/data/api/client-server/definitions/public_rooms_chunk.yaml index 9c6ae6fc..02334d14 100644 --- a/data/api/client-server/definitions/public_rooms_chunk.yaml +++ b/data/api/client-server/definitions/public_rooms_chunk.yaml @@ -33,7 +33,9 @@ properties: example: "!abcdefg:example.org" topic: type: string - description: The topic of the room, if any. + description: |- + The plaintext topic of the room. Omitted if no `text/plain` mimetype + exists in [`m.room.topic`](/client-server-api/#mroomtopic). example: "All things general" world_readable: type: boolean diff --git a/data/event-schemas/examples/m.room.topic.yaml b/data/event-schemas/examples/m.room.topic.yaml index 69e5d4f1..f673e00c 100644 --- a/data/event-schemas/examples/m.room.topic.yaml +++ b/data/event-schemas/examples/m.room.topic.yaml @@ -3,6 +3,14 @@ "type": "m.room.topic", "state_key": "", "content": { - "topic": "A room topic" + "m.topic": { + "m.text": [ { + "mimetype": "text/html", + "body": "An html topic" + }, { + "body": "A plain text topic" + }] + }, + "topic": "A plain text topic" } } diff --git a/data/event-schemas/schema/components/m_text_content_block.yaml b/data/event-schemas/schema/components/m_text_content_block.yaml new file mode 100644 index 00000000..d64c065d --- /dev/null +++ b/data/event-schemas/schema/components/m_text_content_block.yaml @@ -0,0 +1,28 @@ +type: array +description: |- + An ordered array of textual representations in different mimetypes. + + Senders SHOULD specify at least one representation and SHOULD always + include a plaintext representation. + + Receivers SHOULD use the first representation in the array that + they understand. +title: TextContentBlock +items: + type: object + title: TextualRepresentation + properties: + mimetype: + type: string + description: The mimetype. Defaults to `text/plain` if omitted. + example: "text/html" + body: + type: string + description: |- + The string content. + + Clients SHOULD validate and sanitize the content as they do + for rich content associated with [`msgtype`](#mroommessage-msgtypes) + of [`m.room.message`](#mroommessage). + required: + - body diff --git a/data/event-schemas/schema/m.room.topic.yaml b/data/event-schemas/schema/m.room.topic.yaml index 78a3d878..4b4c5000 100644 --- a/data/event-schemas/schema/m.room.topic.yaml +++ b/data/event-schemas/schema/m.room.topic.yaml @@ -1,13 +1,33 @@ --- allOf: - $ref: core-event-schema/state_event.yaml -description: 'A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using `/createRoom` with the `topic` key.' +description: |- + A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using `/createRoom` with the `topic` key. + + In order to prevent formatting abuse in room topics, clients SHOULD + limit the length of topics during both entry and display, for instance, + by capping the number of displayed lines. Additionally, clients SHOULD + ignore things like headings and enumerations (or format them as regular + text). properties: content: properties: topic: - description: The topic text. + description: |- + The topic in plain text. + + This SHOULD duplicate the content of the `text/plain` + representation in `m.topic` if any exists. type: string + m.topic: + type: object + title: TopicContentBlock + x-addedInMatrixVersion: "1.14" + description: |- + Textual representation of the room topic in different mimetypes. + properties: + m.text: + $ref: components/m_text_content_block.yaml required: - topic type: object From 743a035335e7ed6e1ed431a4d42be5559b9fa328 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 14 Mar 2025 10:09:24 +0100 Subject: [PATCH 2/6] Add changelog --- changelogs/client_server/newsfragments/2095.feature | 1 + changelogs/server_server/newsfragments/2095.feature | 1 + 2 files changed, 2 insertions(+) create mode 100644 changelogs/client_server/newsfragments/2095.feature create mode 100644 changelogs/server_server/newsfragments/2095.feature diff --git a/changelogs/client_server/newsfragments/2095.feature b/changelogs/client_server/newsfragments/2095.feature new file mode 100644 index 00000000..0a993bbb --- /dev/null +++ b/changelogs/client_server/newsfragments/2095.feature @@ -0,0 +1 @@ +Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). diff --git a/changelogs/server_server/newsfragments/2095.feature b/changelogs/server_server/newsfragments/2095.feature new file mode 100644 index 00000000..0a993bbb --- /dev/null +++ b/changelogs/server_server/newsfragments/2095.feature @@ -0,0 +1 @@ +Add `m.topic` content block to enable rich text in `m.room.topic` events as per [MSC3765](https://github.com/matrix-org/matrix-spec-proposals/pull/3765). From 9ca647f5ee9363c073ebd6e0496276207ebeca6d Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Thu, 20 Mar 2025 10:20:06 +0100 Subject: [PATCH 3/6] Update data/api/client-server/create_room.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Kévin Commaille <76261501+zecakeh@users.noreply.github.com> --- data/api/client-server/create_room.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/api/client-server/create_room.yaml b/data/api/client-server/create_room.yaml index 8fa022b2..f0d8d7f6 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -117,7 +117,7 @@ paths: type: string description: |- If this is included, an [`m.room.topic`](#mroomtopic) event - with a `text/plain` mimetype will be sent into the room to + with a `text/plain` mimetype will be sent into the room to indicate the topic for the room. This overwrites any [`m.room.topic`](#mroomtopic) event in `initial_state`. invite: From 43f8f6840292b2b64bf563ba36ce154ea2499b2f Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Thu, 20 Mar 2025 10:29:26 +0100 Subject: [PATCH 4/6] Don't use semantically different texts for different mimetypes in the topic example --- data/event-schemas/examples/m.room.topic.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/data/event-schemas/examples/m.room.topic.yaml b/data/event-schemas/examples/m.room.topic.yaml index f673e00c..993145a6 100644 --- a/data/event-schemas/examples/m.room.topic.yaml +++ b/data/event-schemas/examples/m.room.topic.yaml @@ -6,11 +6,11 @@ "m.topic": { "m.text": [ { "mimetype": "text/html", - "body": "An html topic" + "body": "An interesting room topic" }, { - "body": "A plain text topic" + "body": "An interesting room topic" }] }, - "topic": "A plain text topic" + "topic": "An interesting room topic" } } From d060142a8df05bae77786e61c7f9bde76b0e5e19 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Thu, 20 Mar 2025 10:36:27 +0100 Subject: [PATCH 5/6] Line-wrap first paragraph, update link and parameters --- data/event-schemas/schema/m.room.topic.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/data/event-schemas/schema/m.room.topic.yaml b/data/event-schemas/schema/m.room.topic.yaml index 4b4c5000..c37ecf03 100644 --- a/data/event-schemas/schema/m.room.topic.yaml +++ b/data/event-schemas/schema/m.room.topic.yaml @@ -2,7 +2,12 @@ allOf: - $ref: core-event-schema/state_event.yaml description: |- - A topic is a short message detailing what is currently being discussed in the room. It can also be used as a way to display extra information about the room, which may not be suitable for the room name. The room topic can also be set when creating a room using `/createRoom` with the `topic` key. + A topic is a short message detailing what is currently being discussed + in the room. It can also be used as a way to display extra information + about the room, which may not be suitable for the room name. The room + topic can be set when creating a room using + [`/createRoom`](client-server-api/#post_matrixclientv3createroom), either + with the `topic` key or by specifying a full event in `initial_state`. In order to prevent formatting abuse in room topics, clients SHOULD limit the length of topics during both entry and display, for instance, From 7f0431b95fccb4760f1af9c52dd133c749180380 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 28 Mar 2025 13:34:29 +0100 Subject: [PATCH 6/6] Bump version to 1.15 --- data/event-schemas/schema/m.room.topic.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/event-schemas/schema/m.room.topic.yaml b/data/event-schemas/schema/m.room.topic.yaml index c37ecf03..41588f5b 100644 --- a/data/event-schemas/schema/m.room.topic.yaml +++ b/data/event-schemas/schema/m.room.topic.yaml @@ -27,7 +27,7 @@ properties: m.topic: type: object title: TopicContentBlock - x-addedInMatrixVersion: "1.14" + x-addedInMatrixVersion: "1.15" description: |- Textual representation of the room topic in different mimetypes. properties: