diff --git a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift index d6b49e89a7..84efbaba2b 100644 --- a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift +++ b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift @@ -32,6 +32,7 @@ extension NSAttributedString.Key { static let MatrixEventOnRoomAlias: NSAttributedString.Key = .init(rawValue: EventOnRoomAliasAttribute.name) static let MatrixAllUsersMention: NSAttributedString.Key = .init(rawValue: AllUsersMentionAttribute.name) static let CodeBlock: NSAttributedString.Key = .init(rawValue: CodeBlockAttribute.name) + static let MatrixSpoiler: NSAttributedString.Key = .init(rawValue: SpoilerAttribute.name) } struct AttributedStringBuilder: AttributedStringBuilderProtocol { diff --git a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilderV2.swift b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilderV2.swift index a757d7b35c..5a57f5a9bf 100644 --- a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilderV2.swift +++ b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilderV2.swift @@ -16,6 +16,7 @@ struct AttributedStringBuilderV2: AttributedStringBuilderProtocol { private let mentionBuilder: MentionBuilderProtocol private static let attributeMSC4286 = "data-msc4286-external-payment-details" + private static let attributeMSC2010 = "mx-spoiler" private static let cacheDispatchQueue = DispatchQueue(label: "io.element.elementx.attributed_string_builder_v2_cache") private static var caches: [String: LRUCache] = [:] @@ -203,6 +204,10 @@ struct AttributedStringBuilderV2: AttributedStringBuilderProtocol { if childElement.dataset()[Self.attributeMSC4286] != nil { content = attributedString(element: childElement, documentBody: documentBody, preserveFormatting: preserveFormatting, listTag: listTag, listIndex: &childIndex, indentLevel: indentLevel) } + if childElement.dataset()[Self.attributeMSC2010] != nil { + content = attributedString(element: childElement, documentBody: documentBody, preserveFormatting: preserveFormatting, listTag: listTag, listIndex: &childIndex, indentLevel: indentLevel) + content.addAttribute(.MatrixSpoiler, value: true, range: NSRange(location: 0, length: content.length)) + } case "ul", "ol": var listIndex = 1 diff --git a/ElementX/Sources/Other/HTMLParsing/ElementXAttributeScope.swift b/ElementX/Sources/Other/HTMLParsing/ElementXAttributeScope.swift index 02d76c0bd2..d01234afe6 100644 --- a/ElementX/Sources/Other/HTMLParsing/ElementXAttributeScope.swift +++ b/ElementX/Sources/Other/HTMLParsing/ElementXAttributeScope.swift @@ -67,6 +67,11 @@ enum CodeBlockAttribute: AttributedStringKey { static let name = "MXCodeBlockAttribute" } +enum SpoilerAttribute: AttributedStringKey { + typealias Value = Bool + static let name = "MXSpoilerAttribute" +} + // periphery: ignore - required to make NSAttributedString to AttributedString conversion even if not used directly extension AttributeScopes { struct ElementXAttributes: AttributeScope { diff --git a/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift b/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift index 9fec42b8c1..752f4af9ea 100644 --- a/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift +++ b/ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift @@ -17,6 +17,8 @@ enum HTMLFixtures: String, CaseIterable { case codeBlocks case unorderedList case orderedList + case entirelySpoilered + case partiallySpoilered var rawValue: String { switch self { @@ -111,6 +113,14 @@ enum HTMLFixtures: String, CaseIterable {
  • Skittles
  • """ + case .partiallySpoilered: + """ + partially spoilered + """ + case .entirelySpoilered: + """ + entirely spoilered + """ } } } diff --git a/ElementX/Sources/Other/Pills/MessageText.swift b/ElementX/Sources/Other/Pills/MessageText.swift index 56865a6b64..a9497cc62a 100644 --- a/ElementX/Sources/Other/Pills/MessageText.swift +++ b/ElementX/Sources/Other/Pills/MessageText.swift @@ -203,6 +203,8 @@ struct MessageText_Previews: PreviewProvider, TestablePreview { """ private static let htmlStringWithList = "

    This is a list

    \n\n" + + private static let htmlStringWithSpoiler = "partially spoilered" private static let attributedStringBuilder = AttributedStringBuilder(mentionBuilder: MentionBuilder()) @@ -232,5 +234,10 @@ struct MessageText_Previews: PreviewProvider, TestablePreview { .border(Color.purple) .previewDisplayName("With list") } + if let attributedString = attributedStringBuilder.fromHTML(htmlStringWithSpoiler) { + MessageText(attributedString: attributedString) + .border(Color.purple) + .previewDisplayName("With spoiler") + } } }