diff --git a/oAI/Services/ConversationExportService.swift b/oAI/Services/ConversationExportService.swift index 57743be..8cbd32a 100644 --- a/oAI/Services/ConversationExportService.swift +++ b/oAI/Services/ConversationExportService.swift @@ -71,6 +71,7 @@ enum ConversationExportService { nonisolated private static let css = """ :root { color-scheme: light dark; } html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; } + ::-webkit-scrollbar { display: none; } body { font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif; \ font-size: 15px; color: #1a1a1a; background: #ffffff; max-width: 820px; margin: 40px auto; \ padding: 0 24px; line-height: 1.5; } @@ -113,7 +114,15 @@ enum ConversationExportService { static func pdfData(name: String, messages: [Message]) async throws -> Data { let htmlString = html(name: name, messages: messages) - let webView = WKWebView(frame: NSRect(x: 0, y: 0, width: 816, height: 1056)) + // Confirmed empirically (not guessed): with WKPDFConfiguration.rect left at its + // default, createPDF captures exactly the webview's frame size verbatim for content + // that fits within it, and auto-grows to a single tall page matching the full + // scrollable content when it overflows — it does not paginate. Manually resizing the + // frame to match content height beforehand (a previous attempt at this) actively + // breaks that: the captured page ends up NOT matching the resized frame at all, + // producing a small, oddly-proportioned page that made ordinary-sized text look + // enormous relative to it. So: set a sane starting frame and leave it alone. + let webView = WKWebView(frame: NSRect(x: 0, y: 0, width: 850, height: 1100)) webView.pageZoom = 1.0 // PDF content is baked at export time, so it can't respond to prefers-color-scheme // live like the HTML export does — match whatever appearance the app is in right now. @@ -122,14 +131,6 @@ enum ConversationExportService { webView.navigationDelegate = delegate try await delegate.load(htmlString, in: webView) - // Resize to the actual rendered content height so createPDF's capture bounds match - // reality, rather than relying on its undocumented auto-sizing against the arbitrary - // initial frame — a mismatch here is a common cause of blown-up/rescaled PDF output. - if let heightValue = try? await webView.evaluateJavaScript("document.body.scrollHeight"), - let height = (heightValue as? NSNumber)?.doubleValue, height > 0 { - webView.frame = NSRect(x: 0, y: 0, width: webView.frame.width, height: height) - } - return try await withCheckedThrowingContinuation { continuation in webView.createPDF(configuration: WKPDFConfiguration()) { result in continuation.resume(with: result)