Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String, AttributedString>] = [:]

Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
10 changes: 10 additions & 0 deletions ElementX/Sources/Other/HTMLParsing/HTMLFixtures.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ enum HTMLFixtures: String, CaseIterable {
case codeBlocks
case unorderedList
case orderedList
case entirelySpoilered
case partiallySpoilered

var rawValue: String {
switch self {
Expand Down Expand Up @@ -111,6 +113,14 @@ enum HTMLFixtures: String, CaseIterable {
<li>Skittles</li>
</ol>
"""
case .partiallySpoilered:
"""
partially <span data-mx-spoiler>spoilered</span>
"""
case .entirelySpoilered:
"""
<span data-mx-spoiler>entirely spoilered</span>
"""
}
}
}
7 changes: 7 additions & 0 deletions ElementX/Sources/Other/Pills/MessageText.swift
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,8 @@ struct MessageText_Previews: PreviewProvider, TestablePreview {
"""

private static let htmlStringWithList = "<p>This is a list</p>\n<ul>\n<li>One</li>\n<li>Two</li>\n<li>And number 3</li>\n</ul>\n"

private static let htmlStringWithSpoiler = "partially <span data-mx-spoiler>spoilered</span>"

private static let attributedStringBuilder = AttributedStringBuilder(mentionBuilder: MentionBuilder())

Expand Down Expand Up @@ -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")
}
}
}