Fixes #4713, fixes #4648 - Correctly handle span tags and data attributes.

This commit is contained in:
Stefan Ceriu
2025-11-07 12:48:01 +02:00
committed by Stefan Ceriu
parent 51a9d8b56b
commit 0515d4495a
2 changed files with 18 additions and 4 deletions
@@ -40,7 +40,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
private let cacheKey: String private let cacheKey: String
private let mentionBuilder: MentionBuilderProtocol private let mentionBuilder: MentionBuilderProtocol
private static let attributeMSC4286 = "data-msc4286-external-payment-details" private static let attributeMSC4286 = "msc4286-external-payment-details"
private static let cacheDispatchQueue = DispatchQueue(label: "io.element.elementx.attributed_string_builder_v2_cache") private static let cacheDispatchQueue = DispatchQueue(label: "io.element.elementx.attributed_string_builder_v2_cache")
private static var caches: [String: LRUCache<String, AttributedString>] = [:] private static var caches: [String: LRUCache<String, AttributedString>] = [:]
@@ -225,7 +225,7 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol {
} }
case "span": case "span":
if childElement.dataset()[Self.attributeMSC4286] != nil { if childElement.dataset()[Self.attributeMSC4286] == nil {
content = attributedString(element: childElement, documentBody: documentBody, preserveFormatting: preserveFormatting, listTag: listTag, listIndex: &childIndex, indentLevel: indentLevel) content = attributedString(element: childElement, documentBody: documentBody, preserveFormatting: preserveFormatting, listTag: listTag, listIndex: &childIndex, indentLevel: indentLevel)
} }
@@ -1016,19 +1016,33 @@ class AttributedStringBuilderTests: XCTestCase {
} }
func testMxExternalPaymentDetailsRemoved() { func testMxExternalPaymentDetailsRemoved() {
let htmlString = "This is visible<span data-msc4286-external-payment-details>. But text is hidden <a href=\"https://matrix.org\">and this link too</a></span>" var htmlString = "This is visible.<span data-msc4286-external-payment-details> But this is hidden <a href=\"https://matrix.org\">and this link too</a></span>"
guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else { guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else {
XCTFail("Could not build the attributed string") XCTFail("Could not build the attributed string")
return return
} }
XCTAssertEqual(String(attributedString.characters), "This is visible") XCTAssertEqual(String(attributedString.characters), "This is visible.")
for run in attributedString.runs where run.link != nil { for run in attributedString.runs where run.link != nil {
XCTFail("No link expected, but found one") XCTFail("No link expected, but found one")
return return
} }
htmlString = "This is visible.<span> And this text <a href=\"https://matrix.org\">and link</a> are visible too.</span>"
guard let attributedString = attributedStringBuilder.fromHTML(htmlString) else {
XCTFail("Could not build the attributed string")
return
}
XCTAssertEqual(String(attributedString.characters), "This is visible. And this text and link are visible too.")
guard attributedString.runs.first(where: { $0.link != nil })?.link != nil else {
XCTFail("Couldn't find the link")
return
}
} }
// MARK: - Private // MARK: - Private