= persistentMapOf(),
+) : BlockNode
+
/**
* A preformatted code block (``). Rendered in a monospaced, horizontally
* scrollable container. The text is kept raw: no inline styling is applied inside it.
diff --git a/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContent.kt b/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContent.kt
index ecb13310be..a8daab7a90 100644
--- a/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContent.kt
+++ b/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContent.kt
@@ -62,6 +62,7 @@ import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.TextLayoutResult
+import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.buildAnnotatedString
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.rememberTextMeasurer
@@ -76,6 +77,7 @@ import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.htmlrenderer.api.BlockNode
import io.element.android.libraries.htmlrenderer.api.CodeBlockNode
import io.element.android.libraries.htmlrenderer.api.DocumentNode
+import io.element.android.libraries.htmlrenderer.api.HeaderNode
import io.element.android.libraries.htmlrenderer.api.HtmlMessageParser.Companion.INLINE_CODE_ANNOTATION_TAG
import io.element.android.libraries.htmlrenderer.api.HtmlMessageParser.Companion.LINK_ANNOTATION_TAG
import io.element.android.libraries.htmlrenderer.api.ListNode
@@ -158,6 +160,7 @@ internal fun BlockNode.lastBlockNode(): BlockNode? = when (this) {
is ListNode -> this
is QuoteNode -> this
is CodeBlockNode -> this
+ is HeaderNode -> this
}
@Composable
@@ -180,7 +183,7 @@ private fun BlockNodeView(
context: RenderContext,
modifier: Modifier = Modifier,
) {
- if (node === context.lastBlockNode && node !is ParagraphNode) {
+ if (node === context.lastBlockNode && node !is ParagraphNode && node !is HeaderNode) {
SideEffect { context.onContentLayoutChange(ContentAvoidingLayoutData.NotOverlapping) }
}
@@ -189,6 +192,7 @@ private fun BlockNodeView(
is ParagraphNode -> {
ParagraphView(node = node, context = context, modifier = modifier)
}
+ is HeaderNode -> HeaderView(node = node, context = context, modifier = modifier)
is CodeBlockNode -> CodeBlockView(node = node, modifier = modifier)
is QuoteNode -> QuoteView(node = node, context = context, modifier = modifier)
is ListNode -> ListView(node = node, context = context, modifier = modifier)
@@ -201,16 +205,6 @@ private fun ParagraphView(
context: RenderContext,
modifier: Modifier = Modifier,
) {
- val linkColor = ElementTheme.colors.textLinkExternal
- val codeBackgroundColor = ElementTheme.colors.bgSubtleSecondary
- val codeBorderColor = ElementTheme.colors.borderInteractiveSecondary
- val styledText = remember(node.text, linkColor) {
- node.text
- .linkify(SpanStyle(color = linkColor))
- .applyLinkStyles(linkColor = linkColor)
- }
- val inlineContent = rememberMentionInlineContent(node.inlineContent, context)
- val layoutResult = remember { mutableStateOf(null) }
// Only the last rendered paragraph (and only when not inside a code block / quote) reports its
// measured last line to the timeline.
val measureLastLine = if (node === context.lastBlockNode) {
@@ -218,21 +212,87 @@ private fun ParagraphView(
} else {
null
}
+ TextBlock(
+ text = node.text,
+ inlineContent = node.inlineContent,
+ textStyle = ElementTheme.typography.fontBodyMdRegular,
+ context = context,
+ modifier = modifier,
+ onTextLayout = { measureLastLine?.invoke(it) },
+ )
+}
+
+@Composable
+private fun HeaderView(
+ node: HeaderNode,
+ context: RenderContext,
+ modifier: Modifier = Modifier,
+) {
+ // Only the last rendered paragraph (and only when not inside a code block / quote) reports its
+ // measured last line to the timeline.
+ val measureLastLine = if (node === context.lastBlockNode) {
+ ContentAvoidingLayout.measureLastTextLine(onContentLayoutChange = context.onContentLayoutChange)
+ } else {
+ null
+ }
+ TextBlock(
+ text = node.text,
+ inlineContent = node.inlineContent,
+ textStyle = headerTextStyle(node.level),
+ context = context,
+ modifier = modifier,
+ onTextLayout = { measureLastLine?.invoke(it) }
+ )
+}
+
+/**
+ * Renders an inline-content block (a paragraph or a header) as a [Text] with [textStyle], applying
+ * link styling, the inline-code background boxes, mention/image inline content and link taps.
+ */
+@Composable
+private fun TextBlock(
+ text: AnnotatedString,
+ inlineContent: ImmutableMap,
+ textStyle: TextStyle,
+ context: RenderContext,
+ modifier: Modifier = Modifier,
+ onTextLayout: (TextLayoutResult) -> Unit = {},
+) {
+ val linkColor = ElementTheme.colors.textLinkExternal
+ val codeBackgroundColor = ElementTheme.colors.bgSubtleSecondary
+ val codeBorderColor = ElementTheme.colors.borderInteractiveSecondary
+ val styledText = remember(text, linkColor) {
+ text.linkify(SpanStyle(color = linkColor))
+ .applyLinkStyles(linkColor = linkColor)
+ }
+ val resolvedInlineContent = rememberMentionInlineContent(inlineContent, context)
+ val layoutResult = remember { mutableStateOf(null) }
Text(
text = styledText,
modifier = modifier
.drawInlineCodeBackgrounds(styledText, layoutResult, codeBackgroundColor, codeBorderColor, LocalDensity.current)
.linkTapHandler(styledText, layoutResult, context),
- style = ElementTheme.typography.fontBodyMdRegular,
+ style = textStyle,
color = ElementTheme.colors.textPrimary,
- inlineContent = inlineContent,
+ inlineContent = resolvedInlineContent,
onTextLayout = { result ->
layoutResult.value = result
- measureLastLine?.invoke(result)
+ onTextLayout(result)
},
)
}
+/** Maps an ``–`` [level] to a Compound typography style, largest first. */
+@Composable
+private fun headerTextStyle(level: Int): TextStyle = when (level) {
+ // For safety reasons, use the same style for H1 and H2, to avoid people using H1 for 'shouting' spam that fills the timeline with huge text
+ 1, 2 -> ElementTheme.typography.fontHeadingLgBold
+ 3 -> ElementTheme.typography.fontHeadingMdBold
+ 4 -> ElementTheme.typography.fontHeadingSmMedium
+ 5 -> ElementTheme.typography.fontBodyLgMedium
+ else -> ElementTheme.typography.fontBodyMdMedium
+}
+
@Composable
private fun CodeBlockView(
node: CodeBlockNode,
diff --git a/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContentPreview.kt b/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContentPreview.kt
index 47da9af3bb..4187acd070 100644
--- a/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContentPreview.kt
+++ b/libraries/htmlrenderer/api/src/main/kotlin/io/element/android/libraries/htmlrenderer/api/ui/HtmlMessageContentPreview.kt
@@ -26,6 +26,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.htmlrenderer.api.BlockNode
import io.element.android.libraries.htmlrenderer.api.CodeBlockNode
import io.element.android.libraries.htmlrenderer.api.DocumentNode
+import io.element.android.libraries.htmlrenderer.api.HeaderNode
import io.element.android.libraries.htmlrenderer.api.HtmlMessageParser.Companion.INLINE_CODE_ANNOTATION_TAG
import io.element.android.libraries.htmlrenderer.api.HtmlMessageParser.Companion.LINK_ANNOTATION_TAG
import io.element.android.libraries.htmlrenderer.api.ListItemNode
@@ -55,6 +56,7 @@ internal fun HtmlMessageContentPreview(
internal class HtmlMessageContentPreviewParam : PreviewParameterProvider {
override val values: Sequence
get() = sequenceOf(
+ headers(),
richParagraph(),
inlineCode(),
multilineInlineCode(),
@@ -237,6 +239,16 @@ internal class HtmlMessageContentPreviewParam : PreviewParameterProvider buildParagraph(element.childNodes())
TAG_PRE -> CodeBlockNode(code = element.wholeText().trimEnd('\n'))
TAG_BLOCKQUOTE -> QuoteNode(children = parseBlocks(element))
TAG_UL -> buildList(element, ordered = false)
TAG_OL -> buildList(element, ordered = true)
+ in HEADER_TAGS -> buildHeader(element, level = tag.removePrefix("h").toInt())
else -> null
}
@@ -102,6 +105,17 @@ class DefaultHtmlMessageParser(
/** Builds a [ParagraphNode] from a run of inline [nodes], or `null` if it holds no content. */
private fun buildParagraph(nodes: List): ParagraphNode? {
+ return buildInlineContent(nodes)?.let { ParagraphNode(text = it.text, inlineContent = it.inlineContent) }
+ }
+
+ /** Builds a [HeaderNode] of the given [level] from the inline content of [element], or `null` if empty. */
+ private fun buildHeader(element: Element, level: Int): HeaderNode? {
+ return buildInlineContent(element.childNodes())?.let {
+ HeaderNode(level = level, text = it.text, inlineContent = it.inlineContent)
+ }
+ }
+
+ private fun buildInlineContent(nodes: List): InlineContentBuilder.Result? {
val builder = InlineContentBuilder()
nodes.forEach { builder.append(it) }
return builder.build()
@@ -199,21 +213,29 @@ class DefaultHtmlMessageParser(
}
}
- fun build(): ParagraphNode? {
+ fun build(): Result? {
val text = builder.toAnnotatedString()
if (text.isBlank() && mentions.isEmpty()) return null
- return ParagraphNode(
+ return Result(
text = text,
inlineContent = mentions.toImmutableMap(),
)
}
+
+ /** The flattened inline content of a block: styled text plus its inline-content placeholders. */
+ inner class Result(
+ val text: AnnotatedString,
+ val inlineContent: ImmutableMap,
+ )
}
}
/** Tags that start a new block-level node. Anything else is treated as inline content. */
private fun Element.isBlockLevel(): Boolean = tagName() in BLOCK_TAGS
-private val BLOCK_TAGS = setOf(TAG_P, TAG_PRE, TAG_BLOCKQUOTE, TAG_UL, TAG_OL)
+private val HEADER_TAGS = setOf("h1", "h2", "h3", "h4", "h5", "h6")
+
+private val BLOCK_TAGS = setOf(TAG_P, TAG_PRE, TAG_BLOCKQUOTE, TAG_UL, TAG_OL) + HEADER_TAGS
private const val TAG_P = "p"
private const val TAG_PRE = "pre"
diff --git a/libraries/htmlrenderer/impl/src/test/kotlin/io/element/android/libraries/htmlrenderer/impl/DefaultHtmlMessageParserTest.kt b/libraries/htmlrenderer/impl/src/test/kotlin/io/element/android/libraries/htmlrenderer/impl/DefaultHtmlMessageParserTest.kt
index dd90d64279..4c746524c1 100644
--- a/libraries/htmlrenderer/impl/src/test/kotlin/io/element/android/libraries/htmlrenderer/impl/DefaultHtmlMessageParserTest.kt
+++ b/libraries/htmlrenderer/impl/src/test/kotlin/io/element/android/libraries/htmlrenderer/impl/DefaultHtmlMessageParserTest.kt
@@ -12,6 +12,7 @@ import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.font.FontWeight
import com.google.common.truth.Truth.assertThat
import io.element.android.libraries.htmlrenderer.api.CodeBlockNode
+import io.element.android.libraries.htmlrenderer.api.HeaderNode
import io.element.android.libraries.htmlrenderer.api.HtmlMessageParser
import io.element.android.libraries.htmlrenderer.api.ListNode
import io.element.android.libraries.htmlrenderer.api.MentionNodeContent
@@ -191,6 +192,24 @@ class DefaultHtmlMessageParserTest : RobolectricTest() {
assertThat(paragraph.text.text).isEqualTo("Actual message")
}
+ @Test
+ fun `headers become HeaderNodes with their level and inline content`() {
+ val document = parse("Title
Subtitle with bold
Small
")
+ assertThat(document.children).hasSize(3)
+
+ val h1 = document.children[0] as HeaderNode
+ assertThat(h1.level).isEqualTo(1)
+ assertThat(h1.text.text).isEqualTo("Title")
+
+ val h3 = document.children[1] as HeaderNode
+ assertThat(h3.level).isEqualTo(3)
+ assertThat(h3.text.text).isEqualTo("Subtitle with bold")
+
+ val h6 = document.children[2] as HeaderNode
+ assertThat(h6.level).isEqualTo(6)
+ assertThat(h6.text.text).isEqualTo("Small")
+ }
+
@Test
fun `blank input produces an empty document`() {
val document = parse(" ")
diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt
index 2f52320b0d..5cb3535b06 100644
--- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt
+++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/ToHtmlDocument.kt
@@ -89,6 +89,12 @@ private object CustomHtmlToDomParser {
"blockquote",
"p",
"br",
+ "h1",
+ "h2",
+ "h3",
+ "h4",
+ "h5",
+ "h6",
// Add custom `mx-reply` tag, even if it's just to remove its contents from the plain text version of the message
"mx-reply"
)
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_0_en.png
index b587d7bdbd..cee03b9170 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_0_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_0_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:24d689575196e5320e44cdf6882bcf7b4c696fa58d263af7b6864787dd606533
-size 7946
+oid sha256:6ae9a8d351b170dee11bbf0d674625570d66fc6da86f948330d23054c26c8c49
+size 23969
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_10_en.png
index 54a03450e2..61c461a1e9 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_10_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_10_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7a38304be44c5fcf2a9115acef98d71d8b9fe03dcbefb0cfa76546e39911ab8a
-size 21732
+oid sha256:780f661eca8275cc2fb70f7b504f8f95f79f387d6e72b2702cbb5da150c081a0
+size 8059
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_11_en.png
index 36fea9517e..54a03450e2 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_11_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_11_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:9cf8a07aeadd7d54bcdf3304d0bf1efe0a00c1964c02b0a24cd6d7718cc51d4b
-size 31085
+oid sha256:7a38304be44c5fcf2a9115acef98d71d8b9fe03dcbefb0cfa76546e39911ab8a
+size 21732
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_12_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_12_en.png
new file mode 100644
index 0000000000..36fea9517e
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_12_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9cf8a07aeadd7d54bcdf3304d0bf1efe0a00c1964c02b0a24cd6d7718cc51d4b
+size 31085
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_1_en.png
index 104effeaec..b587d7bdbd 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_1_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_1_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:18579f8262a4a55997ef8ab3e085ce7d32e97b454b999ea685656a9b67163f93
-size 9363
+oid sha256:24d689575196e5320e44cdf6882bcf7b4c696fa58d263af7b6864787dd606533
+size 7946
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_2_en.png
index 989ac136d6..104effeaec 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_2_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_2_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:7f6aa713c17f33c96e75b623daba8b45c29c147b46724b2fba4fa1fc662e1f95
-size 19547
+oid sha256:18579f8262a4a55997ef8ab3e085ce7d32e97b454b999ea685656a9b67163f93
+size 9363
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_3_en.png
index 5bdba00a36..989ac136d6 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_3_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_3_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:f2d495aa0a148d9e72d6bdf5f8a68d6934c44084e9669bac5e2ddde2d45d34c0
-size 8086
+oid sha256:7f6aa713c17f33c96e75b623daba8b45c29c147b46724b2fba4fa1fc662e1f95
+size 19547
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_4_en.png
index b97d04658b..5bdba00a36 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_4_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_4_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:b316c5766db0f51151b45bb523e7879bad4a3999f51402e359b1a102829b276a
-size 10875
+oid sha256:f2d495aa0a148d9e72d6bdf5f8a68d6934c44084e9669bac5e2ddde2d45d34c0
+size 8086
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_5_en.png
index fe0cd344e5..b97d04658b 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_5_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_5_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:df17f77b172f58c725a6c30c092ae3fdb2e561785ffe124bdc4fa08fc686f794
-size 21035
+oid sha256:b316c5766db0f51151b45bb523e7879bad4a3999f51402e359b1a102829b276a
+size 10875
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_6_en.png
index 04814e712c..fe0cd344e5 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_6_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_6_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:c6d17d65431bc2c7728a3ad5c6d2fdedbf45658f51ed8f6d73bc26de799b79af
-size 10021
+oid sha256:df17f77b172f58c725a6c30c092ae3fdb2e561785ffe124bdc4fa08fc686f794
+size 21035
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_7_en.png
index 8937dd7d87..04814e712c 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_7_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_7_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:55da0734cf5c1c97e17eee5c88273fc63c94dfa7b3eab12a3e1ea2da0783e039
-size 8812
+oid sha256:c6d17d65431bc2c7728a3ad5c6d2fdedbf45658f51ed8f6d73bc26de799b79af
+size 10021
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_8_en.png
index b1f89a1f45..8937dd7d87 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_8_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_8_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2e457089542659d700e4493bf1d345f79d7c829cbbded2d4337882a7e45f6808
-size 8783
+oid sha256:55da0734cf5c1c97e17eee5c88273fc63c94dfa7b3eab12a3e1ea2da0783e039
+size 8812
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_9_en.png
index 61c461a1e9..b1f89a1f45 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_9_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Day_9_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:780f661eca8275cc2fb70f7b504f8f95f79f387d6e72b2702cbb5da150c081a0
-size 8059
+oid sha256:2e457089542659d700e4493bf1d345f79d7c829cbbded2d4337882a7e45f6808
+size 8783
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_0_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_0_en.png
index b5d45f25e3..f33daef910 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_0_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_0_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:239ea1c7968861e97a6303fa64a8bd14f9140f50e73440329286ca1f0485795b
-size 7724
+oid sha256:561516463cfb7c33307781265d09c3055640773d366247bbed04642b71ca36b9
+size 23200
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_10_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_10_en.png
index 079a0c20cc..7fbf2c7e88 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_10_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_10_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:a74061cb811c957c9b00520eb37566b58168b31ebe74a06506e8ed6c76e03b5f
-size 20803
+oid sha256:fc284fea350c1bfdbd73df2a0065484f77361c707f4ee8d60a29dafde07e8af0
+size 7774
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_11_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_11_en.png
index 7cc90da21f..079a0c20cc 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_11_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_11_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:eb4918eba234005d307ff24540bc837d4e3f06db06eee6e841e5c2af6cae1063
-size 30378
+oid sha256:a74061cb811c957c9b00520eb37566b58168b31ebe74a06506e8ed6c76e03b5f
+size 20803
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_12_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_12_en.png
new file mode 100644
index 0000000000..7cc90da21f
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_12_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eb4918eba234005d307ff24540bc837d4e3f06db06eee6e841e5c2af6cae1063
+size 30378
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_1_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_1_en.png
index 7f8a883927..b5d45f25e3 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_1_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_1_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:1c07fe4ad8f0b14daec7ded50f1886a83868be166a7f42a5dacea985538d97b3
-size 8924
+oid sha256:239ea1c7968861e97a6303fa64a8bd14f9140f50e73440329286ca1f0485795b
+size 7724
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_2_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_2_en.png
index 18345ce06c..7f8a883927 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_2_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_2_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:ccbda5890ab6e53c66483ed169175d223525ac6c4bd7dc6f845c10a9f2531e65
-size 18802
+oid sha256:1c07fe4ad8f0b14daec7ded50f1886a83868be166a7f42a5dacea985538d97b3
+size 8924
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_3_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_3_en.png
index fcbac285f0..18345ce06c 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_3_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_3_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:049a666793d96ad5d4217390adec761e7c3972fded6ca1159a70dbf97f97b725
-size 7901
+oid sha256:ccbda5890ab6e53c66483ed169175d223525ac6c4bd7dc6f845c10a9f2531e65
+size 18802
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_4_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_4_en.png
index d564c06517..fcbac285f0 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_4_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_4_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:efe82e2ec14616e1614e404c0d470c0447816745d954287abd5ade9020d18e6a
-size 10469
+oid sha256:049a666793d96ad5d4217390adec761e7c3972fded6ca1159a70dbf97f97b725
+size 7901
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_5_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_5_en.png
index a3c904e385..d564c06517 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_5_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_5_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:323355db6c969094011a384c9e1f939d056415309400a270a56a6842a7d5072f
-size 20153
+oid sha256:efe82e2ec14616e1614e404c0d470c0447816745d954287abd5ade9020d18e6a
+size 10469
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_6_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_6_en.png
index 64a6c9553e..a3c904e385 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_6_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_6_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:79f9cfc67be1aa32d6eb05bcfe8bab6b4bff43ab8757668c3ea0ebccf5383089
-size 9806
+oid sha256:323355db6c969094011a384c9e1f939d056415309400a270a56a6842a7d5072f
+size 20153
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_7_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_7_en.png
index 5d48d880e6..64a6c9553e 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_7_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_7_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:2bc513febce6bcc1a452cedbfe640ff029cdd8bafcae852d6bdaa2fac4b85094
-size 8593
+oid sha256:79f9cfc67be1aa32d6eb05bcfe8bab6b4bff43ab8757668c3ea0ebccf5383089
+size 9806
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_8_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_8_en.png
index 30fad755ca..5d48d880e6 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_8_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_8_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:3db9c79b4e0ce71b93da5aba58fd9bdcc977a0a979eb89f8027b3ca378f25d5e
-size 8360
+oid sha256:2bc513febce6bcc1a452cedbfe640ff029cdd8bafcae852d6bdaa2fac4b85094
+size 8593
diff --git a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_9_en.png b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_9_en.png
index 7fbf2c7e88..30fad755ca 100644
--- a/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_9_en.png
+++ b/tests/uitests/src/test/snapshots/images/libraries.htmlrenderer.api.ui_HtmlMessageContent_Night_9_en.png
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:fc284fea350c1bfdbd73df2a0065484f77361c707f4ee8d60a29dafde07e8af0
-size 7774
+oid sha256:3db9c79b4e0ce71b93da5aba58fd9bdcc977a0a979eb89f8027b3ca378f25d5e
+size 8360