Files
letro-ios/ElementX/Sources/Other/HTMLParsing/DTHTMLElement+AttributedStringBuilder.swift
manuroe c29f4cc9b4 Dual licensing: AGPL + Element Commercial (#3657)
* New LICENSE-COMMERCIAL file

* Apply dual licenses: AGPL + Element Commercial to file headers

* Update README with dual licensing
2025-01-06 11:27:37 +01:00

66 lines
2.8 KiB
Swift

//
// Copyright 2022-2024 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
// 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"]
}