Files
letro-ios/ElementX/Sources/Other/HTMLParsing/DTHTMLElement+AttributedStringBuilder.swift
Mauro 6160c44d67 Update copyright holding and dates (#4640)
* Update copyright holding and dates

* compound IDE Macros updated

* update copyright

* update copyrights done

* update templates and README
2025-10-21 14:34:56 +02:00

77 lines
3.3 KiB
Swift

//
// Copyright 2025 Element Creations Ltd.
// Copyright 2022-2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
// Please see LICENSE files in the repository root for full details.
//
import DTCoreText
import Foundation
public extension DTHTMLElement {
/// Sanitize the element using the given parameters.
/// - Parameters:
/// - font: The default font to use when resetting the content of any unsupported tags.
@objc func sanitize(font: UIFont) {
if let name, !Self.allowedHTMLTags.contains(name) {
// This is an unsupported tag.
// Remove any attachments to fix rendering.
textAttachment = nil
// Handle special case for span with data-mx-external-payment-details
// This could be based on Storefront.current.countryCode to show the link
// content in unrestricted countries. e.g. currently USA
if name == "span",
let attributes = attributes as? [String: String],
attributes["data-msc4286-external-payment-details"] != nil {
parent.removeChildNode(self)
return
}
// If the element has plain text content show that,
// otherwise prevent the tag from displaying.
if let stringContent = attributedString()?.string,
!stringContent.isEmpty,
let element = DTTextHTMLElement(name: nil, attributes: nil) {
element.setText(stringContent)
removeAllChildNodes()
addChildNode(element)
if let parent = parent() {
element.inheritAttributes(from: parent)
} else {
fontDescriptor = DTCoreTextFontDescriptor()
fontDescriptor.fontFamily = font.familyName
fontDescriptor.fontName = font.fontName
fontDescriptor.pointSize = font.pointSize
paragraphStyle = DTCoreTextParagraphStyle.default()
element.inheritAttributes(from: self)
}
element.interpretAttributes()
} else if let parent = parent() {
parent.removeChildNode(self)
} else {
didOutput = true
}
} else {
// This element is a supported tag, but it may contain children that aren't,
// so santize all child nodes to ensure correct tags.
if let childNodes = childNodes as? [DTHTMLElement] {
childNodes.forEach { $0.sanitize(font: font) }
}
}
}
private static let allowedHTMLTags = ["font", // custom to matrix for IRC-style font coloring
"del", // for markdown
"body", // added internally by DTCoreText
"mx-reply",
"h1", "h2", "h3", "h4", "h5", "h6", "blockquote", "p", "a", "ul", "ol",
"nl", "li", "b", "i", "u", "strong", "em", "strike", "code", "hr", "br", "div",
"table", "thead", "caption", "tbody", "tr", "th", "td", "pre"]
}