From a20ff4a09ae5f349df1b19fea92b1c93e122c6d4 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 14 Mar 2025 10:02:47 +0100 Subject: [PATCH 01/15] 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 02/15] 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 03/15] 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 04/15] 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 05/15] 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 06/15] 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: From 8df093056ff1c28f99258dc0fe103f4fe00558b9 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:50:47 +0200 Subject: [PATCH 07/15] Rephrase usage of topics in server-side search Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- content/client-server-api/modules/search.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/content/client-server-api/modules/search.md b/content/client-server-api/modules/search.md index 591e871c..5805b37e 100644 --- a/content/client-server-api/modules/search.md +++ b/content/client-server-api/modules/search.md @@ -28,8 +28,7 @@ The supported keys to search over are: - `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) +- In [`m.room.topic`](#mroomtopic), `content.topic` as well as the `body` of the `text/plain` representation in `content['m.topic']`. The search will *not* include rooms that are end to end encrypted. From 9a1495f86974b3fa1b1a7a9a232c36bd28ed5ce0 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:52:03 +0200 Subject: [PATCH 08/15] Update data/api/client-server/create_room.yaml --- 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 f0d8d7f6..c2a40809 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -111,7 +111,7 @@ paths: description: |- 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 + This overwrites any [`m.room.name`](/client-server-api/#mroomname) event in `initial_state`. topic: type: string From 22a8066ed2699485d74e71e95933b01e230c65aa Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:52:29 +0200 Subject: [PATCH 09/15] Update data/api/client-server/create_room.yaml --- data/api/client-server/create_room.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/api/client-server/create_room.yaml b/data/api/client-server/create_room.yaml index c2a40809..eac25577 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -111,8 +111,8 @@ paths: description: |- 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`](/client-server-api/#mroomname) event in - `initial_state`. + This overwrites any [`m.room.name`](/client-server-api/#mroomname) + event in `initial_state`. topic: type: string description: |- From 51a4bbc1d989ac412aed14239e331a9d5c85979a Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:53:36 +0200 Subject: [PATCH 10/15] Update data/api/client-server/create_room.yaml --- data/api/client-server/create_room.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/data/api/client-server/create_room.yaml b/data/api/client-server/create_room.yaml index eac25577..91c85840 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -116,10 +116,10 @@ paths: topic: 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 - indicate the topic for the room. This overwrites any - [`m.room.topic`](#mroomtopic) event in `initial_state`. + If this is included, an [`m.room.topic`](/client-server-api/#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`](/client-server-api/#mroomtopic) event in `initial_state`. invite: type: array description: |- From 39edd640342a3e231908c3f4737628b4b4f9a194 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:54:32 +0200 Subject: [PATCH 11/15] Update data/event-schemas/schema/components/m_text_content_block.yaml --- .../event-schemas/schema/components/m_text_content_block.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/event-schemas/schema/components/m_text_content_block.yaml b/data/event-schemas/schema/components/m_text_content_block.yaml index d64c065d..29c8d148 100644 --- a/data/event-schemas/schema/components/m_text_content_block.yaml +++ b/data/event-schemas/schema/components/m_text_content_block.yaml @@ -22,7 +22,7 @@ items: 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). + for rich content associated with [`msgtype`](/client-server-api/#mroommessage-msgtypes) + of [`m.room.message`](/client-server-api/#mroommessage). required: - body From a3f40730eda6d19369e27ccff980ec8fc3ffe454 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:55:05 +0200 Subject: [PATCH 12/15] Update data/api/client-server/create_room.yaml Co-authored-by: Richard van der Hoff <1389908+richvdh@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 91c85840..03a85443 100644 --- a/data/api/client-server/create_room.yaml +++ b/data/api/client-server/create_room.yaml @@ -109,7 +109,7 @@ paths: name: type: string description: |- - If this is included, an [`m.room.name`](#mroomname) event + If this is included, an [`m.room.name`](/client-server-api/#mroomname) event will be sent into the room to indicate the name for the room. This overwrites any [`m.room.name`](/client-server-api/#mroomname) event in `initial_state`. From e9e937ca566b71eeb58f2f19f4c6c0e52f314743 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:56:00 +0200 Subject: [PATCH 13/15] Update content/client-server-api/modules/search.md --- content/client-server-api/modules/search.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/content/client-server-api/modules/search.md b/content/client-server-api/modules/search.md index 5805b37e..c009fa0e 100644 --- a/content/client-server-api/modules/search.md +++ b/content/client-server-api/modules/search.md @@ -28,7 +28,8 @@ The supported keys to search over are: - `content.body` in [`m.room.message`](#mroommessage) - `content.name` in [`m.room.name`](#mroomname) -- In [`m.room.topic`](#mroomtopic), `content.topic` as well as the `body` of the `text/plain` representation in `content['m.topic']`. +- In [`m.room.topic`](/client-server-api/#mroomtopic), `content.topic` + as well as the `body` of the `text/plain` representation in `content['m.topic']`. The search will *not* include rooms that are end to end encrypted. From 469f32821c27dea40ca789d6826c24cef1d5bf50 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:56:29 +0200 Subject: [PATCH 14/15] Update content/client-server-api/modules/search.md --- content/client-server-api/modules/search.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/search.md b/content/client-server-api/modules/search.md index c009fa0e..2705aa66 100644 --- a/content/client-server-api/modules/search.md +++ b/content/client-server-api/modules/search.md @@ -26,8 +26,8 @@ on certain keys of certain event types. The supported keys to search over are: -- `content.body` in [`m.room.message`](#mroommessage) -- `content.name` in [`m.room.name`](#mroomname) +- `content.body` in [`m.room.message`](/client-server-api/#mroommessage) +- `content.name` in [`m.room.name`](/client-server-api/#mroomname) - In [`m.room.topic`](/client-server-api/#mroomtopic), `content.topic` as well as the `body` of the `text/plain` representation in `content['m.topic']`. From 3dd4b40aedd82e0c818c4688b1de14a3746e69d5 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Wed, 30 Apr 2025 08:57:11 +0200 Subject: [PATCH 15/15] Update data/api/client-server/definitions/public_rooms_chunk.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/definitions/public_rooms_chunk.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/api/client-server/definitions/public_rooms_chunk.yaml b/data/api/client-server/definitions/public_rooms_chunk.yaml index 02334d14..64786432 100644 --- a/data/api/client-server/definitions/public_rooms_chunk.yaml +++ b/data/api/client-server/definitions/public_rooms_chunk.yaml @@ -34,7 +34,7 @@ properties: topic: type: string description: |- - The plaintext topic of the room. Omitted if no `text/plain` mimetype + The plain text 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: