diff --git a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift index 59fa8ec23..cc1f56f8a 100644 --- a/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift +++ b/ElementX/Sources/Other/HTMLParsing/AttributedStringBuilder.swift @@ -330,12 +330,17 @@ struct AttributedStringBuilder: AttributedStringBuilderProtocol { }) matches.append(contentsOf: MatrixEntityRegex.linkRegex.matches(in: string).compactMap { match in - guard let matchRange = Range(match.range, in: string) else { + guard let matchRange = Range(match.range, in: string), let url = match.url else { return nil } - let link = String(string[matchRange]).asSanitizedLink - return TextParsingMatch(type: .link(urlString: link), range: match.range) + // If the NSDataDetector found a hyperlink then sanitise it + if url.scheme?.contains("http") ?? false { + // Use the underlying string so it gets an `https` scheme if it didn't have any + return TextParsingMatch(type: .link(urlString: String(string[matchRange]).asSanitizedLink), range: match.range) + } else { // otherwise use it as it is e.g. mailto: (https://github.com/element-hq/element-x-ios/issues/4913) + return TextParsingMatch(type: .link(urlString: url.absoluteString), range: match.range) + } }) matches.append(contentsOf: MatrixEntityRegex.allUsersRegex.matches(in: attributedString.string).map { match in diff --git a/UnitTests/Sources/AttributedStringBuilderTests.swift b/UnitTests/Sources/AttributedStringBuilderTests.swift index 660e3335d..6d2b55ecd 100644 --- a/UnitTests/Sources/AttributedStringBuilderTests.swift +++ b/UnitTests/Sources/AttributedStringBuilderTests.swift @@ -114,6 +114,18 @@ class AttributedStringBuilderTests: XCTestCase { XCTAssertEqual(link, "https://matrix.org") } + func testMailToLinks() { + let plainString = "Linking to email addresses like stefan@matrix.org should work as well" + + guard let attributedString = attributedStringBuilder.fromPlain(plainString) else { + XCTFail("Could not build the attributed string") + return + } + + let link = attributedString.runs.first { $0.link != nil }?.link + XCTAssertEqual(link, "mailto:stefan@matrix.org") + } + func testRenderHTMLStringWithLinkInHeader() { let h1HTMLString = "

Matrix.org

" let h2HTMLString = "

Matrix.org

"