Fix HTML issues
This commit is contained in:
parent
582ff3623c
commit
083e960166
|
@ -17,7 +17,13 @@ extension HTML: Codable {
|
||||||
let container = try decoder.singleValueContainer()
|
let container = try decoder.singleValueContainer()
|
||||||
|
|
||||||
raw = try container.decode(String.self)
|
raw = try container.decode(String.self)
|
||||||
attributed = HTMLParser(string: raw).parse()
|
|
||||||
|
if let cachedAttributedString = Self.attributedStringCache.object(forKey: raw as NSString) {
|
||||||
|
attributed = cachedAttributedString
|
||||||
|
} else {
|
||||||
|
attributed = HTMLParser(string: raw).parse()
|
||||||
|
Self.attributedStringCache.setObject(attributed, forKey: raw as NSString)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func encode(to encoder: Encoder) throws {
|
public func encode(to encoder: Encoder) throws {
|
||||||
|
@ -27,6 +33,10 @@ extension HTML: Codable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private extension HTML {
|
||||||
|
static var attributedStringCache = NSCache<NSString, NSAttributedString>()
|
||||||
|
}
|
||||||
|
|
||||||
// https://docs.joinmastodon.org/spec/activitypub/#sanitization
|
// https://docs.joinmastodon.org/spec/activitypub/#sanitization
|
||||||
|
|
||||||
private class HTMLParser: NSObject {
|
private class HTMLParser: NSObject {
|
||||||
|
@ -48,7 +58,9 @@ private class HTMLParser: NSObject {
|
||||||
private static let closingContainerTag = "</\(containerTag)>"
|
private static let closingContainerTag = "</\(containerTag)>"
|
||||||
|
|
||||||
init(string: String) {
|
init(string: String) {
|
||||||
rawString = Self.openingContainerTag + string + Self.closingContainerTag
|
rawString = Self.openingContainerTag
|
||||||
|
.appending(string.replacingOccurrences(of: "<br>", with: "<br/>"))
|
||||||
|
.appending(Self.closingContainerTag)
|
||||||
parser = XMLParser(data: Data(rawString.utf8))
|
parser = XMLParser(data: Data(rawString.utf8))
|
||||||
parseStopColumn = rawString.count - Self.closingContainerTag.count
|
parseStopColumn = rawString.count - Self.closingContainerTag.count
|
||||||
|
|
||||||
|
@ -81,7 +93,7 @@ extension HTMLParser: XMLParserDelegate {
|
||||||
attributesStack.append(attributeDict)
|
attributesStack.append(attributeDict)
|
||||||
|
|
||||||
if elementName == "a", let hrefString = attributeDict["href"], let href = URL(string: hrefString) {
|
if elementName == "a", let hrefString = attributeDict["href"], let href = URL(string: hrefString) {
|
||||||
currentLink = Link(href: href, location: constructedString.count)
|
currentLink = Link(href: href, location: constructedString.utf16.count)
|
||||||
} else if elementName == "br" {
|
} else if elementName == "br" {
|
||||||
constructedString.append("\n")
|
constructedString.append("\n")
|
||||||
}
|
}
|
||||||
|
@ -98,7 +110,7 @@ extension HTMLParser: XMLParserDelegate {
|
||||||
}
|
}
|
||||||
|
|
||||||
if elementName == "a", var link = currentLink {
|
if elementName == "a", var link = currentLink {
|
||||||
link.length = constructedString.count - link.location
|
link.length = constructedString.utf16.count - link.location
|
||||||
links.insert(link)
|
links.insert(link)
|
||||||
} else if elementName == "p", parser.columnNumber < parseStopColumn {
|
} else if elementName == "p", parser.columnNumber < parseStopColumn {
|
||||||
constructedString.append("\n\n")
|
constructedString.append("\n\n")
|
||||||
|
|
Loading…
Reference in New Issue