Fix .skip action skipping too much if a run was in-progress when the skip element was encountered

This commit is contained in:
Shadowfacts 2024-02-04 15:09:08 -05:00
parent a86fe04348
commit 7e624c0a4a
4 changed files with 31 additions and 0 deletions

View File

@ -67,6 +67,9 @@ public struct AttributedStringConverter<Callbacks: HTMLConversionCallbacks> {
case .startTag(let name, let selfClosing, let attributes):
currentElementIsEmpty = true
let action = Callbacks.elementAction(name: name, attributes: attributes)
if action != .default {
finishRun()
}
actionStack.append(action)
handleStartTag(name, selfClosing: selfClosing, attributes: attributes)
case .endTag(let name):

View File

@ -48,6 +48,9 @@ public struct TextConverter<Callbacks: HTMLConversionCallbacks> {
case .startTag(let name, let selfClosing, let attributes):
currentElementIsEmpty = true
let action = Callbacks.elementAction(name: name, attributes: attributes)
if action != .default {
finishRun()
}
actionStack.append(action)
handleStartTag(name, selfClosing: selfClosing, attributes: attributes)
case .endTag(let name):

View File

@ -336,4 +336,20 @@ final class AttributedStringConverterTests: XCTestCase {
XCTAssertEqual(convert("a<ol><li>b</li><li>c</li></ol>"), result)
}
func testSkipElementActionFollowingUnfinishedRun() {
struct Callbacks: HTMLConversionCallbacks {
static func elementAction(name: String, attributes: [Attribute]) -> ElementAction {
attributes.attributeValue(for: "class") == "invisible" ? .skip : .default
}
}
let result = NSMutableAttributedString()
result.append(NSAttributedString(string: "example.com", attributes: [
.font: font,
.paragraphStyle: NSParagraphStyle.default,
.foregroundColor: color,
.link: URL(string: "https://example.com")!,
]))
XCTAssertEqual(convert(#"<a href="https://example.com"><span class="invisible">https://</span><span>example.com</span><span class="invisible"></span></a>"#, callbacks: Callbacks.self), result)
}
}

View File

@ -74,4 +74,13 @@ final class TextConverterTests: XCTestCase {
XCTAssertEqual(convert("<p></p><blockquote><span>inside<br>quote</span></blockquote><span>after</span><p></p>"), "inside\nquote\n\nafter")
}
func testSkipElementActionFollowingUnfinishedRun() {
struct Callbacks: HTMLConversionCallbacks {
static func elementAction(name: String, attributes: [Attribute]) -> ElementAction {
attributes.attributeValue(for: "class") == "invisible" ? .skip : .default
}
}
XCTAssertEqual(convert(#"<a href="https://example.com"><span class="invisible">https://</span><span>example.com</span><span class="invisible"></span></a>"#, callbacks: Callbacks.self), "example.com")
}
}