fix: center bullets and checkboxes in the marker column

This commit is contained in:
2026-10-19 21:00:43 +02:00
parent 07dae870f7
commit 9e92dc3d7f
3 changed files with 40 additions and 7 deletions
+34 -3
View File
@@ -1250,17 +1250,48 @@ func renderedListMarkersPaintBulletsAndNumbersInsideTheirGlyphFrames() throws {
context.cgContext.clear(CGRect(x: 0, y: 0, width: 160, height: 48))
layout.drawGlyphs(forGlyphRange: glyphs, at: NSPoint(x: 4 - frame.minX, y: 10 - frame.minY))
NSGraphicsContext.restoreGraphicsState()
var painted = false
var minX = 160, maxX = -1
for y in 0..<48 {
for x in 0..<160 where (bitmap.colorAt(x: x, y: y)?.alphaComponent ?? 0) > 0.1 {
painted = true
minX = min(minX, x)
maxX = max(maxX, x)
}
}
#expect(painted, "The actual TextKit draw path must paint the marker for \(source)")
#expect(maxX >= minX, "The actual TextKit draw path must paint the marker for \(source)")
if ["-", "*", "+"].contains(String(source.prefix(1))) {
#expect(abs(CGFloat(minX + maxX + 1) / 2 - (4 + frame.width / 2)) <= 1)
} else {
#expect(abs(CGFloat(maxX + 1) - frame.width) <= 3)
}
#expect(editor.markdownString == source)
}
}
@Test @MainActor
func listCheckboxesStayCenteredInTheSharedColumnAtEachIndentation() throws {
_ = NSApplication.shared
let editor = NotesTextView(frame: NSRect(x: 0, y: 0, width: 400, height: 300))
let source = "- bullet\n- [ ] task\n12345. wide number\n + nested bullet\n - [x] nested task"
editor.setMarkdownContents(NSAttributedString(string: source))
let layout = try #require(editor.layoutManager)
let container = try #require(editor.textContainer)
layout.ensureLayout(for: container)
editor.layout()
let text = editor.string as NSString
let checkboxes = editor.subviews.compactMap { $0 as? NSButton }
for (index, label) in ["task", "nested task"].enumerated() {
let body = text.range(of: label)
let line = text.lineRange(for: body)
let marker = text.range(of: "\u{fffc}", options: [], range: line)
let glyphs = layout.glyphRange(forCharacterRange: marker, actualCharacterRange: nil)
let frame = layout.boundingRect(forGlyphRange: glyphs, in: container)
.offsetBy(dx: editor.textContainerOrigin.x, dy: editor.textContainerOrigin.y)
let checkbox = try #require(checkboxes.indices.contains(index) ? checkboxes[index] : nil)
#expect(abs(checkbox.frame.midX - frame.midX) <= 0.5)
}
#expect(editor.markdownString == source)
}
@Test @MainActor
func listBodyInsertionUsesVisiblePositionForTypingPasteAndReplacementRanges() throws {
_ = NSApplication.shared