Fix inline text/elements coming after block elements
This commit is contained in:
parent
c8512fa71e
commit
395f5965bc
|
@ -26,6 +26,7 @@ public struct AttributedStringConverter<Callbacks: AttributedStringCallbacks> {
|
|||
|
||||
private var actionStack: [ElementAction] = []
|
||||
private var styleStack: [Style] = []
|
||||
private var previouslyFinishedBlockElement = false
|
||||
// The current run of text w/o styles changing
|
||||
private var currentRun: String = ""
|
||||
|
||||
|
@ -144,6 +145,7 @@ public struct AttributedStringConverter<Callbacks: AttributedStringCallbacks> {
|
|||
|
||||
private mutating func startBlockElement() {
|
||||
if str.length != 0 || !currentRun.isEmpty {
|
||||
previouslyFinishedBlockElement = false
|
||||
currentRun.append("\n\n")
|
||||
}
|
||||
}
|
||||
|
@ -170,15 +172,19 @@ public struct AttributedStringConverter<Callbacks: AttributedStringCallbacks> {
|
|||
case "pre":
|
||||
finishRun()
|
||||
removeLastStyle(.monospace)
|
||||
finishBlockElement()
|
||||
case "blockquote":
|
||||
finishRun()
|
||||
removeLastStyle(.blockquote)
|
||||
finishBlockElement()
|
||||
case "ol":
|
||||
finishRun()
|
||||
removeLastStyle(.orderedList)
|
||||
finishBlockElement()
|
||||
case "ul":
|
||||
finishRun()
|
||||
removeLastStyle(.unorderedList)
|
||||
finishBlockElement()
|
||||
case "li":
|
||||
finishRun()
|
||||
default:
|
||||
|
@ -186,6 +192,13 @@ public struct AttributedStringConverter<Callbacks: AttributedStringCallbacks> {
|
|||
}
|
||||
}
|
||||
|
||||
private mutating func finishBlockElement() {
|
||||
if str.length != 0 {
|
||||
previouslyFinishedBlockElement = true
|
||||
// currentRun.append("\n\n")
|
||||
}
|
||||
}
|
||||
|
||||
// Finds the last currently-open style of the given type.
|
||||
// We can't just use the last one because we need to handle mis-nested tags.
|
||||
private mutating func removeLastStyle(_ type: Style.StyleType) {
|
||||
|
@ -234,6 +247,11 @@ public struct AttributedStringConverter<Callbacks: AttributedStringCallbacks> {
|
|||
} else if case .replace(let replacement) = actionStack.first(where: \.isReplace) {
|
||||
currentRun = replacement
|
||||
}
|
||||
|
||||
if previouslyFinishedBlockElement {
|
||||
previouslyFinishedBlockElement = false
|
||||
currentRun.insert(contentsOf: "\n\n", at: currentRun.startIndex)
|
||||
}
|
||||
|
||||
var attributes = [NSAttributedString.Key: Any]()
|
||||
var currentFontTraits: FontTrait = []
|
||||
|
|
|
@ -170,6 +170,36 @@ final class AttributedStringConverterTests: XCTestCase {
|
|||
]))
|
||||
}
|
||||
|
||||
func testTextAfterBlockquote() {
|
||||
let result = NSMutableAttributedString()
|
||||
result.append(NSAttributedString(string: "wee", attributes: [
|
||||
.font: italicFont,
|
||||
.paragraphStyle: blockquoteParagraphStyle,
|
||||
]))
|
||||
result.append(NSAttributedString(string: "\n\nafter", attributes: [
|
||||
.font: font,
|
||||
.paragraphStyle: NSParagraphStyle.default,
|
||||
]))
|
||||
XCTAssertEqual(convert("<blockquote>wee</blockquote>after"), result)
|
||||
}
|
||||
|
||||
func testMultipleBlockElements() {
|
||||
let result = NSMutableAttributedString()
|
||||
result.append(NSAttributedString(string: "a", attributes: [
|
||||
.font: italicFont,
|
||||
.paragraphStyle: blockquoteParagraphStyle,
|
||||
]))
|
||||
result.append(NSAttributedString(string: "\n\n", attributes: [
|
||||
.font: font,
|
||||
.paragraphStyle: NSParagraphStyle.default,
|
||||
]))
|
||||
result.append(NSAttributedString(string: "b", attributes: [
|
||||
.font: italicFont,
|
||||
.paragraphStyle: blockquoteParagraphStyle,
|
||||
]))
|
||||
XCTAssertEqual(convert("<blockquote>a</blockquote><blockquote>b</blockquote>"), result)
|
||||
}
|
||||
|
||||
func testSelfClosing() {
|
||||
XCTAssertEqual(convert("<b />asdf"), NSAttributedString(string: "asdf", attributes: [
|
||||
.font: font,
|
||||
|
|
Loading…
Reference in New Issue